diff --git a/ansible/group_vars/all/kolla b/ansible/group_vars/all/kolla
index b8bdd46a89b63f5100519907ade82ea3c68dc718..c42ef8eaf68e0de5a8d434c41a2bd006150a66fc 100644
--- a/ansible/group_vars/all/kolla
+++ b/ansible/group_vars/all/kolla
@@ -144,6 +144,8 @@ overcloud_container_image_regex_map:
     enabled: "{{ kolla_enable_ironic | bool }}"
   - regex: iscsid
     enabled: "{{ kolla_enable_cinder | bool or kolla_enable_ironic | bool }}"
+  - regex: kafka
+    enabled: "{{ kolla_enable_kafka | bool }}"
   - regex: keepalived
     enabled: "{{ kolla_enable_haproxy | bool }}"
   - regex: keystone
@@ -301,7 +303,6 @@ kolla_enable_haproxy: "yes"
 kolla_enable_heat: "yes"
 kolla_enable_horizon: "yes"
 kolla_enable_ironic: "yes"
-# Kafka is not currently supported
 kolla_enable_kafka: "no"
 kolla_enable_kibana: "{{ 'yes' if kolla_enable_central_logging | bool else 'no' }}"
 kolla_enable_magnum: "no"
@@ -316,7 +317,7 @@ kolla_enable_osprofiler: "no"
 kolla_enable_sahara: "no"
 kolla_enable_skydive: "no"
 kolla_enable_swift: "no"
-kolla_enable_zookeeper: "no"
+kolla_enable_zookeeper: "{{ 'yes' if kolla_enable_kafka | bool else 'no' }}"
 
 ###############################################################################
 # Passwords and credentials.
diff --git a/ansible/kolla-openstack.yml b/ansible/kolla-openstack.yml
index babf5d5653451747112e170d7a19f5ecf360eda8..e10c58113bc9213396f4b0389ff9d76fc9fa8d0b 100644
--- a/ansible/kolla-openstack.yml
+++ b/ansible/kolla-openstack.yml
@@ -107,6 +107,7 @@
             - { name: inspector, file: ironic-inspector.conf }
             - { name: ironic, file: ironic.conf }
             - { name: ironic_dnsmasq, file: ironic/ironic-dnsmasq.conf }
+            - { name: kafka, file: kafka.server.properties }
             - { name: magnum, file: magnum.conf }
             - { name: murano, file: murano.conf }
             - { name: neutron, file: neutron.conf }
@@ -208,6 +209,7 @@
       kolla_extra_inspector: "{{ kolla_extra_config.inspector | default }}"
       kolla_extra_ironic: "{{ kolla_extra_config.ironic | default }}"
       kolla_extra_ironic_dnsmasq: "{{ kolla_extra_config.ironic_dnsmasq | default }}"
+      kolla_extra_kafka: "{{ kolla_extra_config.kafka | default }}"
       kolla_extra_magnum: "{{ kolla_extra_config.magnum | default }}"
       kolla_extra_murano: "{{ kolla_extra_config.murano | default }}"
       kolla_extra_neutron: "{{ kolla_extra_config.neutron | default }}"
diff --git a/ansible/roles/kolla-ansible/templates/overcloud-components.j2 b/ansible/roles/kolla-ansible/templates/overcloud-components.j2
index baded2d1defbb127dbd3ca01418e8c6eda46519a..62c0ab849fa304bc68bb75b511e5e807aef98a60 100644
--- a/ansible/roles/kolla-ansible/templates/overcloud-components.j2
+++ b/ansible/roles/kolla-ansible/templates/overcloud-components.j2
@@ -36,6 +36,9 @@ control
 [influxdb:children]
 monitoring
 
+[kafka:children]
+control
+
 [karbor:children]
 control
 
diff --git a/ansible/roles/kolla-ansible/tests/test-defaults.yml b/ansible/roles/kolla-ansible/tests/test-defaults.yml
index 4137bc60e281c1710b2a291a84d3d5c74b4959ab..ec439844ff906f960fd0df48b92f87fcc83303ea 100644
--- a/ansible/roles/kolla-ansible/tests/test-defaults.yml
+++ b/ansible/roles/kolla-ansible/tests/test-defaults.yml
@@ -116,6 +116,7 @@
               - neutron_tenant_network_types
               - enable_glance
               - enable_ironic
+              - enable_kafka
               - enable_neutron
               - enable_nova
               - enable_zookeeper
diff --git a/ansible/roles/kolla-ansible/tests/test-extras.yml b/ansible/roles/kolla-ansible/tests/test-extras.yml
index 712481cd54a755420e89e3ce050e18a3a3e44ba5..2a93f134c89087715f52ffed0888af11c6fd3f09 100644
--- a/ansible/roles/kolla-ansible/tests/test-extras.yml
+++ b/ansible/roles/kolla-ansible/tests/test-extras.yml
@@ -85,6 +85,7 @@
             kolla_enable_horizon: True
             kolla_enable_influxdb: True
             kolla_enable_ironic: True
+            kolla_enable_kafka: True
             kolla_enable_karbor: True
             kolla_enable_kibana: True
             kolla_enable_kuryr: True
@@ -219,6 +220,7 @@
               #enable_horizon: True
               #enable_influxdb: True
               #enable_ironic: True
+              #enable_kafka: True
               #enable_karbor: True
               #enable_kibana: True
               #enable_kuryr: True
diff --git a/ansible/roles/kolla-ansible/vars/main.yml b/ansible/roles/kolla-ansible/vars/main.yml
index cddaa4449270b8ede846e5cf2ede20e9771472d8..15888bdb3f916f31d0e6adc92de7b1cc89159adf 100644
--- a/ansible/roles/kolla-ansible/vars/main.yml
+++ b/ansible/roles/kolla-ansible/vars/main.yml
@@ -82,6 +82,7 @@ kolla_feature_flags:
   - horizon
   - influxdb
   - ironic
+  - kafka
   - karbor
   - kibana
   - kuryr
diff --git a/ansible/roles/kolla-openstack/defaults/main.yml b/ansible/roles/kolla-openstack/defaults/main.yml
index 003b14c608207a339af25c613456338806b7def2..cd0fcdcffc12124cc14010f78c15bfb75955563b 100644
--- a/ansible/roles/kolla-openstack/defaults/main.yml
+++ b/ansible/roles/kolla-openstack/defaults/main.yml
@@ -246,6 +246,15 @@ kolla_inspector_default_gateway:
 # Free form extra configuration to append to dnsmasq.conf.
 kolla_extra_ironic_dnsmasq:
 
+###############################################################################
+# Kafka configuration.
+
+# Whether to enable Kafka.
+kolla_enable_kafka:
+
+# Free form extra configuration to append to kafka.server.properties.
+kolla_extra_kafka:
+
 ###############################################################################
 # Magnum configuration.
 
diff --git a/ansible/roles/kolla-openstack/molecule/default/tests/test_default.py b/ansible/roles/kolla-openstack/molecule/default/tests/test_default.py
index c3ea79ef659b671c38d7962c3804d5911c0877a7..1b1bd0c7662a1e345d17449964f5d1a6522dd291 100644
--- a/ansible/roles/kolla-openstack/molecule/default/tests/test_default.py
+++ b/ansible/roles/kolla-openstack/molecule/default/tests/test_default.py
@@ -45,6 +45,7 @@ def test_service_config_directory(host, path):
      'heat',
      'horizon',
      'ironic',
+     'kafka',
      'magnum',
      'manila',
      'murano',
diff --git a/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml b/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml
index 50db855d3870b2f02c4b6794045e7006e5843bb1..83972ca342b83af3e3cfc0af076892287c9cad7d 100644
--- a/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml
+++ b/ansible/roles/kolla-openstack/molecule/enable-everything/molecule.yml
@@ -52,6 +52,10 @@ provisioner:
         kolla_inspector_ipa_ramdisk_path: ${MOLECULE_TEMP_PATH:-/tmp}/ironic-agent.initramfs
         kolla_extra_ironic_dnsmasq: |
           extra=bar
+        kolla_enable_kafka: True
+        kolla_extra_kafka: |
+          [extra-kafka.server.properties]
+          foo=bar
         kolla_enable_magnum: True
         kolla_extra_magnum: |
           [extra-magnum.conf]
diff --git a/ansible/roles/kolla-openstack/molecule/enable-everything/tests/test_default.py b/ansible/roles/kolla-openstack/molecule/enable-everything/tests/test_default.py
index 262e3d3617b2ece920f685597700e08d7956fb05..450247ddac11a0862402b923f68059a735bf8a67 100644
--- a/ansible/roles/kolla-openstack/molecule/enable-everything/tests/test_default.py
+++ b/ansible/roles/kolla-openstack/molecule/enable-everything/tests/test_default.py
@@ -37,6 +37,7 @@ testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
      'heat',
      'horizon',
      'ironic',
+     'kafka',
      'keystone',
      'magnum',
      'manila',
@@ -61,6 +62,7 @@ def test_service_config_directory(host, path):
      'heat.conf',
      'ironic.conf',
      'ironic-inspector.conf',
+     'kafka.server.properties',
      'magnum.conf',
      'neutron/ml2_conf.ini',
      'murano.conf',
diff --git a/ansible/roles/kolla-openstack/tasks/config.yml b/ansible/roles/kolla-openstack/tasks/config.yml
index 341f26e73796f2d0cc72d74bae21703a668f2189..c4c98a9a24247f278c496ddf66e9ea49ed45c446 100644
--- a/ansible/roles/kolla-openstack/tasks/config.yml
+++ b/ansible/roles/kolla-openstack/tasks/config.yml
@@ -22,6 +22,7 @@
     - { src: ironic.conf.j2, dest: ironic.conf, enabled: "{{ kolla_enable_ironic }}" }
     - { src: ironic-dnsmasq.conf.j2, dest: ironic/ironic-dnsmasq.conf, enabled: "{{ kolla_enable_ironic }}" }
     - { src: ironic-inspector.conf.j2, dest: ironic-inspector.conf, enabled: "{{ kolla_enable_ironic }}" }
+    - { src: kafka.server.properties.j2, dest: kafka.server.properties, enabled: "{{ kolla_enable_kafka }}" }
     - { src: magnum.conf.j2, dest: magnum.conf, enabled: "{{ kolla_enable_magnum }}" }
     - { src: ml2_conf.ini.j2, dest: neutron/ml2_conf.ini, enabled: "{{ kolla_enable_neutron }}" }
     - { src: murano.conf.j2, dest: murano.conf, enabled: "{{ kolla_enable_murano }}" }
diff --git a/ansible/roles/kolla-openstack/templates/kafka.server.properties.j2 b/ansible/roles/kolla-openstack/templates/kafka.server.properties.j2
new file mode 100644
index 0000000000000000000000000000000000000000..12d0dac24c85fb97ef6b34c61a9287fab2a978c9
--- /dev/null
+++ b/ansible/roles/kolla-openstack/templates/kafka.server.properties.j2
@@ -0,0 +1,9 @@
+# {{ ansible_managed }}
+
+{% if kolla_extra_kafka %}
+#######################
+# Extra configuration
+#######################
+
+{{ kolla_extra_kafka }}
+{% endif %}
diff --git a/ansible/roles/kolla-openstack/vars/main.yml b/ansible/roles/kolla-openstack/vars/main.yml
index cfd4f43bee657a001ce62dd3b74afc4d7801e95c..f6f9fe04bda67435acfac187531d13c4305af2ec 100644
--- a/ansible/roles/kolla-openstack/vars/main.yml
+++ b/ansible/roles/kolla-openstack/vars/main.yml
@@ -65,6 +65,11 @@ kolla_openstack_custom_config:
       - ironic-agent.kernel
       - ironic-dnsmasq.conf
       - pxelinux.default
+  # Kafka.
+  - src: "{{ kolla_extra_config_path }}/kafka"
+    dest: "{{ kolla_node_custom_config_path }}/kafka"
+    patterns: "*"
+    enabled: "{{ kolla_enable_kafka }}"
   # Keystone.
   - src: "{{ kolla_extra_config_path }}/keystone"
     dest: "{{ kolla_node_custom_config_path }}/keystone"