diff --git a/ansible/certificates.yml b/ansible/certificates.yml
index 4b6d2528d9..28a1a5f8ee 100644
--- a/ansible/certificates.yml
+++ b/ansible/certificates.yml
@@ -1,6 +1,8 @@
 ---
 - import_playbook: gather-facts.yml
-  when: kolla_enable_tls_backend | default(false) | bool
+  when: >-
+    kolla_enable_tls_backend | default(false) | bool or
+    rabbitmq_enable_tls | default(false) | bool
 
 - name: Apply role certificates
   hosts: localhost
diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml
index aa4938b080..fe30d155ea 100644
--- a/ansible/group_vars/all.yml
+++ b/ansible/group_vars/all.yml
@@ -192,6 +192,11 @@ om_notify_vhost: "/"
 
 notify_transport_url: "{{ om_notify_transport }}://{% for host in groups[om_notify_group] %}{{ om_notify_user }}:{{ om_notify_password }}@{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ om_notify_port }}{% if not loop.last %},{% endif %}{% endfor %}/{{ om_notify_vhost }}"
 
+# Whether to enable TLS for oslo.messaging communication with RabbitMQ.
+om_enable_rabbitmq_tls: "{{ rabbitmq_enable_tls | bool }}"
+# CA certificate bundle in containers using oslo.messaging with RabbitMQ TLS.
+om_rabbitmq_cacert: "{{ rabbitmq_cacert }}"
+
 ####################
 # Networking options
 ####################
@@ -426,7 +431,7 @@ qdrouterd_port: "31459"
 
 qinling_api_port: "7070"
 
-rabbitmq_port: "5672"
+rabbitmq_port: "{{ '5671' if rabbitmq_enable_tls | bool else '5672' }}"
 rabbitmq_management_port: "15672"
 rabbitmq_cluster_port: "25672"
 rabbitmq_epmd_port: "4369"
@@ -748,6 +753,10 @@ osprofiler_backend_connection_string: "{{ redis_connection_string if osprofiler_
 rabbitmq_user: "openstack"
 rabbitmq_monitoring_user: ""
 outward_rabbitmq_user: "openstack"
+# Whether to enable TLS encryption for RabbitMQ client-server communication.
+rabbitmq_enable_tls: "no"
+# CA certificate bundle in RabbitMQ container.
+rabbitmq_cacert: "/etc/ssl/certs/{{ 'ca-certificates.crt' if kolla_base_distro in ['debian', 'ubuntu'] else 'ca-bundle.trust.crt' }}"
 
 ####################
 # Qdrouterd options
diff --git a/ansible/roles/aodh/templates/aodh.conf.j2 b/ansible/roles/aodh/templates/aodh.conf.j2
index 6745323ca6..b9c3b08475 100644
--- a/ansible/roles/aodh/templates/aodh.conf.j2
+++ b/ansible/roles/aodh/templates/aodh.conf.j2
@@ -58,3 +58,8 @@ topics = {{ aodh_enabled_notification_topics | map(attribute='name') | join(',')
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
diff --git a/ansible/roles/barbican/templates/barbican.conf.j2 b/ansible/roles/barbican/templates/barbican.conf.j2
index d7b698579f..1c858fa6dd 100644
--- a/ansible/roles/barbican/templates/barbican.conf.j2
+++ b/ansible/roles/barbican/templates/barbican.conf.j2
@@ -75,6 +75,12 @@ topics = {{ barbican_enabled_notification_topics | map(attribute='name') | join(
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 [oslo_middleware]
 enable_proxy_headers_parsing = True
 
diff --git a/ansible/roles/blazar/templates/blazar.conf.j2 b/ansible/roles/blazar/templates/blazar.conf.j2
index 734b9c326d..2fdc6adfa6 100644
--- a/ansible/roles/blazar/templates/blazar.conf.j2
+++ b/ansible/roles/blazar/templates/blazar.conf.j2
@@ -60,6 +60,11 @@ topics = {{ blazar_enabled_notification_topics | map(attribute='name') | join(',
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
 
 {% if blazar_policy_file is defined %}
 [oslo_policy]
diff --git a/ansible/roles/ceilometer/templates/ceilometer.conf.j2 b/ansible/roles/ceilometer/templates/ceilometer.conf.j2
index 1f15481fa8..e87fdb494a 100644
--- a/ansible/roles/ceilometer/templates/ceilometer.conf.j2
+++ b/ansible/roles/ceilometer/templates/ceilometer.conf.j2
@@ -35,6 +35,12 @@ ca_file = /etc/ceilometer/vmware_ca
 [oslo_messaging_notifications]
 transport_url = {{ notify_transport_url }}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if ceilometer_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ ceilometer_policy_file }}
diff --git a/ansible/roles/certificates/tasks/generate-backend.yml b/ansible/roles/certificates/tasks/generate-backend.yml
index 8eab9e48b3..341f5dcdb7 100644
--- a/ansible/roles/certificates/tasks/generate-backend.yml
+++ b/ansible/roles/certificates/tasks/generate-backend.yml
@@ -62,3 +62,16 @@
     src: "{{ backend_dir }}/backend.key"
     dest: "{{ kolla_certificates_dir }}/backend-key.pem"
     mode: "0660"
+
+- name: Copy backend TLS certificate and key for RabbitMQ
+  copy:
+    src: "{{ item.src }}"
+    dest: "{{ item.dest }}"
+    remote_src: true
+  with_items:
+    - src: "{{ kolla_tls_backend_cert }}"
+      dest: "{{ kolla_certificates_dir }}/rabbitmq-cert.pem"
+    - src: "{{ kolla_tls_backend_key }}"
+      dest: "{{ kolla_certificates_dir }}/rabbitmq-key.pem"
+  when:
+    - rabbitmq_enable_tls | bool
diff --git a/ansible/roles/certificates/tasks/main.yml b/ansible/roles/certificates/tasks/main.yml
index 21b253bebb..f8d80dd9b9 100644
--- a/ansible/roles/certificates/tasks/main.yml
+++ b/ansible/roles/certificates/tasks/main.yml
@@ -3,4 +3,4 @@
 - include_tasks: generate.yml
 - include_tasks: generate-backend.yml
   when:
-    - kolla_enable_tls_backend | bool
+    - kolla_enable_tls_backend | bool or rabbitmq_enable_tls | bool
diff --git a/ansible/roles/cinder/templates/cinder.conf.j2 b/ansible/roles/cinder/templates/cinder.conf.j2
index 2ab967de6f..c80ae265de 100644
--- a/ansible/roles/cinder/templates/cinder.conf.j2
+++ b/ansible/roles/cinder/templates/cinder.conf.j2
@@ -69,6 +69,12 @@ topics = {{ cinder_enabled_notification_topics | map(attribute='name') | join(',
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 [oslo_middleware]
 enable_proxy_headers_parsing = True
 
diff --git a/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2 b/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2
index cc1ebaf5aa..16293a79a6 100644
--- a/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2
+++ b/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2
@@ -43,6 +43,12 @@ lock_path = /var/lib/cloudkitty/tmp
 policy_file = {{ cloudkitty_policy_file }}
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 [collect]
 collector = {{ cloudkitty_collector_backend }}
 {% if cloudkitty_custom_metrics_used %}
diff --git a/ansible/roles/cyborg/templates/cyborg.conf.j2 b/ansible/roles/cyborg/templates/cyborg.conf.j2
index 61a5673b1d..89a3191090 100644
--- a/ansible/roles/cyborg/templates/cyborg.conf.j2
+++ b/ansible/roles/cyborg/templates/cyborg.conf.j2
@@ -54,3 +54,9 @@ topics = {{ cyborg_enabled_notification_topics | map(attribute='name') | join(',
 {% else %}
 driver = noop
 {% endif %}
+
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
diff --git a/ansible/roles/designate/templates/designate.conf.j2 b/ansible/roles/designate/templates/designate.conf.j2
index 2d1701aa56..67101ef742 100644
--- a/ansible/roles/designate/templates/designate.conf.j2
+++ b/ansible/roles/designate/templates/designate.conf.j2
@@ -89,6 +89,12 @@ topics = {{ designate_enabled_notification_topics | map(attribute='name') | join
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 [oslo_concurrency]
 lock_path = /var/lib/designate/tmp
 
diff --git a/ansible/roles/glance/templates/glance-api.conf.j2 b/ansible/roles/glance/templates/glance-api.conf.j2
index 5ad3a5c00c..d784df3ca8 100644
--- a/ansible/roles/glance/templates/glance-api.conf.j2
+++ b/ansible/roles/glance/templates/glance-api.conf.j2
@@ -120,6 +120,12 @@ topics = {{ glance_enabled_notification_topics | map(attribute='name') | join(',
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if glance_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ glance_policy_file }}
diff --git a/ansible/roles/heat/templates/heat.conf.j2 b/ansible/roles/heat/templates/heat.conf.j2
index c7245e0a26..08f32be9ab 100644
--- a/ansible/roles/heat/templates/heat.conf.j2
+++ b/ansible/roles/heat/templates/heat.conf.j2
@@ -84,6 +84,12 @@ topics = {{ heat_enabled_notification_topics | map(attribute='name') | join(',')
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if heat_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ heat_policy_file }}
diff --git a/ansible/roles/ironic/templates/ironic-inspector.conf.j2 b/ansible/roles/ironic/templates/ironic-inspector.conf.j2
index 3a3d4a8933..ac7f62211e 100644
--- a/ansible/roles/ironic/templates/ironic-inspector.conf.j2
+++ b/ansible/roles/ironic/templates/ironic-inspector.conf.j2
@@ -12,6 +12,12 @@ transport_url = {{ rpc_transport_url }}
 [oslo_messaging_notifications]
 transport_url = {{ notify_transport_url }}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 [ironic]
 {% if enable_keystone | bool %}
 auth_url = {{ keystone_admin_url }}
diff --git a/ansible/roles/ironic/templates/ironic.conf.j2 b/ansible/roles/ironic/templates/ironic.conf.j2
index 79d387cf8a..7854d0eccc 100644
--- a/ansible/roles/ironic/templates/ironic.conf.j2
+++ b/ansible/roles/ironic/templates/ironic.conf.j2
@@ -30,6 +30,12 @@ topics = {{ ironic_enabled_notification_topics | map(attribute='name') | join(',
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if ironic_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ ironic_policy_file }}
diff --git a/ansible/roles/karbor/templates/karbor.conf.j2 b/ansible/roles/karbor/templates/karbor.conf.j2
index d31985b12c..936f204f27 100644
--- a/ansible/roles/karbor/templates/karbor.conf.j2
+++ b/ansible/roles/karbor/templates/karbor.conf.j2
@@ -57,5 +57,11 @@ topics = {{ karbor_enabled_notification_topics | map(attribute='name') | join(',
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 [oslo_middleware]
 enable_proxy_headers_parsing = True
diff --git a/ansible/roles/keystone/templates/keystone.conf.j2 b/ansible/roles/keystone/templates/keystone.conf.j2
index 06d57eb3b2..730107eaca 100644
--- a/ansible/roles/keystone/templates/keystone.conf.j2
+++ b/ansible/roles/keystone/templates/keystone.conf.j2
@@ -59,6 +59,11 @@ topics = {{ keystone_enabled_notification_topics | map(attribute='name') | join(
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
 
 {% if enable_osprofiler | bool %}
 [profiler]
diff --git a/ansible/roles/magnum/templates/magnum.conf.j2 b/ansible/roles/magnum/templates/magnum.conf.j2
index c0cb531aa9..f1d9742562 100644
--- a/ansible/roles/magnum/templates/magnum.conf.j2
+++ b/ansible/roles/magnum/templates/magnum.conf.j2
@@ -112,6 +112,12 @@ topics = {{ magnum_enabled_notification_topics | map(attribute='name') | join(',
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if magnum_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ magnum_policy_file }}
diff --git a/ansible/roles/manila/templates/manila.conf.j2 b/ansible/roles/manila/templates/manila.conf.j2
index 171033f732..9bf62cadf7 100644
--- a/ansible/roles/manila/templates/manila.conf.j2
+++ b/ansible/roles/manila/templates/manila.conf.j2
@@ -54,6 +54,11 @@ topics = {{ manila_enabled_notification_topics | map(attribute='name') | join(',
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
 
 [oslo_middleware]
 enable_proxy_headers_parsing = True
diff --git a/ansible/roles/masakari/templates/masakari.conf.j2 b/ansible/roles/masakari/templates/masakari.conf.j2
index 5a0bab0fc9..da0ef60ad4 100644
--- a/ansible/roles/masakari/templates/masakari.conf.j2
+++ b/ansible/roles/masakari/templates/masakari.conf.j2
@@ -48,6 +48,12 @@ topics = notifications
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 [oslo_middleware]
 enable_proxy_headers_parsing = True
 
diff --git a/ansible/roles/mistral/templates/mistral.conf.j2 b/ansible/roles/mistral/templates/mistral.conf.j2
index de3540ad5c..c784c1105e 100644
--- a/ansible/roles/mistral/templates/mistral.conf.j2
+++ b/ansible/roles/mistral/templates/mistral.conf.j2
@@ -70,6 +70,12 @@ topics = {{ mistral_enabled_notification_topics | map(attribute='name') | join('
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if mistral_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ mistral_policy_file }}
diff --git a/ansible/roles/murano/templates/murano.conf.j2 b/ansible/roles/murano/templates/murano.conf.j2
index ce67b458f7..5b9194a774 100644
--- a/ansible/roles/murano/templates/murano.conf.j2
+++ b/ansible/roles/murano/templates/murano.conf.j2
@@ -59,6 +59,12 @@ topics = {{ murano_enabled_notification_topics | map(attribute='name') | join(',
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 [oslo_middleware]
 enable_proxy_headers_parsing = True
 
diff --git a/ansible/roles/neutron/templates/neutron.conf.j2 b/ansible/roles/neutron/templates/neutron.conf.j2
index 4b8510dea5..ee7ed148c8 100644
--- a/ansible/roles/neutron/templates/neutron.conf.j2
+++ b/ansible/roles/neutron/templates/neutron.conf.j2
@@ -129,6 +129,12 @@ topics = {{ neutron_enabled_notification_topics | map(attribute='name') | join('
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if neutron_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ neutron_policy_file }}
diff --git a/ansible/roles/nova-cell/templates/nova.conf.j2 b/ansible/roles/nova-cell/templates/nova.conf.j2
index d54ab23be5..81852d5e70 100644
--- a/ansible/roles/nova-cell/templates/nova.conf.j2
+++ b/ansible/roles/nova-cell/templates/nova.conf.j2
@@ -183,6 +183,12 @@ topics = {{ nova_enabled_notification_topics | map(attribute='name') | join(',')
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if service_name in nova_cell_services_require_policy_json and nova_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ nova_policy_file }}
diff --git a/ansible/roles/nova/templates/nova.conf.j2 b/ansible/roles/nova/templates/nova.conf.j2
index 5a7f88dbbd..2795c14759 100644
--- a/ansible/roles/nova/templates/nova.conf.j2
+++ b/ansible/roles/nova/templates/nova.conf.j2
@@ -132,6 +132,12 @@ topics = {{ nova_enabled_notification_topics | map(attribute='name') | join(',')
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if service_name in nova_services_require_policy_json and nova_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ nova_policy_file }}
diff --git a/ansible/roles/octavia/templates/octavia.conf.j2 b/ansible/roles/octavia/templates/octavia.conf.j2
index 33289a9a91..3d42d7aa77 100644
--- a/ansible/roles/octavia/templates/octavia.conf.j2
+++ b/ansible/roles/octavia/templates/octavia.conf.j2
@@ -88,6 +88,12 @@ rpc_thread_pool_size = 2
 [oslo_messaging_notifications]
 transport_url = {{ notify_transport_url }}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if octavia_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ octavia_policy_file }}
diff --git a/ansible/roles/qinling/templates/qinling.conf.j2 b/ansible/roles/qinling/templates/qinling.conf.j2
index 030edd9354..ee9f8702c9 100644
--- a/ansible/roles/qinling/templates/qinling.conf.j2
+++ b/ansible/roles/qinling/templates/qinling.conf.j2
@@ -55,6 +55,12 @@ topics = notifications
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if qinling_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ qinling_policy_file }}
diff --git a/ansible/roles/rabbitmq/defaults/main.yml b/ansible/roles/rabbitmq/defaults/main.yml
index 8c3553a040..1d93ca5491 100644
--- a/ansible/roles/rabbitmq/defaults/main.yml
+++ b/ansible/roles/rabbitmq/defaults/main.yml
@@ -72,3 +72,5 @@ rabbitmq_cluster_name: "openstack"
 rabbitmq_hostname: "{{ ansible_hostname }}"
 rabbitmq_pid_file: "/var/lib/rabbitmq/mnesia/rabbitmq.pid"
 rabbitmq_server_additional_erl_args: ""
+# Dict of TLS options for RabbitMQ. Keys will be prefixed with 'ssl_options.'.
+rabbitmq_tls_options: {}
diff --git a/ansible/roles/rabbitmq/handlers/main.yml b/ansible/roles/rabbitmq/handlers/main.yml
index 515126e0bf..d3cb4d717d 100644
--- a/ansible/roles/rabbitmq/handlers/main.yml
+++ b/ansible/roles/rabbitmq/handlers/main.yml
@@ -17,6 +17,7 @@
     - inventory_hostname == groups[service.group]|first
   notify:
     - Waiting for rabbitmq to start on first node
+  listen: Restart rabbitmq container
 
 - name: Waiting for rabbitmq to start on first node
   vars:
@@ -43,3 +44,4 @@
   when:
     - kolla_action != "config"
     - inventory_hostname != groups[service.group]|first
+  listen: Restart rabbitmq container
diff --git a/ansible/roles/rabbitmq/tasks/check-containers.yml b/ansible/roles/rabbitmq/tasks/check-containers.yml
index 7cb590b5b9..0ff847b49f 100644
--- a/ansible/roles/rabbitmq/tasks/check-containers.yml
+++ b/ansible/roles/rabbitmq/tasks/check-containers.yml
@@ -14,5 +14,4 @@
     - item.value.enabled | bool
   with_dict: "{{ rabbitmq_services }}"
   notify:
-    - Restart rabbitmq container (first node)
-    - Restart rabbitmq container (rest of nodes)
+    - Restart rabbitmq container
diff --git a/ansible/roles/rabbitmq/tasks/config.yml b/ansible/roles/rabbitmq/tasks/config.yml
index 25a977b6c5..9e9f4f2213 100644
--- a/ansible/roles/rabbitmq/tasks/config.yml
+++ b/ansible/roles/rabbitmq/tasks/config.yml
@@ -23,8 +23,7 @@
     - item.value.enabled | bool
   with_dict: "{{ rabbitmq_services }}"
   notify:
-    - Restart rabbitmq container (first node)
-    - Restart rabbitmq container (rest of nodes)
+    - Restart rabbitmq container
 
 - name: Copying over rabbitmq-env.conf
   become: true
@@ -42,9 +41,7 @@
     - inventory_hostname in groups[service.group]
     - service.enabled | bool
   notify:
-    - Restart rabbitmq container (first node)
-    - Restart rabbitmq container (rest of nodes)
-
+    - Restart rabbitmq container
 
 - name: Copying over rabbitmq.conf
   become: true
@@ -62,8 +59,7 @@
     - inventory_hostname in groups[service.group]
     - service.enabled | bool
   notify:
-    - Restart rabbitmq container (first node)
-    - Restart rabbitmq container (rest of nodes)
+    - Restart rabbitmq container
 
 - name: Copying over erl_inetrc
   become: true
@@ -81,8 +77,7 @@
     - inventory_hostname in groups[service.group]
     - service.enabled | bool
   notify:
-    - Restart rabbitmq container (first node)
-    - Restart rabbitmq container (rest of nodes)
+    - Restart rabbitmq container
 
 - name: Copying over definitions.json
   become: true
@@ -100,8 +95,10 @@
     - inventory_hostname in groups[service.group]
     - service.enabled | bool
   notify:
-    - Restart rabbitmq container (first node)
-    - Restart rabbitmq container (rest of nodes)
+    - Restart rabbitmq container
+
+- include_tasks: copy-certs.yml
+  when: rabbitmq_enable_tls | bool
 
 - import_tasks: check-containers.yml
   when: kolla_action != "config"
diff --git a/ansible/roles/rabbitmq/tasks/copy-certs.yml b/ansible/roles/rabbitmq/tasks/copy-certs.yml
new file mode 100644
index 0000000000..f3c84a49ab
--- /dev/null
+++ b/ansible/roles/rabbitmq/tasks/copy-certs.yml
@@ -0,0 +1,52 @@
+---
+- name: Copying over extra CA certificates
+  become: true
+  vars:
+    service: "{{ rabbitmq_services['rabbitmq'] }}"
+  copy:
+    src: "{{ kolla_certificates_dir }}/ca/"
+    dest: "{{ node_config_directory }}/{{ project_name }}/ca-certificates"
+    mode: "0644"
+  when:
+    - kolla_copy_ca_into_containers | bool
+    - service | service_enabled_and_mapped_to_host
+  notify:
+    - Restart rabbitmq container
+
+- name: Copying over TLS certificate
+  become: true
+  vars:
+    service: "{{ rabbitmq_services['rabbitmq'] }}"
+  copy:
+    src: "{{ item }}"
+    dest: "{{ node_config_directory }}/{{ project_name }}/{{ project_name }}-cert.pem"
+    mode: "0644"
+  with_first_found:
+    - files:
+        - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}/{{ project_name }}-cert.pem"
+        - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}-cert.pem"
+        - "{{ kolla_certificates_dir }}/{{ project_name }}-cert.pem"
+      skip: true
+  when:
+    - service | service_enabled_and_mapped_to_host
+  notify:
+    - Restart rabbitmq container
+
+- name: Copying over TLS key
+  become: true
+  vars:
+    service: "{{ rabbitmq_services['rabbitmq'] }}"
+  copy:
+    src: "{{ item }}"
+    dest: "{{ node_config_directory }}/{{ project_name }}/{{ project_name }}-key.pem"
+    mode: "0600"
+  with_first_found:
+    - files:
+        - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}/{{ project_name }}-key.pem"
+        - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}-key.pem"
+        - "{{ kolla_certificates_dir }}/{{ project_name }}-key.pem"
+      skip: true
+  when:
+    - service | service_enabled_and_mapped_to_host
+  notify:
+    - Restart rabbitmq container
diff --git a/ansible/roles/rabbitmq/tasks/precheck.yml b/ansible/roles/rabbitmq/tasks/precheck.yml
index a7baf2afa4..3dc37bc88f 100644
--- a/ansible/roles/rabbitmq/tasks/precheck.yml
+++ b/ansible/roles/rabbitmq/tasks/precheck.yml
@@ -74,6 +74,32 @@
   when:
     - not item.1 is match('^'+('api' | kolla_address(item.0.item))+'\\b')
 
+- name: Check if TLS certificate exists for RabbitMQ
+  vars:
+    cert: "{{ query('first_found', paths, errors='ignore') }}"
+    paths:
+      - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}/rabbitmq-cert.pem"
+      - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}-cert.pem"
+      - "{{ kolla_certificates_dir }}/rabbitmq-cert.pem"
+  fail:
+    msg: No TLS certificate provided for RabbitMQ.
+  when:
+    - rabbitmq_enable_tls | bool
+    - cert | length == 0
+
+- name: Check if TLS key exists for RabbitMQ
+  vars:
+    key: "{{ query('first_found', paths, errors='ignore') }}"
+    paths:
+      - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}/rabbitmq-key.pem"
+      - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}-key.pem"
+      - "{{ kolla_certificates_dir }}/rabbitmq-key.pem"
+  fail:
+    msg: No TLS key provided for RabbitMQ.
+  when:
+    - rabbitmq_enable_tls | bool
+    - key | length == 0
+
 - name: Checking free port for outward RabbitMQ
   wait_for:
     host: "{{ api_interface_address }}"
@@ -137,3 +163,31 @@
   when:
     - enable_outward_rabbitmq | bool
     - not item.1 is match('^'+('api' | kolla_address(item.0.item))+'\\b')
+
+- name: Check if TLS certificate exists for outward RabbitMQ
+  vars:
+    cert: "{{ query('first_found', paths, errors='ignore') }}"
+    paths:
+      - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}/outward_rabbitmq-cert.pem"
+      - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}-cert.pem"
+      - "{{ kolla_certificates_dir }}/outward_rabbitmq-cert.pem"
+  fail:
+    msg: No TLS certificate provided for outward RabbitMQ.
+  when:
+    - enable_outward_rabbitmq | bool
+    - rabbitmq_enable_tls | bool
+    - cert | length == 0
+
+- name: Check if TLS key exists for outward RabbitMQ
+  vars:
+    key: "{{ query('first_found', paths, errors='ignore') }}"
+    paths:
+      - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}/outward_rabbitmq-key.pem"
+      - "{{ kolla_certificates_dir }}/{{ inventory_hostname }}-key.pem"
+      - "{{ kolla_certificates_dir }}/outward_rabbitmq-key.pem"
+  fail:
+    msg: No TLS key provided for outward RabbitMQ.
+  when:
+    - enable_outward_rabbitmq | bool
+    - rabbitmq_enable_tls | bool
+    - key | length == 0
diff --git a/ansible/roles/rabbitmq/templates/rabbitmq.conf.j2 b/ansible/roles/rabbitmq/templates/rabbitmq.conf.j2
index f897499dac..25ec6b46f3 100644
--- a/ansible/roles/rabbitmq/templates/rabbitmq.conf.j2
+++ b/ansible/roles/rabbitmq/templates/rabbitmq.conf.j2
@@ -1,6 +1,11 @@
 # NOTE(yoctozepto): rabbitmq uses the raw format (e.g. fd::) of IPv6 address;
 # despite specifying port via colon, the url format (e.g. [fd::]) is not accepted
+{% if rabbitmq_enable_tls | bool %}
+listeners.tcp = none
+listeners.ssl.1 = {{ api_interface_address }}:{{ role_rabbitmq_port }}
+{% else %}
 listeners.tcp.1 = {{ api_interface_address }}:{{ role_rabbitmq_port }}
+{% endif %}
 {# NOTE: to avoid split-brain #}
 cluster_partition_handling = pause_minority
 
@@ -12,3 +17,12 @@ cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config
 {% for host in groups[role_rabbitmq_groups] %}
 cluster_formation.classic_config.nodes.{{ loop.index0 }} = rabbit@{{ hostvars[host]['ansible_hostname'] }}
 {% endfor %}
+
+{% if rabbitmq_enable_tls | bool %}
+# https://www.rabbitmq.com/ssl.html
+ssl_options.certfile = /etc/rabbitmq/certs/{{ project_name }}-cert.pem
+ssl_options.keyfile = /etc/rabbitmq/certs/{{ project_name }}-key.pem
+{% for key, value in rabbitmq_tls_options.items() %}
+ssl_options.{{ key }} = {{ value }}
+{% endfor %}
+{% endif %}
diff --git a/ansible/roles/rabbitmq/templates/rabbitmq.json.j2 b/ansible/roles/rabbitmq/templates/rabbitmq.json.j2
index 91e67e15b4..d93df3ad18 100644
--- a/ansible/roles/rabbitmq/templates/rabbitmq.json.j2
+++ b/ansible/roles/rabbitmq/templates/rabbitmq.json.j2
@@ -24,7 +24,19 @@
             "dest": "/etc/rabbitmq/definitions.json",
             "owner": "rabbitmq",
             "perm": "0600"
-        }
+        }{% if rabbitmq_enable_tls | bool %},
+        {
+            "source": "{{ container_config_directory }}/{{ project_name }}-cert.pem",
+            "dest": "/etc/rabbitmq/certs/{{ project_name }}-cert.pem",
+            "owner": "rabbitmq",
+            "perm": "0600"
+        },
+        {
+            "source": "{{ container_config_directory }}/{{ project_name }}-key.pem",
+            "dest": "/etc/rabbitmq/certs/{{ project_name }}-key.pem",
+            "owner": "rabbitmq",
+            "perm": "0600"
+        }{% endif %}
     ],
     "permissions": [
         {
diff --git a/ansible/roles/sahara/templates/sahara.conf.j2 b/ansible/roles/sahara/templates/sahara.conf.j2
index 9b4c15661f..c982e375e8 100644
--- a/ansible/roles/sahara/templates/sahara.conf.j2
+++ b/ansible/roles/sahara/templates/sahara.conf.j2
@@ -38,6 +38,12 @@ topics = {{ sahara_enabled_notification_topics | map(attribute='name') | join(',
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if sahara_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ sahara_policy_file }}
diff --git a/ansible/roles/searchlight/templates/searchlight.conf.j2 b/ansible/roles/searchlight/templates/searchlight.conf.j2
index e1ea68cfed..1c51fbcc61 100644
--- a/ansible/roles/searchlight/templates/searchlight.conf.j2
+++ b/ansible/roles/searchlight/templates/searchlight.conf.j2
@@ -44,6 +44,11 @@ topics = {{ searchlight_enabled_notification_topics | map(attribute='name') | jo
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
 
 {% if searchlight_policy_file is defined %}
 [oslo_policy]
diff --git a/ansible/roles/senlin/templates/senlin.conf.j2 b/ansible/roles/senlin/templates/senlin.conf.j2
index 2764bf07d3..5879a8f222 100644
--- a/ansible/roles/senlin/templates/senlin.conf.j2
+++ b/ansible/roles/senlin/templates/senlin.conf.j2
@@ -66,6 +66,12 @@ topics = {{ senlin_enabled_notification_topics | map(attribute='name') | join(',
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if senlin_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ senlin_policy_file }}
diff --git a/ansible/roles/solum/templates/solum.conf.j2 b/ansible/roles/solum/templates/solum.conf.j2
index 02d46ecc9e..e4d3c4647a 100644
--- a/ansible/roles/solum/templates/solum.conf.j2
+++ b/ansible/roles/solum/templates/solum.conf.j2
@@ -61,3 +61,9 @@ memcached_servers = {% for host in groups['memcached'] %}{{ 'api' | kolla_addres
 
 [oslo_messaging_notifications]
 transport_url = {{ notify_transport_url }}
+
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
diff --git a/ansible/roles/tacker/templates/tacker.conf.j2 b/ansible/roles/tacker/templates/tacker.conf.j2
index c76b83bd20..4f89287555 100644
--- a/ansible/roles/tacker/templates/tacker.conf.j2
+++ b/ansible/roles/tacker/templates/tacker.conf.j2
@@ -66,6 +66,12 @@ topics = {{ tacker_enabled_notification_topics | map(attribute='name') | join(',
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if tacker_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ tacker_policy_file }}
diff --git a/ansible/roles/trove/templates/trove-conductor.conf.j2 b/ansible/roles/trove/templates/trove-conductor.conf.j2
index 42247a3b03..6aaf468563 100644
--- a/ansible/roles/trove/templates/trove-conductor.conf.j2
+++ b/ansible/roles/trove/templates/trove-conductor.conf.j2
@@ -25,6 +25,12 @@ topics = {{ trove_enabled_notification_topics | map(attribute='name') | join(','
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 [database]
 connection = mysql+pymysql://{{ trove_database_user }}:{{ trove_database_password }}@{{ trove_database_address }}/{{ trove_database_name }}
 connection_recycle_time = {{ database_connection_recycle_time }}
diff --git a/ansible/roles/trove/templates/trove-taskmanager.conf.j2 b/ansible/roles/trove/templates/trove-taskmanager.conf.j2
index 9c4d4ac498..c578bbf8ec 100644
--- a/ansible/roles/trove/templates/trove-taskmanager.conf.j2
+++ b/ansible/roles/trove/templates/trove-taskmanager.conf.j2
@@ -48,6 +48,11 @@ topics = {{ trove_enabled_notification_topics | map(attribute='name') | join(','
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
 
 {% if enable_osprofiler | bool %}
 [profiler]
diff --git a/ansible/roles/trove/templates/trove.conf.j2 b/ansible/roles/trove/templates/trove.conf.j2
index 3bb9199aa6..e642ed2687 100644
--- a/ansible/roles/trove/templates/trove.conf.j2
+++ b/ansible/roles/trove/templates/trove.conf.j2
@@ -55,6 +55,12 @@ topics = {{ trove_enabled_notification_topics | map(attribute='name') | join(','
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if enable_osprofiler | bool %}
 [profiler]
 enabled = true
diff --git a/ansible/roles/vitrage/templates/vitrage.conf.j2 b/ansible/roles/vitrage/templates/vitrage.conf.j2
index 12cf804956..e007c03cd0 100644
--- a/ansible/roles/vitrage/templates/vitrage.conf.j2
+++ b/ansible/roles/vitrage/templates/vitrage.conf.j2
@@ -72,6 +72,12 @@ topics = {{ vitrage_enabled_notification_topics | map(attribute='name') | join('
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 [oslo_concurrency]
 lock_path = /var/lib/vitrage/tmp
 
diff --git a/ansible/roles/watcher/templates/watcher.conf.j2 b/ansible/roles/watcher/templates/watcher.conf.j2
index 33178edd47..3f655da1dc 100644
--- a/ansible/roles/watcher/templates/watcher.conf.j2
+++ b/ansible/roles/watcher/templates/watcher.conf.j2
@@ -57,6 +57,12 @@ topics = {{ watcher_enabled_notification_topics | map(attribute='name') | join('
 driver = noop
 {% endif %}
 
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
+
 {% if watcher_policy_file is defined %}
 [oslo_policy]
 policy_file = {{ watcher_policy_file }}
diff --git a/ansible/roles/zun/templates/zun.conf.j2 b/ansible/roles/zun/templates/zun.conf.j2
index a3358c51c5..4600a48229 100644
--- a/ansible/roles/zun/templates/zun.conf.j2
+++ b/ansible/roles/zun/templates/zun.conf.j2
@@ -127,3 +127,9 @@ docker_remote_api_port = 2375
 
 [cni_daemon]
 cni_daemon_port = {{ zun_cni_daemon_port }}
+
+{% if om_enable_rabbitmq_tls | bool %}
+[oslo_messaging_rabbit]
+ssl = true
+ssl_ca_file = {{ om_rabbitmq_cacert }}
+{% endif %}
diff --git a/doc/source/admin/advanced-configuration.rst b/doc/source/admin/advanced-configuration.rst
index d228c83345..82f28654a3 100644
--- a/doc/source/admin/advanced-configuration.rst
+++ b/doc/source/admin/advanced-configuration.rst
@@ -69,6 +69,8 @@ RabbitMQ doesn't work with IP address, hence the IP address of
 ``api_interface`` should be resolvable by hostnames to make sure that
 all RabbitMQ Cluster hosts can resolve each others hostname beforehand.
 
+.. _tls-configuration:
+
 TLS Configuration
 ~~~~~~~~~~~~~~~~~
 
diff --git a/doc/source/conf.py b/doc/source/conf.py
index f10c47e994..b7b15c4b7d 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -98,6 +98,7 @@ openstack_projects = [
     'neutron',
     'nova',
     'octavia',
+    'oslo.messaging',
     'oslotest',
     'swift',
 ]
diff --git a/doc/source/reference/message-queues/rabbitmq.rst b/doc/source/reference/message-queues/rabbitmq.rst
index 1457327ce0..916df309c8 100644
--- a/doc/source/reference/message-queues/rabbitmq.rst
+++ b/doc/source/reference/message-queues/rabbitmq.rst
@@ -8,6 +8,81 @@ RabbitMQ is a message broker written in Erlang.
 It is currently the default provider of message queues in Kolla Ansible
 deployments.
 
+TLS encryption
+~~~~~~~~~~~~~~
+
+There are a number of channels to consider when securing RabbitMQ
+communication. Kolla Ansible currently supports TLS encryption of the
+following:
+
+* client-server traffic, typically between OpenStack services using the
+  :oslo.messaging-doc:`oslo.messaging </>` library and RabbitMQ
+* RabbitMQ Management API and UI (frontend connection to HAProxy only)
+
+Encryption of the following channels is not currently supported:
+
+* RabbitMQ cluster traffic between RabbitMQ server nodes
+* RabbitMQ CLI communication with RabbitMQ server nodes
+* RabbitMQ Management API and UI (backend connection from HAProxy to RabbitMQ)
+
+Client-server
+-------------
+
+Encryption of client-server traffic is enabled by setting
+``rabbitmq_enable_tls`` to ``true``. Additionally, certificates and keys must
+be available in the following paths (in priority order):
+
+Certificates:
+
+* ``"{{ kolla_certificates_dir }}/{{ inventory_hostname }}/rabbitmq-cert.pem"``
+* ``"{{ kolla_certificates_dir }}/{{ inventory_hostname }}-cert.pem"``
+* ``"{{ kolla_certificates_dir }}/rabbitmq-cert.pem"``
+
+Keys:
+
+* ``"{{ kolla_certificates_dir }}/{{ inventory_hostname }}/rabbitmq-key.pem"``
+* ``"{{ kolla_certificates_dir }}/{{ inventory_hostname }}-key.pem"``
+* ``"{{ kolla_certificates_dir }}/rabbitmq-key.pem"``
+
+The default for ``kolla_certificates_dir`` is ``/etc/kolla/certificates``.
+
+The certificates must be valid for the IP address of the host running RabbitMQ
+on the API network.
+
+Additional TLS configuration options may be passed to RabbitMQ via
+``rabbitmq_tls_options``. This should be a dict, and the keys will be prefixed
+with ``ssl_options.``. For example:
+
+.. code-block:: yaml
+
+   rabbitmq_tls_options:
+     ciphers.1: ECDHE-ECDSA-AES256-GCM-SHA384
+     ciphers.2: ECDHE-RSA-AES256-GCM-SHA384
+     ciphers.3: ECDHE-ECDSA-AES256-SHA384
+     honor_cipher_order: true
+     honor_ecc_order: true
+
+Details on configuration of RabbitMQ for TLS can be found in the `RabbitMQ
+documentation <https://www.rabbitmq.com/ssl.html>`__.
+
+When ``om_rabbitmq_enable_tls`` is ``true`` (it defaults to the value of
+``rabbitmq_enable_tls``), applicable OpenStack services will be configured to
+use oslo.messaging with TLS enabled. The CA certificate is configured via
+``om_rabbitmq_cacert`` (it defaults to ``rabbitmq_cacert``, which points to the
+system's trusted CA certificate bundle for TLS). Note that there is currently
+no support for using client certificates.
+
+For testing purposes, Kolla Ansible provides the ``kolla-ansible certificates``
+command, which will generate self-signed certificates for RabbitMQ if
+``rabbitmq_enable_tls`` is ``true``.
+
+Management API and UI
+---------------------
+
+The management API and UI are accessed via HAProxy, exposed only on the
+internal VIP. As such, traffic to this endpoint is encrypted when
+``kolla_enable_tls_internal`` is ``true``. See :ref:`tls-configuration`.
+
 Passing arguments to RabbitMQ server's Erlang VM
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/etc/kolla/globals.yml b/etc/kolla/globals.yml
index 34c2ae69eb..f1b5336b3e 100644
--- a/etc/kolla/globals.yml
+++ b/etc/kolla/globals.yml
@@ -84,6 +84,10 @@
 #om_rpc_port: "{{ qdrouterd_port }}"
 #om_rpc_group: "qdrouterd"
 
+# Whether to enable TLS for oslo.messaging communication with RabbitMQ.
+#om_enable_rabbitmq_tls: "{{ rabbitmq_enable_tls | bool }}"
+# CA certificate bundle in containers using oslo.messaging with RabbitMQ TLS.
+#om_rabbitmq_cacert: "{{ rabbitmq_cacert }}"
 
 ##############################
 # Neutron - Networking Options
@@ -373,6 +377,10 @@
 # These are appended to args already provided by Kolla Ansible
 # to configure IPv6 in RabbitMQ server.
 #rabbitmq_server_additional_erl_args: ""
+# Whether to enable TLS encryption for RabbitMQ client-server communication.
+#rabbitmq_enable_tls: "no"
+# CA certificate bundle in RabbitMQ container.
+#rabbitmq_cacert: "/etc/ssl/certs/{{ 'ca-certificates.crt' if kolla_base_distro in ['debian', 'ubuntu'] else 'ca-bundle.trust.crt' }}"
 
 #################
 # MariaDB options
diff --git a/releasenotes/notes/rabbitmq-tls-78ea3fddf67267f2.yaml b/releasenotes/notes/rabbitmq-tls-78ea3fddf67267f2.yaml
new file mode 100644
index 0000000000..f8bced3bac
--- /dev/null
+++ b/releasenotes/notes/rabbitmq-tls-78ea3fddf67267f2.yaml
@@ -0,0 +1,7 @@
+---
+features:
+  - |
+    Adds support for TLS encryption of RabbitMQ client-server communication.
+    See `blueprint
+    <https://blueprints.launchpad.net/kolla-ansible/+spec/message-queue-ssl-support>`__
+    for details.
diff --git a/tests/templates/globals-default.j2 b/tests/templates/globals-default.j2
index 2740ab1ef5..bf4364d913 100644
--- a/tests/templates/globals-default.j2
+++ b/tests/templates/globals-default.j2
@@ -134,6 +134,7 @@ openstack_cacert: "/etc/ssl/certs/ca-certificates.crt"
 openstack_cacert: "/etc/pki/tls/certs/ca-bundle.crt"
 {% endif %}
 kolla_admin_openrc_cacert: "{% raw %}{{ kolla_certificates_dir }}{% endraw %}/ca/root.crt"
+rabbitmq_enable_tls: "yes"
 {% endif %}
 
 {% if scenario == 'linuxbridge' %}