From c15dc20341bc7e9d26f63e677d0d45ef962301dc Mon Sep 17 00:00:00 2001
From: James Kirsch <generalfuzz@gmail.com>
Date: Mon, 16 Dec 2019 15:50:19 -0800
Subject: [PATCH] Configure services to use Certificate Authority

Include a reference to the globally configured Certificate Authority to
all services. Services use the CA to verify HTTPs connections.

Change-Id: I38da931cdd7ff46cce1994763b5c713652b096cc
Partially-Implements: blueprint support-trusted-ca-certificate-file
---
 ansible/roles/aodh/templates/aodh.conf.j2             |  2 ++
 ansible/roles/barbican/templates/barbican.conf.j2     |  1 +
 ansible/roles/blazar/templates/blazar.conf.j2         |  1 +
 ansible/roles/ceilometer/templates/ceilometer.conf.j2 |  1 +
 ansible/roles/cinder/templates/cinder.conf.j2         |  2 ++
 ansible/roles/cloudkitty/templates/cloudkitty.conf.j2 |  1 +
 ansible/roles/congress/templates/congress.conf.j2     |  1 +
 ansible/roles/cyborg/templates/cyborg.conf.j2         |  1 +
 ansible/roles/designate/templates/designate.conf.j2   |  1 +
 ansible/roles/freezer/templates/freezer.conf.j2       |  1 +
 ansible/roles/glance/templates/glance-api.conf.j2     |  1 +
 ansible/roles/glance/templates/glance-swift.conf.j2   |  1 +
 ansible/roles/gnocchi/templates/gnocchi.conf.j2       |  1 +
 ansible/roles/heat/tasks/bootstrap_service.yml        |  1 +
 ansible/roles/heat/templates/heat.conf.j2             |  1 +
 .../roles/ironic/templates/ironic-inspector.conf.j2   |  2 ++
 ansible/roles/ironic/templates/ironic.conf.j2         |  7 +++++++
 ansible/roles/karbor/templates/karbor.conf.j2         |  2 ++
 ansible/roles/kibana/templates/kibana.yml.j2          |  1 +
 ansible/roles/kuryr/templates/kuryr.conf.j2           |  1 +
 ansible/roles/magnum/templates/magnum.conf.j2         |  1 +
 ansible/roles/manila/templates/manila-share.conf.j2   |  3 +++
 ansible/roles/manila/templates/manila.conf.j2         |  1 +
 .../masakari/templates/masakari-monitors.conf.j2      |  1 +
 ansible/roles/masakari/templates/masakari.conf.j2     |  1 +
 ansible/roles/mistral/templates/mistral.conf.j2       |  1 +
 .../roles/monasca/templates/monasca-api/api.conf.j2   |  1 +
 .../monasca/templates/monasca-log-api/log-api.conf.j2 |  1 +
 ansible/roles/murano/templates/murano.conf.j2         |  7 +++++++
 ansible/roles/neutron/templates/neutron.conf.j2       |  4 ++++
 ansible/roles/nova-cell/templates/nova.conf.j2        |  7 +++++++
 .../roles/nova-hyperv/templates/nova_hyperv.conf.j2   |  3 +++
 ansible/roles/nova/templates/nova.conf.j2             | 11 +++++++----
 ansible/roles/octavia/templates/octavia.conf.j2       |  4 ++++
 ansible/roles/panko/templates/panko.conf.j2           |  1 +
 ansible/roles/placement/templates/placement.conf.j2   |  1 +
 ansible/roles/qinling/templates/qinling.conf.j2       |  1 +
 ansible/roles/sahara/templates/sahara.conf.j2         |  2 ++
 .../roles/searchlight/templates/searchlight.conf.j2   |  2 ++
 ansible/roles/senlin/templates/senlin.conf.j2         |  1 +
 ansible/roles/solum/templates/solum.conf.j2           |  1 +
 ansible/roles/swift/templates/proxy-server.conf.j2    |  1 +
 ansible/roles/tacker/templates/tacker.conf.j2         |  1 +
 ansible/roles/telegraf/templates/telegraf.conf.j2     |  1 +
 ansible/roles/tempest/templates/tempest.conf.j2       |  2 +-
 ansible/roles/trove/templates/trove.conf.j2           |  1 +
 ansible/roles/vitrage/templates/vitrage.conf.j2       |  2 ++
 ansible/roles/watcher/templates/watcher.conf.j2       |  2 ++
 ansible/roles/zun/templates/zun.conf.j2               |  2 ++
 ...figure-certificate-authority-aa21fa88234b021e.yaml |  5 +++++
 50 files changed, 97 insertions(+), 5 deletions(-)
 create mode 100644 releasenotes/notes/configure-certificate-authority-aa21fa88234b021e.yaml

diff --git a/ansible/roles/aodh/templates/aodh.conf.j2 b/ansible/roles/aodh/templates/aodh.conf.j2
index b424936048..d65e35d84f 100644
--- a/ansible/roles/aodh/templates/aodh.conf.j2
+++ b/ansible/roles/aodh/templates/aodh.conf.j2
@@ -25,6 +25,7 @@ username = {{ aodh_keystone_user }}
 password = {{ aodh_keystone_password }}
 auth_url = {{ keystone_admin_url }}
 auth_type = password
+cafile = {{ openstack_cacert | default(omit) }}
 
 [oslo_middleware]
 enable_proxy_headers_parsing = True
@@ -44,6 +45,7 @@ project_domain_id = {{ default_project_domain_id }}
 user_domain_id = {{ default_user_domain_id }}
 auth_type = password
 interface = internal
+cafile = {{ openstack_cacert | default(omit) }}
 
 [oslo_messaging_notifications]
 transport_url = {{ notify_transport_url }}
diff --git a/ansible/roles/barbican/templates/barbican.conf.j2 b/ansible/roles/barbican/templates/barbican.conf.j2
index c2d14a2bca..306f2eab9a 100644
--- a/ansible/roles/barbican/templates/barbican.conf.j2
+++ b/ansible/roles/barbican/templates/barbican.conf.j2
@@ -59,6 +59,7 @@ username = {{ barbican_keystone_user }}
 password = {{ barbican_keystone_password }}
 auth_url = {{ keystone_admin_url }}
 auth_type = password
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/blazar/templates/blazar.conf.j2 b/ansible/roles/blazar/templates/blazar.conf.j2
index 91d1e46c01..d6c6dcccd3 100644
--- a/ansible/roles/blazar/templates/blazar.conf.j2
+++ b/ansible/roles/blazar/templates/blazar.conf.j2
@@ -32,6 +32,7 @@ project_name = service
 username = {{ blazar_keystone_user }}
 password = {{ blazar_keystone_password }}
 service_token_roles_required = True
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/ceilometer/templates/ceilometer.conf.j2 b/ansible/roles/ceilometer/templates/ceilometer.conf.j2
index 412e01b0bf..58fd80301d 100644
--- a/ansible/roles/ceilometer/templates/ceilometer.conf.j2
+++ b/ansible/roles/ceilometer/templates/ceilometer.conf.j2
@@ -21,6 +21,7 @@ project_domain_id = {{ default_project_domain_id }}
 user_domain_id = {{ default_user_domain_id }}
 auth_type = password
 interface = internal
+cafile = {{ openstack_cacert | default(omit) }}
 
 {% if nova_compute_virt_type == 'vmware' %}
 [vmware]
diff --git a/ansible/roles/cinder/templates/cinder.conf.j2 b/ansible/roles/cinder/templates/cinder.conf.j2
index 410d63312b..751ec806d6 100644
--- a/ansible/roles/cinder/templates/cinder.conf.j2
+++ b/ansible/roles/cinder/templates/cinder.conf.j2
@@ -86,6 +86,7 @@ region_name = {{ openstack_region_name }}
 project_name = service
 username = {{ nova_keystone_user }}
 password = {{ nova_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 [database]
 connection = mysql+pymysql://{{ cinder_database_user }}:{{ cinder_database_password }}@{{ cinder_database_address }}/{{ cinder_database_name }}
@@ -100,6 +101,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ cinder_keystone_user }}
 password = {{ cinder_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2 b/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2
index 8966606a06..1bfbde4c0c 100644
--- a/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2
+++ b/ansible/roles/cloudkitty/templates/cloudkitty.conf.j2
@@ -24,6 +24,7 @@ project_name = service
 username = {{ cloudkitty_keystone_user }}
 password = {{ cloudkitty_keystone_password }}
 region_name = {{ openstack_region_name }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/congress/templates/congress.conf.j2 b/ansible/roles/congress/templates/congress.conf.j2
index 8bf690796e..4d2f027668 100644
--- a/ansible/roles/congress/templates/congress.conf.j2
+++ b/ansible/roles/congress/templates/congress.conf.j2
@@ -37,6 +37,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ congress_keystone_user }}
 password = {{ congress_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/cyborg/templates/cyborg.conf.j2 b/ansible/roles/cyborg/templates/cyborg.conf.j2
index 7bf0a1b3cd..48fd9b56ae 100644
--- a/ansible/roles/cyborg/templates/cyborg.conf.j2
+++ b/ansible/roles/cyborg/templates/cyborg.conf.j2
@@ -25,6 +25,7 @@ username = {{ cyborg_keystone_user }}
 password = {{ cyborg_keystone_password }}
 auth_url = {{ admin_protocol }}://{{ kolla_internal_fqdn | put_address_in_context('url') }}:{{ keystone_admin_port }}
 auth_type = password
+cafile = {{ openstack_cacert | default(omit) }}
 
 {% if cyborg_policy_file is defined %}
 [oslo_policy]
diff --git a/ansible/roles/designate/templates/designate.conf.j2 b/ansible/roles/designate/templates/designate.conf.j2
index b1b67deece..617e2abd2e 100644
--- a/ansible/roles/designate/templates/designate.conf.j2
+++ b/ansible/roles/designate/templates/designate.conf.j2
@@ -29,6 +29,7 @@ username = {{ designate_keystone_user }}
 password = {{ designate_keystone_password }}
 http_connect_timeout = 60
 service_token_roles_required = True
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/freezer/templates/freezer.conf.j2 b/ansible/roles/freezer/templates/freezer.conf.j2
index e31e48c737..0716d8020d 100644
--- a/ansible/roles/freezer/templates/freezer.conf.j2
+++ b/ansible/roles/freezer/templates/freezer.conf.j2
@@ -30,6 +30,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ freezer_keystone_user }}
 password = {{ freezer_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/glance/templates/glance-api.conf.j2 b/ansible/roles/glance/templates/glance-api.conf.j2
index a7f68d0198..ba7ea07178 100644
--- a/ansible/roles/glance/templates/glance-api.conf.j2
+++ b/ansible/roles/glance/templates/glance-api.conf.j2
@@ -35,6 +35,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ glance_keystone_user }}
 password = {{ glance_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/glance/templates/glance-swift.conf.j2 b/ansible/roles/glance/templates/glance-swift.conf.j2
index 9cec0ab69e..ee836fe00a 100644
--- a/ansible/roles/glance/templates/glance-swift.conf.j2
+++ b/ansible/roles/glance/templates/glance-swift.conf.j2
@@ -5,3 +5,4 @@ user = service:{{ glance_keystone_user }}
 key = {{ glance_keystone_password }}
 project_domain_id = default
 user_domain_id = default
+cafile = {{ openstack_cacert | default(omit) }}
diff --git a/ansible/roles/gnocchi/templates/gnocchi.conf.j2 b/ansible/roles/gnocchi/templates/gnocchi.conf.j2
index 7a952fe334..76906f8de1 100644
--- a/ansible/roles/gnocchi/templates/gnocchi.conf.j2
+++ b/ansible/roles/gnocchi/templates/gnocchi.conf.j2
@@ -50,6 +50,7 @@ username = {{ gnocchi_keystone_user }}
 password = {{ gnocchi_keystone_password }}
 auth_url = {{ keystone_admin_url }}
 auth_type = password
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/heat/tasks/bootstrap_service.yml b/ansible/roles/heat/tasks/bootstrap_service.yml
index 8f6a757380..849d218bbb 100644
--- a/ansible/roles/heat/tasks/bootstrap_service.yml
+++ b/ansible/roles/heat/tasks/bootstrap_service.yml
@@ -17,6 +17,7 @@
       OS_PASSWORD: "{{ openstack_auth.password }}"
       OS_PROJECT_NAME: "{{ openstack_auth.project_name }}"
       OS_REGION_NAME: "{{ openstack_region_name }}"
+      OS_CACERT: "{{ openstack_cacert | default(omit) }}"
       HEAT_DOMAIN_ADMIN_PASSWORD: "{{ heat_domain_admin_password }}"
     image: "{{ heat_api.image }}"
     labels:
diff --git a/ansible/roles/heat/templates/heat.conf.j2 b/ansible/roles/heat/templates/heat.conf.j2
index 014d6529b6..5c58f0dc47 100644
--- a/ansible/roles/heat/templates/heat.conf.j2
+++ b/ansible/roles/heat/templates/heat.conf.j2
@@ -49,6 +49,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ heat_keystone_user }}
 password = {{ heat_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/ironic/templates/ironic-inspector.conf.j2 b/ansible/roles/ironic/templates/ironic-inspector.conf.j2
index 54b68eab5d..fb11fab366 100644
--- a/ansible/roles/ironic/templates/ironic-inspector.conf.j2
+++ b/ansible/roles/ironic/templates/ironic-inspector.conf.j2
@@ -22,6 +22,7 @@ project_name = service
 username = {{ ironic_inspector_keystone_user }}
 password = {{ ironic_inspector_keystone_password }}
 os_endpoint_type = internalURL
+cafile = {{ openstack_cacert | default(omit) }}
 {% else %}
 auth_type = none
 endpoint_override = {{ ironic_internal_endpoint }}
@@ -37,6 +38,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ ironic_inspector_keystone_user }}
 password = {{ ironic_inspector_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/ironic/templates/ironic.conf.j2 b/ansible/roles/ironic/templates/ironic.conf.j2
index d22e1d0f7b..9b8f563472 100644
--- a/ansible/roles/ironic/templates/ironic.conf.j2
+++ b/ansible/roles/ironic/templates/ironic.conf.j2
@@ -63,6 +63,7 @@ username = {{ ironic_keystone_user }}
 password = {{ ironic_keystone_password }}
 region_name = {{ openstack_region_name }}
 valid_interfaces = internal
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
@@ -80,6 +81,7 @@ username = {{ ironic_keystone_user }}
 password = {{ ironic_keystone_password }}
 region_name = {{ openstack_region_name }}
 valid_interfaces = internal
+cafile = {{ openstack_cacert | default(omit) }}
 {% endif %}
 
 {% if enable_glance | bool %}
@@ -93,6 +95,7 @@ username = {{ ironic_keystone_user }}
 password = {{ ironic_keystone_password }}
 region_name = {{ openstack_region_name }}
 valid_interfaces = internal
+cafile = {{ openstack_cacert | default(omit) }}
 {% endif %}
 
 {% if enable_neutron | bool %}
@@ -107,6 +110,7 @@ password = {{ ironic_keystone_password }}
 region_name = {{ openstack_region_name }}
 valid_interfaces = internal
 cleaning_network = {{ ironic_cleaning_network }}
+cafile = {{ openstack_cacert | default(omit) }}
 {% endif %}
 
 {% if enable_nova | bool %}
@@ -120,6 +124,7 @@ username = {{ ironic_keystone_user }}
 password = {{ ironic_keystone_password }}
 region_name = {{ openstack_region_name }}
 valid_interfaces = internal
+cafile = {{ openstack_cacert | default(omit) }}
 {% endif %}
 
 [inspector]
@@ -133,6 +138,7 @@ username = {{ ironic_keystone_user }}
 password = {{ ironic_keystone_password }}
 region_name = {{ openstack_region_name }}
 valid_interfaces = internal
+cafile = {{ openstack_cacert | default(omit) }}
 {% else %}
 auth_type = none
 endpoint_override = {{ ironic_inspector_internal_endpoint }}
@@ -149,6 +155,7 @@ username = {{ ironic_keystone_user }}
 password = {{ ironic_keystone_password }}
 region_name = {{ openstack_region_name }}
 valid_interfaces = internal
+cafile = {{ openstack_cacert | default(omit) }}
 {% else %}
 auth_type = none
 endpoint_override = {{ internal_protocol }}://{{ ironic_internal_fqdn | put_address_in_context('url') }}:{{ ironic_api_port }}
diff --git a/ansible/roles/karbor/templates/karbor.conf.j2 b/ansible/roles/karbor/templates/karbor.conf.j2
index 4190e04bf8..e996f0e8b6 100644
--- a/ansible/roles/karbor/templates/karbor.conf.j2
+++ b/ansible/roles/karbor/templates/karbor.conf.j2
@@ -19,6 +19,7 @@ username = {{ karbor_keystone_user }}
 password = {{ karbor_keystone_password }}
 auth_url = {{ keystone_admin_url }}
 auth_type = password
+cafile = {{ openstack_cacert | default(omit) }}
 
 [clients_keystone]
 auth_uri = {{ keystone_internal_url }}
@@ -39,6 +40,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ karbor_keystone_user }}
 password = {{ karbor_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/kibana/templates/kibana.yml.j2 b/ansible/roles/kibana/templates/kibana.yml.j2
index 581dcafce0..9203d2a0ae 100644
--- a/ansible/roles/kibana/templates/kibana.yml.j2
+++ b/ansible/roles/kibana/templates/kibana.yml.j2
@@ -6,3 +6,4 @@ elasticsearch.url: "{{ internal_protocol }}://{{ kolla_internal_vip_address | pu
 elasticsearch.requestTimeout: {{ kibana_elasticsearch_request_timeout }}
 elasticsearch.shardTimeout: {{ kibana_elasticsearch_shard_timeout }}
 elasticsearch.ssl.verificationMode: "{{ 'full' if kibana_elasticsearch_ssl_verify | bool else 'none' }}"
+elasticsearch.ssl.certificateAuthorities: {{ openstack_cacert | default(omit) }}
diff --git a/ansible/roles/kuryr/templates/kuryr.conf.j2 b/ansible/roles/kuryr/templates/kuryr.conf.j2
index b41e5f41e9..30027a2e63 100644
--- a/ansible/roles/kuryr/templates/kuryr.conf.j2
+++ b/ansible/roles/kuryr/templates/kuryr.conf.j2
@@ -21,6 +21,7 @@ project_domain_id = {{ default_project_domain_id }}
 user_domain_id = {{ default_user_domain_id }}
 password = {{ kuryr_keystone_password }}
 username = {{ kuryr_keystone_user }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 {% if kuryr_policy_file is defined %}
 [oslo_policy]
diff --git a/ansible/roles/magnum/templates/magnum.conf.j2 b/ansible/roles/magnum/templates/magnum.conf.j2
index c7c5fcdad8..772421742e 100644
--- a/ansible/roles/magnum/templates/magnum.conf.j2
+++ b/ansible/roles/magnum/templates/magnum.conf.j2
@@ -65,6 +65,7 @@ user_domain_name = {{ default_user_domain_name }}
 project_name = service
 username = {{ magnum_keystone_user }}
 password = {{ magnum_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/manila/templates/manila-share.conf.j2 b/ansible/roles/manila/templates/manila-share.conf.j2
index db76ea42e8..9a837d5b99 100644
--- a/ansible/roles/manila/templates/manila-share.conf.j2
+++ b/ansible/roles/manila/templates/manila-share.conf.j2
@@ -16,6 +16,7 @@ endpoint_type = internalURL
 project_name = service
 username = cinder
 password = {{ cinder_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
@@ -32,6 +33,7 @@ endpoint_type = internalURL
 project_name = service
 username = {{ nova_keystone_user }}
 password = {{ nova_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
@@ -49,6 +51,7 @@ endpoint_type = internalURL
 project_name = service
 username = {{ neutron_keystone_user }}
 password = {{ neutron_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/manila/templates/manila.conf.j2 b/ansible/roles/manila/templates/manila.conf.j2
index 7ee7f9a917..9598560325 100644
--- a/ansible/roles/manila/templates/manila.conf.j2
+++ b/ansible/roles/manila/templates/manila.conf.j2
@@ -37,6 +37,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ manila_keystone_user }}
 password = {{ manila_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/masakari/templates/masakari-monitors.conf.j2 b/ansible/roles/masakari/templates/masakari-monitors.conf.j2
index 142075894a..0a8a6b547e 100644
--- a/ansible/roles/masakari/templates/masakari-monitors.conf.j2
+++ b/ansible/roles/masakari/templates/masakari-monitors.conf.j2
@@ -10,6 +10,7 @@ project_name = service
 project_domain_id = {{ default_project_domain_id }}
 username = {{ masakari_keystone_user }}
 password = {{ masakari_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 [libvirt]
 connection_uri = "qemu+tcp://{{ migration_interface_address | put_address_in_context('url') }}/system"
diff --git a/ansible/roles/masakari/templates/masakari.conf.j2 b/ansible/roles/masakari/templates/masakari.conf.j2
index 4111eac980..eb4c512783 100644
--- a/ansible/roles/masakari/templates/masakari.conf.j2
+++ b/ansible/roles/masakari/templates/masakari.conf.j2
@@ -28,6 +28,7 @@ username = {{ masakari_keystone_user }}
 password = {{ masakari_keystone_password }}
 service_token_roles_required = True
 region_name = {{ openstack_region_name }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 {% if enable_memcached | bool %}
 memcache_security_strategy = ENCRYPT
diff --git a/ansible/roles/mistral/templates/mistral.conf.j2 b/ansible/roles/mistral/templates/mistral.conf.j2
index b612cc57ff..1c758543d3 100644
--- a/ansible/roles/mistral/templates/mistral.conf.j2
+++ b/ansible/roles/mistral/templates/mistral.conf.j2
@@ -45,6 +45,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ mistral_keystone_user }}
 password = {{ mistral_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/monasca/templates/monasca-api/api.conf.j2 b/ansible/roles/monasca/templates/monasca-api/api.conf.j2
index dc1aa4ec71..30491645ab 100644
--- a/ansible/roles/monasca/templates/monasca-api/api.conf.j2
+++ b/ansible/roles/monasca/templates/monasca-api/api.conf.j2
@@ -36,6 +36,7 @@ project_name = service
 username = {{ monasca_keystone_user }}
 password = {{ monasca_keystone_password }}
 service_token_roles_required=True
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/monasca/templates/monasca-log-api/log-api.conf.j2 b/ansible/roles/monasca/templates/monasca-log-api/log-api.conf.j2
index 91e3ef6e6c..b303de5cbb 100644
--- a/ansible/roles/monasca/templates/monasca-log-api/log-api.conf.j2
+++ b/ansible/roles/monasca/templates/monasca-log-api/log-api.conf.j2
@@ -36,6 +36,7 @@ project_name = service
 username = {{ monasca_keystone_user }}
 password = {{ monasca_keystone_password }}
 service_token_roles_required=True
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/murano/templates/murano.conf.j2 b/ansible/roles/murano/templates/murano.conf.j2
index 5f4e3654ff..98831dc016 100644
--- a/ansible/roles/murano/templates/murano.conf.j2
+++ b/ansible/roles/murano/templates/murano.conf.j2
@@ -27,6 +27,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ murano_keystone_user }}
 password = {{ murano_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
@@ -41,6 +42,7 @@ user_domain_name = {{ default_user_domain_name }}
 project_name = service
 username = {{ murano_keystone_user }}
 password = {{ murano_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 [murano]
 url = {{ internal_protocol }}://{{ kolla_internal_fqdn | put_address_in_context('url') }}:{{ murano_api_port }}
@@ -78,17 +80,22 @@ auth_url = {{ keystone_internal_url }}/v3
 username = {{ murano_keystone_user }}
 password = {{ murano_keystone_password }}
 user_domain_name = {{ default_project_domain_name }}
+cafile = {{ openstack_cacert | default(omit) }}
 {% endif %}
 {% endif %}
 
 [neutron]
 endpoint_type = internalURL
+cafile = {{ openstack_cacert | default(omit) }}
 
 [heat]
 endpoint_type = internalURL
+cafile = {{ openstack_cacert | default(omit) }}
 
 [glance]
 endpoint_type = internalURL
+cafile = {{ openstack_cacert | default(omit) }}
 
 [mistral]
 endpoint_type = internalURL
+cafile = {{ openstack_cacert | default(omit) }}
diff --git a/ansible/roles/neutron/templates/neutron.conf.j2 b/ansible/roles/neutron/templates/neutron.conf.j2
index 1990e967f7..03a02132f1 100644
--- a/ansible/roles/neutron/templates/neutron.conf.j2
+++ b/ansible/roles/neutron/templates/neutron.conf.j2
@@ -84,6 +84,7 @@ project_name = service
 username = {{ nova_keystone_user }}
 password = {{ nova_keystone_password }}
 endpoint_type = internal
+cafile = {{ openstack_cacert | default(omit) }}
 
 [oslo_middleware]
 enable_proxy_headers_parsing = True
@@ -107,6 +108,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ neutron_keystone_user }}
 password = {{ neutron_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
@@ -149,6 +151,7 @@ password = {{ designate_keystone_password }}
 allow_reverse_dns_lookup = True
 ipv4_ptr_zone_prefix_size = 24
 ipv6_ptr_zone_prefix_size = 116
+cafile = {{ openstack_cacert | default(omit) }}
 {% endif %}
 
 {% if enable_osprofiler | bool %}
@@ -169,6 +172,7 @@ project_name = service
 project_domain_name = {{ default_project_domain_name }}
 os_region_name = {{ openstack_region_name }}
 os_interface = internal
+cafile = {{ openstack_cacert | default(omit) }}
 
 [privsep]
 helper_command=sudo neutron-rootwrap /etc/neutron/rootwrap.conf privsep-helper
diff --git a/ansible/roles/nova-cell/templates/nova.conf.j2 b/ansible/roles/nova-cell/templates/nova.conf.j2
index ea9e543204..f39c95ef61 100644
--- a/ansible/roles/nova-cell/templates/nova.conf.j2
+++ b/ansible/roles/nova-cell/templates/nova.conf.j2
@@ -90,6 +90,7 @@ proxyclient_address = {{ api_interface_address }}
 username = {{ ironic_keystone_user }}
 password = {{ ironic_keystone_password }}
 auth_url = {{ openstack_auth.auth_url }}/v3
+cafile = {{ openstack_cacert | default(omit) }}
 auth_type = password
 project_name = service
 user_domain_name = {{ default_user_domain_name }}
@@ -103,12 +104,14 @@ lock_path = /var/lib/nova/tmp
 
 [glance]
 api_servers = {{ internal_protocol }}://{{ glance_internal_fqdn | put_address_in_context('url') }}:{{ glance_api_port }}
+cafile = {{ openstack_cacert | default(omit) }}
 num_retries = 3
 
 {% if enable_cinder | bool %}
 [cinder]
 catalog_info = volumev3:cinderv3:internalURL
 os_region_name = {{ openstack_region_name }}
+cafile = {{ openstack_cacert | default(omit) }}
 {% endif %}
 
 [neutron]
@@ -119,6 +122,7 @@ ovs_bridge = {{ ovs_bridge }}
 {% endif %}
 auth_url = {{ keystone_admin_url }}
 auth_type = password
+cafile = {{ openstack_cacert | default(omit) }}
 project_domain_name = {{ default_project_domain_name }}
 user_domain_id = {{ default_user_domain_id }}
 project_name = service
@@ -184,6 +188,7 @@ helper_command=sudo nova-rootwrap /etc/nova/rootwrap.conf privsep-helper --confi
 
 [glance]
 debug = {{ nova_logging_debug }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 [guestfs]
 debug = {{ nova_logging_debug }}
@@ -197,6 +202,7 @@ user_domain_name = {{ default_user_domain_name }}
 project_name = service
 project_domain_name = {{ default_project_domain_name }}
 region_name = {{ openstack_region_name }}
+cafile = {{ openstack_cacert | default(omit) }}
 valid_interfaces = internal
 
 [notifications]
@@ -221,6 +227,7 @@ connection_string = {{ osprofiler_backend_connection_string }}
 {% if enable_barbican | bool %}
 [barbican]
 auth_endpoint = {{ keystone_internal_url }}
+cafile = {{ openstack_cacert | default(omit) }}
 {% endif %}
 
 {% if nova_compute_virt_type == "xenapi" %}
diff --git a/ansible/roles/nova-hyperv/templates/nova_hyperv.conf.j2 b/ansible/roles/nova-hyperv/templates/nova_hyperv.conf.j2
index 7ff452799e..7a2dc9f51a 100644
--- a/ansible/roles/nova-hyperv/templates/nova_hyperv.conf.j2
+++ b/ansible/roles/nova-hyperv/templates/nova_hyperv.conf.j2
@@ -29,9 +29,11 @@ password = {{ placement_keystone_password }}
 project_domain_name = {{ default_project_domain_name }}
 user_domain_name = {{ default_user_domain_name }}
 os_region_name = {{ openstack_region_name }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 [glance]
 api_servers = {{ internal_protocol }}://{{ glance_internal_fqdn | put_address_in_context('url') }}:{{ glance_api_port }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 
 [hyperv]
@@ -57,6 +59,7 @@ username = {{ neutron_keystone_user }}
 password = {{ neutron_keystone_password }}
 auth_url = {{ keystone_admin_url }}/v3
 auth_type = v3password
+cafile = {{ openstack_cacert | default(omit) }}
 
 [oslo_messaging_notifications]
 transport_url = {{ notify_transport_url }}
diff --git a/ansible/roles/nova/templates/nova.conf.j2 b/ansible/roles/nova/templates/nova.conf.j2
index e9c1b73250..d3e21781c7 100644
--- a/ansible/roles/nova/templates/nova.conf.j2
+++ b/ansible/roles/nova/templates/nova.conf.j2
@@ -59,8 +59,9 @@ lock_path = /var/lib/nova/tmp
 
 [glance]
 api_servers = {{ internal_protocol }}://{{ glance_internal_fqdn | put_address_in_context('url') }}:{{ glance_api_port }}
-
+cafile = {{ openstack_cacert | default(omit) }}
 num_retries = {{ groups['glance-api'] | length }}
+debug = {{ nova_logging_debug }}
 
 {% if enable_cinder | bool %}
 [cinder]
@@ -73,6 +74,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ cinder_keystone_user }}
 password = {{ cinder_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 {% endif %}
 
 [neutron]
@@ -90,6 +92,7 @@ username = {{ neutron_keystone_user }}
 password = {{ neutron_keystone_password }}
 region_name = {{ openstack_region_name }}
 valid_interfaces = internal
+cafile = {{ openstack_cacert | default(omit) }}
 
 [database]
 connection = mysql+pymysql://{{ nova_cell0_database_user }}:{{ nova_cell0_database_password }}@{{ nova_cell0_database_address }}/{{ nova_cell0_database_name }}
@@ -116,6 +119,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ nova_keystone_user }}
 password = {{ nova_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
@@ -141,9 +145,6 @@ policy_file = {{ nova_policy_file }}
 [privsep_entrypoint]
 helper_command=sudo nova-rootwrap /etc/nova/rootwrap.conf privsep-helper --config-file /etc/nova/nova.conf
 
-[glance]
-debug = {{ nova_logging_debug }}
-
 [guestfs]
 debug = {{ nova_logging_debug }}
 
@@ -169,6 +170,7 @@ user_domain_name = {{ default_user_domain_name }}
 project_name = service
 project_domain_name = {{ default_project_domain_name }}
 region_name = {{ openstack_region_name }}
+cafile = {{ openstack_cacert | default(omit) }}
 valid_interfaces = internal
 
 [notifications]
@@ -193,4 +195,5 @@ connection_string = {{ osprofiler_backend_connection_string }}
 {% if enable_barbican | bool %}
 [barbican]
 auth_endpoint = {{ keystone_internal_url }}
+cafile = {{ openstack_cacert | default(omit) }}
 {% endif %}
diff --git a/ansible/roles/octavia/templates/octavia.conf.j2 b/ansible/roles/octavia/templates/octavia.conf.j2
index 0072e0527a..48bb231eb9 100644
--- a/ansible/roles/octavia/templates/octavia.conf.j2
+++ b/ansible/roles/octavia/templates/octavia.conf.j2
@@ -44,6 +44,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ octavia_keystone_user }}
 password = {{ octavia_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
@@ -83,11 +84,14 @@ policy_file = {{ octavia_policy_file }}
 [glance]
 region_name = {{ openstack_region_name }}
 endpoint_type = internal
+ca_certificates_file ==  {{ openstack_cacert | default(omit) }}
 
 [neutron]
 region_name = {{ openstack_region_name }}
 endpoint_type = internal
+ca_certificates_file ==  {{ openstack_cacert | default(omit) }}
 
 [nova]
 region_name = {{ openstack_region_name }}
 endpoint_type = internal
+ca_certificates_file ==  {{ openstack_cacert | default(omit) }}
diff --git a/ansible/roles/panko/templates/panko.conf.j2 b/ansible/roles/panko/templates/panko.conf.j2
index eb1a83ae23..29544fba49 100644
--- a/ansible/roles/panko/templates/panko.conf.j2
+++ b/ansible/roles/panko/templates/panko.conf.j2
@@ -25,6 +25,7 @@ username = {{ panko_keystone_user }}
 password = {{ panko_keystone_password }}
 auth_url = {{ keystone_admin_url }}
 auth_type = password
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/placement/templates/placement.conf.j2 b/ansible/roles/placement/templates/placement.conf.j2
index a3fa5fad5f..300329c09a 100644
--- a/ansible/roles/placement/templates/placement.conf.j2
+++ b/ansible/roles/placement/templates/placement.conf.j2
@@ -42,6 +42,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ placement_keystone_user }}
 password = {{ placement_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/qinling/templates/qinling.conf.j2 b/ansible/roles/qinling/templates/qinling.conf.j2
index 03a1ee5f5e..f22917bc93 100644
--- a/ansible/roles/qinling/templates/qinling.conf.j2
+++ b/ansible/roles/qinling/templates/qinling.conf.j2
@@ -28,6 +28,7 @@ project_name = service
 username = {{ qinling_keystone_user }}
 password = {{ qinling_keystone_password }}
 region_name = {{ openstack_region_name }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/sahara/templates/sahara.conf.j2 b/ansible/roles/sahara/templates/sahara.conf.j2
index c2b6036d53..5f1baa8144 100644
--- a/ansible/roles/sahara/templates/sahara.conf.j2
+++ b/ansible/roles/sahara/templates/sahara.conf.j2
@@ -21,6 +21,7 @@ project_name = service
 project_domain_name = {{ default_project_domain_name }}
 username = {{ sahara_keystone_user }}
 password = {{ sahara_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
@@ -51,3 +52,4 @@ user_domain_name = {{ default_user_domain_name }}
 username = {{ sahara_keystone_user }}
 password = {{ sahara_keystone_password }}
 auth_url = {{ keystone_admin_url }}/v3
+cafile = {{ openstack_cacert | default(omit) }}
diff --git a/ansible/roles/searchlight/templates/searchlight.conf.j2 b/ansible/roles/searchlight/templates/searchlight.conf.j2
index a8f11b766c..4a22f8a3e1 100644
--- a/ansible/roles/searchlight/templates/searchlight.conf.j2
+++ b/ansible/roles/searchlight/templates/searchlight.conf.j2
@@ -29,6 +29,7 @@ user_domain_name = {{ default_user_domain_name }}
 username = {{ searchlight_keystone_user }}
 password = {{ searchlight_keystone_password }}
 auth_type = password
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
@@ -60,6 +61,7 @@ username = {{ searchlight_keystone_user }}
 password = {{ searchlight_keystone_password }}
 auth_type = password
 auth_plugin = password
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/senlin/templates/senlin.conf.j2 b/ansible/roles/senlin/templates/senlin.conf.j2
index fbe31a72ac..a3c689c34b 100644
--- a/ansible/roles/senlin/templates/senlin.conf.j2
+++ b/ansible/roles/senlin/templates/senlin.conf.j2
@@ -49,6 +49,7 @@ project_name = service
 username = {{ senlin_keystone_user }}
 password = {{ senlin_keystone_password }}
 service_token_roles_required = False
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/solum/templates/solum.conf.j2 b/ansible/roles/solum/templates/solum.conf.j2
index 12083a76a8..71f7373ad9 100644
--- a/ansible/roles/solum/templates/solum.conf.j2
+++ b/ansible/roles/solum/templates/solum.conf.j2
@@ -51,6 +51,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ solum_keystone_user }}
 password = {{ solum_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/swift/templates/proxy-server.conf.j2 b/ansible/roles/swift/templates/proxy-server.conf.j2
index 958b4bf535..e7b2c42f2b 100644
--- a/ansible/roles/swift/templates/proxy-server.conf.j2
+++ b/ansible/roles/swift/templates/proxy-server.conf.j2
@@ -44,6 +44,7 @@ project_name = service
 username = {{ swift_keystone_user }}
 password = {{ swift_keystone_password }}
 delay_auth_decision = {{ swift_delay_auth_decision }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/tacker/templates/tacker.conf.j2 b/ansible/roles/tacker/templates/tacker.conf.j2
index 8e0fa2910c..4267564817 100644
--- a/ansible/roles/tacker/templates/tacker.conf.j2
+++ b/ansible/roles/tacker/templates/tacker.conf.j2
@@ -38,6 +38,7 @@ user_domain_name = {{ default_user_domain_id }}
 project_name = service
 username = {{ tacker_keystone_user }}
 password = {{ tacker_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/telegraf/templates/telegraf.conf.j2 b/ansible/roles/telegraf/templates/telegraf.conf.j2
index 2dceae53e7..c61b4682ea 100644
--- a/ansible/roles/telegraf/templates/telegraf.conf.j2
+++ b/ansible/roles/telegraf/templates/telegraf.conf.j2
@@ -19,6 +19,7 @@
   retention_policy = "autogen"
   write_consistency = "any"
   timeout = "5s"
+  tls_ca = {{ openstack_cacert | default(omit) }}
 {% endfor %}
 {% endif %}
 [[inputs.cpu]]
diff --git a/ansible/roles/tempest/templates/tempest.conf.j2 b/ansible/roles/tempest/templates/tempest.conf.j2
index ed0aa87215..90d7f691bd 100644
--- a/ansible/roles/tempest/templates/tempest.conf.j2
+++ b/ansible/roles/tempest/templates/tempest.conf.j2
@@ -10,7 +10,6 @@ admin_password = {{ keystone_admin_password }}
 admin_project_name = {{ openstack_auth.project_name }}
 admin_domain_name = {{ openstack_auth.domain_name }}
 
-
 [dashboard]
 dashboard_url = {{ internal_protocol }}://{{ kolla_internal_fqdn }}
 login_url = {{ internal_protocol }}://{{ kolla_internal_fqdn }}/auth/login/
@@ -42,6 +41,7 @@ region = {{ openstack_region_name }}
 auth_version = v3
 uri = {{ keystone_admin_url }}/v2.0
 uri_v3 = {{ keystone_admin_url }}/v3
+ca_certificates_file = {{ openstack_cacert | default(omit) }}
 
 [image]
 region = {{ openstack_region_name }}
diff --git a/ansible/roles/trove/templates/trove.conf.j2 b/ansible/roles/trove/templates/trove.conf.j2
index 0c18d5e3e5..ef2fbe60a3 100644
--- a/ansible/roles/trove/templates/trove.conf.j2
+++ b/ansible/roles/trove/templates/trove.conf.j2
@@ -39,6 +39,7 @@ username = {{ trove_keystone_user }}
 password = {{ trove_keystone_password }}
 auth_url = {{ keystone_admin_url }}
 auth_type = password
+cafile = {{ openstack_cacert | default(omit) }}
 
 [oslo_messaging_notifications]
 transport_url = {{ notify_transport_url }}
diff --git a/ansible/roles/vitrage/templates/vitrage.conf.j2 b/ansible/roles/vitrage/templates/vitrage.conf.j2
index 260a986c54..07c41707a6 100644
--- a/ansible/roles/vitrage/templates/vitrage.conf.j2
+++ b/ansible/roles/vitrage/templates/vitrage.conf.j2
@@ -39,6 +39,7 @@ project_name = service
 username = {{ vitrage_keystone_user }}
 password = {{ vitrage_keystone_password }}
 service_token_roles_required = True
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
@@ -54,6 +55,7 @@ project_name = admin
 password = {{ vitrage_keystone_password }}
 username = {{ vitrage_keystone_user }}
 interface = internal
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
diff --git a/ansible/roles/watcher/templates/watcher.conf.j2 b/ansible/roles/watcher/templates/watcher.conf.j2
index a73cae7e87..ed3ec2c68a 100644
--- a/ansible/roles/watcher/templates/watcher.conf.j2
+++ b/ansible/roles/watcher/templates/watcher.conf.j2
@@ -26,6 +26,7 @@ project_name = service
 username = {{ watcher_keystone_user }}
 password = {{ watcher_keystone_password }}
 service_token_roles_required = True
+cafile = {{ openstack_cacert | default(omit) }}
 
 memcache_security_strategy = ENCRYPT
 memcache_secret_key = {{ memcache_secret_key }}
@@ -40,6 +41,7 @@ user_domain_id = {{ default_user_domain_id }}
 project_name = service
 username = {{ watcher_keystone_user }}
 password = {{ watcher_keystone_password }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 [oslo_concurrency]
 lock_path = /var/lib/watcher/tmp
diff --git a/ansible/roles/zun/templates/zun.conf.j2 b/ansible/roles/zun/templates/zun.conf.j2
index 3e41e9b717..bb8c0698b4 100644
--- a/ansible/roles/zun/templates/zun.conf.j2
+++ b/ansible/roles/zun/templates/zun.conf.j2
@@ -38,6 +38,7 @@ username = {{ zun_keystone_user }}
 password = {{ zun_keystone_password }}
 service_token_roles_required = True
 region_name = {{ openstack_region_name }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 {% if enable_memcached | bool %}
 memcache_security_strategy = ENCRYPT
@@ -59,6 +60,7 @@ username = {{ zun_keystone_user }}
 password = {{ zun_keystone_password }}
 service_token_roles_required = True
 region_name = {{ openstack_region_name }}
+cafile = {{ openstack_cacert | default(omit) }}
 
 {% if enable_memcached | bool %}
 memcache_security_strategy = ENCRYPT
diff --git a/releasenotes/notes/configure-certificate-authority-aa21fa88234b021e.yaml b/releasenotes/notes/configure-certificate-authority-aa21fa88234b021e.yaml
new file mode 100644
index 0000000000..583d34fbc5
--- /dev/null
+++ b/releasenotes/notes/configure-certificate-authority-aa21fa88234b021e.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - Configure all openstack services to use the globally defined Certificate
+    Authority to verify HTTPs connections. The global CA is configured by the
+    'openstack_cacert' parameter.