diff --git a/playbooks/activemq_cluster.yml b/playbooks/activemq_cluster.yml
new file mode 100644
index 00000000..606a8351
--- /dev/null
+++ b/playbooks/activemq_cluster.yml
@@ -0,0 +1,29 @@
+---
+- name: Playbook for Red Hat AMQ Broker
+  hosts: all
+  vars:
+    amq_broker_ha_enabled: true
+    amq_broker_disable_hornetq_protocol: true
+    amq_broker_disable_mqtt_protocol: true
+    amq_broker_shared_storage: true
+    amq_broker_configure_firewalld: true
+  collections:
+   - middleware_automation.redhat_csp_download
+   - middleware_automation.amq
+  roles:
+   - amq_broker
+  pre_tasks:
+    - name: Create nfs shared directory
+      ansible.builtin.file:
+        state: directory
+        path: /opt/amq/amq-broker/data/shared
+        owner: root
+        group: root
+        mode: 0775
+    - name: Create mount NFS volume
+      ansible.posix.mount:
+       src: 10.0.153.34:/nfs
+       path: /opt/amq/amq-broker/data/shared
+       opts: rw,sync,hard,intr
+       state: mounted
+       fstype: nfs
diff --git a/roles/amq_broker/README.md b/roles/amq_broker/README.md
index 666f6218..560afeb0 100644
--- a/roles/amq_broker/README.md
+++ b/roles/amq_broker/README.md
@@ -90,6 +90,7 @@ Role Defaults
 |`amq_broker_cluster_lb_policy`| Policy for cluster load balancing | `ON_DEMAND` |
 |`amq_broker_replicate`| Enables replication | `False` |
 |`amq_broker_replicated`| Designate instance as replicated node | `False` |
+|`amq_broker_cluster_discovery` | Cluster discovery: [`jgroups` (shared file ping), `multicast` (UDP), `static` (node list)] | `static` |
 
 
 * TLS/SSL protocol
@@ -108,6 +109,7 @@ Role Defaults
 |:---------|:------------|:--------|
 |`amq_broker_nio_enabled`| Enable Native IO using libaio | `False` |
 |`amq_broker_shared_storage`| Use shared filesystem directory for storage | `False` |
+|`amq_broker_shared_storage_path`| Path of shared directory relative to activemq home directory | `data/shared` |
 |`amq_broker_disable_destination_autocreate`| Disable automatic creation of destination | `True` |
 |`amq_broker_queues`| Queue names comma separated | `queue.in,queue.out` |
 |`amq_broker_disable_amqp_protocol`| Whether to disable AMQP protocol | `False` |
diff --git a/roles/amq_broker/defaults/main.yml b/roles/amq_broker/defaults/main.yml
index e3db0770..22c753b4 100644
--- a/roles/amq_broker/defaults/main.yml
+++ b/roles/amq_broker/defaults/main.yml
@@ -49,6 +49,8 @@ amq_broker_cluster_maxhops: 1
 amq_broker_cluster_lb_policy: ON_DEMAND
 amq_broker_replicate: False
 amq_broker_replicated: False
+# cluster discovery: ['jgroups' for shared file ping, 'multicast' for UDP multicast, 'static' for static declaration]
+amq_broker_cluster_discovery: static
 
 ### Enable database configuration for JDBC persistence
 amq_broker_db_enabled: False
@@ -70,6 +72,7 @@ amq_broker_nio_enabled: False
 
 ## Shared Storage
 amq_broker_shared_storage: False
+amq_broker_shared_storage_path: data/shared
 
 ## Ports
 amq_broker_ports_offset_enabled: False
@@ -83,4 +86,4 @@ amq_broker_queues: queue.in,queue.out
 amq_broker_disable_amqp_protocol: False
 amq_broker_disable_hornetq_protocol: False
 amq_broker_disable_mqtt_protocol: False
-amq_broker_disable_stomp_protocol: False
\ No newline at end of file
+amq_broker_disable_stomp_protocol: False
diff --git a/roles/amq_broker/meta/argument_specs.yml b/roles/amq_broker/meta/argument_specs.yml
index 81a0b2ed..7e7601b5 100644
--- a/roles/amq_broker/meta/argument_specs.yml
+++ b/roles/amq_broker/meta/argument_specs.yml
@@ -201,6 +201,10 @@ argument_specs:
                 default: "ON_DEMAND"
                 description: "Policy for cluster load balancing"
                 type: "str"
+            amq_broker_cluster_discovery:
+                default: "static"
+                description: "Cluster discovery: ['jgroups' for shared file ping, 'multicast' for UDP multicast, 'static' for static declaration]"
+                type: "str"
             amq_broker_replicate:
                 # line 50 of defaults/main.yml
                 default: false
@@ -261,6 +265,10 @@ argument_specs:
                 default: false
                 description: "Use shared filesystem directory for storage"
                 type: "bool"
+            amq_broker_shared_storage_path:
+                default: "data/shared"
+                description: "Path of shared directory relative to activemq home directory"
+                type: "str"
             amq_broker_ports_offset_enabled:
                 # line 75 of defaults/main.yml
                 default: false
diff --git a/roles/amq_broker/tasks/configure.yml b/roles/amq_broker/tasks/configure.yml
index e54c7e56..344bf740 100644
--- a/roles/amq_broker/tasks/configure.yml
+++ b/roles/amq_broker/tasks/configure.yml
@@ -7,7 +7,7 @@
              "name": amq_broker.instance_name,
              "address": item,
              "inventory_host": item,
-             "value": "tcp://" + item + ":" + (((61616|int + amq_broker_ports_offset|int)|abs)|string)
+             "value": "tcp://" + item + ":" + (((amq_broker_port|int + amq_broker_ports_offset|int)|abs)|string)
            }
          ] }}
   loop: "{{ ansible_play_batch }}"
@@ -25,10 +25,19 @@
       - "--cluster-user {{ amq_broker_cluster_user }}"
       - "--cluster-password {{ amq_broker_cluster_pass }}"
       - "--max-hops {{ amq_broker_cluster_maxhops }}"
-      - "--message-load-balancing {{ amq_broker_cluster_load_balancing_policy }}"
+      - "--message-load-balancing {{ amq_broker_cluster_lb_policy }}"
       - "--failover-on-shutdown"
   when: amq_broker_ha_enabled
 
+- name: Enable static clustering
+  ansible.builtin.set_fact:
+    amq_broker_options:
+      - "{{ amq_broker_options | join(' ') }}"
+      - "--staticCluster {{ amq_broker_cluster_nodes | map(attribute='value') | join(',') }}"
+  when:
+    - amq_broker_ha_enabled
+    - amq_broker_cluster_discovery == "static"
+
 - name: Enable security
   ansible.builtin.set_fact:
     amq_broker_options:
@@ -48,7 +57,7 @@
   ansible.builtin.set_fact:
     amq_broker_options:
       - "{{ amq_broker_options | join(' ') }}"
-      - "--http-host {{ amq_broker_host }}"
+      - "--http-host {{ amq_broker_bind_address }}"
 
 - name: Disable automatic creation of queues
   ansible.builtin.set_fact:
@@ -89,7 +98,7 @@
     amq_broker_options:
       - "{{ amq_broker_options | join(' ') }}"
       - "--shared-store"
-      - "--data {{ amq_broker.home }}/data"
+      - "--data {{ amq_broker.instance_home }}/{{ amq_broker_shared_storage_path }}"
   when: amq_broker_shared_storage
 
 - name: Set up port offset
diff --git a/roles/amq_broker/tasks/jgroups.yml b/roles/amq_broker/tasks/jgroups.yml
new file mode 100644
index 00000000..f8f9113b
--- /dev/null
+++ b/roles/amq_broker/tasks/jgroups.yml
@@ -0,0 +1,9 @@
+---
+- name: configure - clustering - remove discovery groups
+  xml:
+    path: "{{ amq_broker.home }}/etc/broker.xml"
+    xpath: /conf:configuration/core:core/core:discovery-groups
+    state: absent
+    namespaces:
+      conf: urn:activemq
+      core: urn:activemq:core
diff --git a/roles/amq_broker/tasks/systemd.yml b/roles/amq_broker/tasks/systemd.yml
index b9b80b1f..de2bc6f6 100644
--- a/roles/amq_broker/tasks/systemd.yml
+++ b/roles/amq_broker/tasks/systemd.yml
@@ -35,15 +35,21 @@
 
 - name: "Check instance directory: {{ amq_broker_dest }}/{{ amq_broker.instance_name }}"
   ansible.builtin.stat:
-    path: "{{ amq_broker_dest }}/{{ amq_broker.instance_name }}"
+    path: "{{ amq_broker_dest }}/{{ amq_broker.instance_name }}/bin"
   register: instance_directory
   become: yes
 
-- name: "Generate configuration for: {{ amq_broker_dest }}/{{ amq_broker.instance_name }}"
+- name: "Generate artemis configuration for: {{ amq_broker_dest }}/{{ amq_broker.instance_name }}"
   ansible.builtin.include_tasks: configure.yml
   when:
     - not instance_directory.stat.exists
 
+- name: "Setup clustering with jgroups"
+  ansible.builtin.include_tasks: jgroups.yml
+  when:
+    - amq_broker_ha_enabled
+    - amq_broker_cluster_discovery == 'jgroups'
+
 - name: "Create instance {{ amq_broker.instance_name }} of {{ amq_broker.service_name }}"
   ansible.builtin.command:
     cmd: "{{ amq_broker.home }}/bin/artemis create {{ amq_broker.instance_home }} {{ amq_broker_options }}"
@@ -71,6 +77,8 @@
   ansible.builtin.command: "systemctl status {{ amq_broker.instance_name }}"
   register: amq_broker_service_status
   changed_when: False
+  retries: 6
+  delay: 5
 
 - name: Verify service status
   ansible.builtin.assert:
diff --git a/roles/amq_broker/templates/jgroups_ping.xml.j2 b/roles/amq_broker/templates/jgroups_ping.xml.j2
new file mode 100644
index 00000000..4a72c11b
--- /dev/null
+++ b/roles/amq_broker/templates/jgroups_ping.xml.j2
@@ -0,0 +1,56 @@
+<!-- (( ansible_managed )) -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xmlns="urn:org:jgroups"
+        xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups.xsd">
+
+    <TCP loopback="false"
+         bind_addr="{{ broker_private_ip }}"
+         bind_port="7800"
+         use_send_queues="true"
+         recv_buf_size="${tcp.recv_buf_size:5M}"
+         send_buf_size="${tcp.send_buf_size:5M}"
+         max_bundle_size="64K"
+         max_bundle_timeout="30"
+         sock_conn_timeout="300"
+
+         timer_type="new3"
+         timer.min_threads="4"
+         timer.max_threads="10"
+         timer.keep_alive_time="3000"
+         timer.queue_max_size="500"
+
+         thread_pool.enabled="true"
+         thread_pool.min_threads="2"
+         thread_pool.max_threads="8"
+         thread_pool.keep_alive_time="5000"
+         thread_pool.queue_enabled="true"
+         thread_pool.queue_max_size="10000"
+         thread_pool.rejection_policy="discard"
+
+         oob_thread_pool.enabled="true"
+         oob_thread_pool.min_threads="1"
+         oob_thread_pool.max_threads="8"
+         oob_thread_pool.keep_alive_time="5000"
+         oob_thread_pool.queue_enabled="false"
+         oob_thread_pool.queue_max_size="100"
+         oob_thread_pool.rejection_policy="discard" />
+
+    <FILE_PING location="{{ amq_broker.home }}/{{ amq_broker_shared_storage_path }}/file-ping" />
+    <MERGE3  min_interval="10000"
+             max_interval="30000"/>
+    <FD_SOCK/>
+    <FD timeout="3000" max_tries="3"/>
+    <VERIFY_SUSPECT timeout="1500"/>
+    <BARRIER/>
+    <pbcast.NAKACK2 use_mcast_xmit="false"
+                    discard_delivered_msgs="true"/>
+    <UNICAST3/>
+    <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
+                   max_bytes="4M"/>
+    <pbcast.GMS print_local_addr="true" join_timeout="2000"
+                view_bundling="true"/>
+    <MFC max_credits="2M"
+         min_threshold="0.4"/>
+    <FRAG2 frag_size="60K"/>
+    <pbcast.STATE_TRANSFER/>
+</config>
\ No newline at end of file