diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml
index 5f3cd1f88b..896eb9de13 100644
--- a/ansible/group_vars/all.yml
+++ b/ansible/group_vars/all.yml
@@ -356,6 +356,7 @@ enable_neutron_bgp_dragent: "no"
 enable_nova_serialconsole_proxy: "no"
 enable_octavia: "no"
 enable_openvswitch: "{{ neutron_plugin_agent != 'linuxbridge' | bool }}"
+enable_osprofiler: "no"
 enable_panko: "no"
 enable_rally: "no"
 enable_sahara: "no"
@@ -393,7 +394,7 @@ enable_destroy_images: "no"
 elasticsearch_address: "{{ kolla_internal_vip_address }}"
 elasticsearch_protocol: "{{ internal_protocol }}"
 
-enable_elasticsearch: "{{ 'yes' if enable_central_logging | bool or enable_freezer | bool else 'no' }}"
+enable_elasticsearch: "{{ 'yes' if enable_central_logging | bool or enable_freezer | bool or enable_osprofiler | bool else 'no' }}"
 enable_kibana: "{{ 'yes' if enable_central_logging | bool else 'no' }}"
 
 ####################
diff --git a/ansible/roles/cinder/templates/cinder.conf.j2 b/ansible/roles/cinder/templates/cinder.conf.j2
index 462e3307ed..038ea4c733 100644
--- a/ansible/roles/cinder/templates/cinder.conf.j2
+++ b/ansible/roles/cinder/templates/cinder.conf.j2
@@ -152,3 +152,13 @@ hnas_svc0_hdp = {{ hnas_nfs_svc0_hdp }}
 
 [privsep_entrypoint]
 helper_command=sudo cinder-rootwrap /etc/cinder/rootwrap.conf privsep-helper --config-file /etc/cinder/cinder.conf
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/glance/templates/glance-api.conf.j2 b/ansible/roles/glance/templates/glance-api.conf.j2
index b56c18b47b..bbeab9b0f8 100644
--- a/ansible/roles/glance/templates/glance-api.conf.j2
+++ b/ansible/roles/glance/templates/glance-api.conf.j2
@@ -91,3 +91,13 @@ driver = messagingv2
 {% else %}
 driver = noop
 {% endif %}
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/glance/templates/glance-registry.conf.j2 b/ansible/roles/glance/templates/glance-registry.conf.j2
index b26551f10b..4c837e25d8 100644
--- a/ansible/roles/glance/templates/glance-registry.conf.j2
+++ b/ansible/roles/glance/templates/glance-registry.conf.j2
@@ -50,3 +50,13 @@ driver = messagingv2
 {% else %}
 driver = noop
 {% endif %}
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/heat/templates/heat.conf.j2 b/ansible/roles/heat/templates/heat.conf.j2
index 277e9d5122..974551bbe7 100644
--- a/ansible/roles/heat/templates/heat.conf.j2
+++ b/ansible/roles/heat/templates/heat.conf.j2
@@ -106,3 +106,13 @@ endpoint_type = publicURL
 [oslo_middleware]
 enable_proxy_headers_parsing = True
 {% endif %}
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/keystone/templates/keystone.conf.j2 b/ansible/roles/keystone/templates/keystone.conf.j2
index 4b39d955f7..43aa002559 100644
--- a/ansible/roles/keystone/templates/keystone.conf.j2
+++ b/ansible/roles/keystone/templates/keystone.conf.j2
@@ -53,3 +53,13 @@ memcache_servers = {% for host in groups['memcached'] %}{{ hostvars[host]['ansib
 [oslo_messaging_notifications]
 driver = messagingv2
 {% endif %}
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/magnum/templates/magnum.conf.j2 b/ansible/roles/magnum/templates/magnum.conf.j2
index 32d8c53ed6..1ff521aaaf 100644
--- a/ansible/roles/magnum/templates/magnum.conf.j2
+++ b/ansible/roles/magnum/templates/magnum.conf.j2
@@ -76,3 +76,13 @@ topics = 'notifications'
 {% else %}
 driver = noop
 {% endif %}
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/mistral/templates/mistral.conf.j2 b/ansible/roles/mistral/templates/mistral.conf.j2
index 812efdd390..bb66b8c7bb 100644
--- a/ansible/roles/mistral/templates/mistral.conf.j2
+++ b/ansible/roles/mistral/templates/mistral.conf.j2
@@ -40,3 +40,13 @@ url = {{ internal_protocol }}://{{ kolla_internal_fqdn }}:{{ mistral_api_port }}
 
 [oslo_messaging_notifications]
 driver = noop
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/neutron/templates/neutron.conf.j2 b/ansible/roles/neutron/templates/neutron.conf.j2
index 223f1c44a9..e16c166eab 100644
--- a/ansible/roles/neutron/templates/neutron.conf.j2
+++ b/ansible/roles/neutron/templates/neutron.conf.j2
@@ -130,3 +130,13 @@ allow_reverse_dns_lookup = True
 ipv4_ptr_zone_prefix_size = 24
 ipv6_ptr_zone_prefix_size = 116
 {% endif %}
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/nova/templates/nova.conf.j2 b/ansible/roles/nova/templates/nova.conf.j2
index f7d8a373f9..513a5110b0 100644
--- a/ansible/roles/nova/templates/nova.conf.j2
+++ b/ansible/roles/nova/templates/nova.conf.j2
@@ -247,3 +247,13 @@ os_interface = internal
 {% if enable_ceilometer | bool or enable_searchlight | bool or enable_designate | bool %}
 notify_on_state_change = vm_and_task_state
 {% endif %}
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/searchlight/templates/searchlight.conf.j2 b/ansible/roles/searchlight/templates/searchlight.conf.j2
index e3eac130db..cf66c005df 100644
--- a/ansible/roles/searchlight/templates/searchlight.conf.j2
+++ b/ansible/roles/searchlight/templates/searchlight.conf.j2
@@ -102,3 +102,15 @@ enabled = {{ enable_neutron | bool }}
 
 [resource_plugin:os_neutron_security_group]
 enabled = {{ enable_neutron | bool }}
+
+{# TODO(blallau): enabling osprofiler when fixed in searchlight #}
+
+{# {% if enable_osprofiler | bool %} #}
+{# [profiler] #}
+{# enabled = true #}
+{# trace_sqlalchemy = true #}
+{# hmac_keys = {{ osprofiler_secret }} #}
+{# {% if enable_elasticsearch | bool %} #}
+{# connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }} #}
+{# {% endif %} #}
+{# {% endif %} #}
diff --git a/ansible/roles/senlin/templates/senlin.conf.j2 b/ansible/roles/senlin/templates/senlin.conf.j2
index 5d56dafdbf..a9f9d5b724 100644
--- a/ansible/roles/senlin/templates/senlin.conf.j2
+++ b/ansible/roles/senlin/templates/senlin.conf.j2
@@ -50,3 +50,13 @@ topics = 'notifications'
 {% else %}
 driver = noop
 {% endif %}
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/trove/templates/trove-conductor.conf.j2 b/ansible/roles/trove/templates/trove-conductor.conf.j2
index 2805f57bea..9e1da63116 100644
--- a/ansible/roles/trove/templates/trove-conductor.conf.j2
+++ b/ansible/roles/trove/templates/trove-conductor.conf.j2
@@ -11,3 +11,13 @@ transport_url = rabbit://{% for host in groups['rabbitmq'] %}{{ rabbitmq_user }}
 [database]
 connection = mysql+pymysql://{{ trove_database_user }}:{{ trove_database_password }}@{{ trove_database_address }}/{{ trove_database_name }}
 max_retries = -1
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/trove/templates/trove-taskmanager.conf.j2 b/ansible/roles/trove/templates/trove-taskmanager.conf.j2
index 339cdfc32c..3aef3112f8 100644
--- a/ansible/roles/trove/templates/trove-taskmanager.conf.j2
+++ b/ansible/roles/trove/templates/trove-taskmanager.conf.j2
@@ -32,3 +32,13 @@ topics = 'notifications'
 {% else %}
 driver = noop
 {% endif %}
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/trove/templates/trove.conf.j2 b/ansible/roles/trove/templates/trove.conf.j2
index 512fffd019..7280922045 100644
--- a/ansible/roles/trove/templates/trove.conf.j2
+++ b/ansible/roles/trove/templates/trove.conf.j2
@@ -43,3 +43,13 @@ topics = 'notifications'
 {% else %}
 driver = noop
 {% endif %}
+
+{% if enable_osprofiler | bool %}
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/ansible/roles/zun/templates/zun.conf.j2 b/ansible/roles/zun/templates/zun.conf.j2
index 2fb85acec7..5a662460a8 100644
--- a/ansible/roles/zun/templates/zun.conf.j2
+++ b/ansible/roles/zun/templates/zun.conf.j2
@@ -53,7 +53,6 @@ memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
 memcached_servers = {% for host in groups['memcached'] %}{{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ memcached_port }}{% if not loop.last %},{% endif %}{% endfor %}
 
-
 [glance_client]
 auth_uri = {{ internal_protocol }}://{{ kolla_internal_fqdn }}:{{ keystone_public_port }}
 auth_url = {{ admin_protocol }}://{{ kolla_internal_fqdn }}:{{ keystone_admin_port }}
@@ -66,3 +65,13 @@ password = {{ zun_keystone_password }}
 region_name = {{ openstack_region_name }}
 endpoint_type = internalURL
 api_version = 2
+{% if enable_osprofiler | bool %}
+
+[profiler]
+enabled = true
+trace_sqlalchemy = true
+hmac_keys = {{ osprofiler_secret }}
+{% if enable_elasticsearch | bool %}
+connection_string = elasticsearch://{{ elasticsearch_address }}:{{ elasticsearch_port }}
+{% endif %}
+{% endif %}
diff --git a/doc/index.rst b/doc/index.rst
index 5a99fdfccd..86f96684fb 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -71,6 +71,7 @@ Services
    networking-guide
    kuryr-guide
    zun-guide
+   osprofiler-guide
 
 Developer Docs
 ==============
diff --git a/doc/osprofiler-guide.rst b/doc/osprofiler-guide.rst
new file mode 100644
index 0000000000..65ad92acab
--- /dev/null
+++ b/doc/osprofiler-guide.rst
@@ -0,0 +1,55 @@
+.. _osprofiler-guide:
+
+===================
+OSprofiler in Kolla
+===================
+
+Overview
+========
+OSProfiler provides a tiny but powerful library that is used by most
+(soon to be all) OpenStack projects and their corresponding python clients
+as well as the Openstack client.
+It provides functionality to generate 1 trace per request, that goes
+through all involved services. This trace can then be extracted and used
+to build a tree of calls which can be quite handy for a variety of reasons
+(for example in isolating cross-project performance issues).
+
+Configuration on Kolla deployment
+---------------------------------
+
+Enable OSprofiler in ``/etc/kolla/globals.yml``
+
+.. code-block:: console
+
+    enable_osprofiler: "yes"
+    enable_elasticsearch: "yes"
+
+Verify operation
+----------------
+
+Retrieve ``osprofiler_secret`` key present at ``/etc/kolla/passwords.yml``.
+
+Profiler UUIDs can be created executing OpenStack clients (Nova, Glance, Cinder, Heat, Keystone)
+with ``--profile`` option or using the official Openstack client with ``--os-profile``.
+In example to get the OSprofiler trace UUID for ``openstack server create``.
+
+.. code-block:: console
+
+    $ openstack --os-profile <OSPROFILER_SECRET> \
+      server create \
+      --image cirros \
+      --flavor m1.tiny \
+      --key-name mykey \
+      --nic net-id=${NETWORK_ID} \
+      demo
+
+
+The previous command will output the command to retrieve OSprofiler trace.
+
+.. code-block:: console
+
+    $ osprofiler trace show --html <TRACE_ID> --connection-string elasticsearch://<api_interface_address>:9200
+
+For more information about how OSprofiler works, see
+`OSProfiler – Cross-project profiling library
+<https://docs.openstack.org/developer/osprofiler/>`__.
diff --git a/etc/kolla/globals.yml b/etc/kolla/globals.yml
index 04d8107e91..e699e8efd0 100644
--- a/etc/kolla/globals.yml
+++ b/etc/kolla/globals.yml
@@ -180,6 +180,7 @@ kolla_internal_vip_address: "10.10.10.254"
 #enable_nova_serialconsole_proxy: "no"
 #enable_octavia: "no"
 #enable_openvswitch: "{{ neutron_plugin_agent != 'linuxbridge' | bool }}"
+#enable_osprofiler: "no"
 #enable_panko: "no"
 #enable_rally: "no"
 #enable_sahara: "no"
diff --git a/etc/kolla/passwords.yml b/etc/kolla/passwords.yml
index 20850cb279..298ee70a1c 100644
--- a/etc/kolla/passwords.yml
+++ b/etc/kolla/passwords.yml
@@ -149,6 +149,9 @@ zun_keystone_password:
 
 memcache_secret_key:
 
+#HMAC secret key
+osprofiler_secret:
+
 nova_ssh_key:
   private_key:
   public_key:
diff --git a/kolla_ansible/cmd/genpwd.py b/kolla_ansible/cmd/genpwd.py
index 3d0c01ea0b..76b4e6dd9f 100755
--- a/kolla_ansible/cmd/genpwd.py
+++ b/kolla_ansible/cmd/genpwd.py
@@ -69,7 +69,8 @@ def main():
     blank_keys = ['docker_registry_password']
 
     # HMAC-MD5 keys
-    hmac_md5_keys = ['designate_rndc_key']
+    hmac_md5_keys = ['designate_rndc_key',
+                     'osprofiler_secret']
 
     # HMAC-SHA256 keys
     hmac_sha256_keys = ['barbican_crypto_key']
diff --git a/releasenotes/notes/osprofiler-support-ac1df8db57bf7789.yaml b/releasenotes/notes/osprofiler-support-ac1df8db57bf7789.yaml
new file mode 100644
index 0000000000..7defe0ef70
--- /dev/null
+++ b/releasenotes/notes/osprofiler-support-ac1df8db57bf7789.yaml
@@ -0,0 +1,4 @@
+---
+features:
+  - |
+    Osprofiler support has been implemented in OpenStack services