diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml
index faf84b18fa..1e59d9d4e6 100644
--- a/ansible/group_vars/all.yml
+++ b/ansible/group_vars/all.yml
@@ -501,6 +501,10 @@ nova_console: "novnc"
 # Valid options are [ public, internal, admin ]
 openstack_interface: "admin"
 
+# Openstack CA certificate bundle file
+# CA bundle file must be added to both the Horizon and Kolla Toolbox containers
+openstack_cacert: ""
+
 # Enable core OpenStack services. This includes:
 # glance, keystone, neutron, nova, heat, and horizon.
 enable_openstack_core: "yes"
diff --git a/ansible/roles/aodh/tasks/register.yml b/ansible/roles/aodh/tasks/register.yml
index ccab65f26f..4cc2bc1fb3 100644
--- a/ansible/roles/aodh/tasks/register.yml
+++ b/ansible/roles/aodh/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_aodh_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ aodh_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_aodh_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/barbican/tasks/register.yml b/ansible/roles/barbican/tasks/register.yml
index 6856bc4d35..75f0855d7e 100644
--- a/ansible/roles/barbican/tasks/register.yml
+++ b/ansible/roles/barbican/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_barbican_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ barbican_admin_endpoint }}'}
@@ -31,6 +32,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_barbican_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Creating default barbican roles
@@ -41,6 +43,7 @@
       name: "{{ item }}"
       auth: "{{ openstack_barbican_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - "{{ barbican_keymanager_role }}"
diff --git a/ansible/roles/blazar/tasks/bootstrap.yml b/ansible/roles/blazar/tasks/bootstrap.yml
index 5110a3e1df..b3dd1a3296 100644
--- a/ansible/roles/blazar/tasks/bootstrap.yml
+++ b/ansible/roles/blazar/tasks/bootstrap.yml
@@ -48,6 +48,7 @@
     --os-password {{ keystone_admin_password }}
     --os-user-domain-name default
     --os-region-name {{ openstack_region_name }}
+    {% if openstack_cacert != '' %}--os-cacert {{ openstack_cacert }}{% endif %}
     aggregate create {{ blazar_aggregate_pool_name }}
   register: blazar_host_aggregate
   changed_when: blazar_host_aggregate is success
diff --git a/ansible/roles/blazar/tasks/register.yml b/ansible/roles/blazar/tasks/register.yml
index 31aff54ded..73b2164984 100644
--- a/ansible/roles/blazar/tasks/register.yml
+++ b/ansible/roles/blazar/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_blazar_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ blazar_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_blazar_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/ceilometer/tasks/register.yml b/ansible/roles/ceilometer/tasks/register.yml
index 9ceacbace5..76ee2b0d7a 100644
--- a/ansible/roles/ceilometer/tasks/register.yml
+++ b/ansible/roles/ceilometer/tasks/register.yml
@@ -11,6 +11,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_ceilometer_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Associate the ResellerAdmin role and ceilometer user
@@ -24,5 +25,6 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_ceilometer_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   when: enable_swift | bool
   run_once: True
diff --git a/ansible/roles/ceph/tasks/start_rgw_keystone.yml b/ansible/roles/ceph/tasks/start_rgw_keystone.yml
index a510a30764..4027d341ea 100644
--- a/ansible/roles/ceph/tasks/start_rgw_keystone.yml
+++ b/ansible/roles/ceph/tasks/start_rgw_keystone.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_ceph_rgw_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ swift_admin_endpoint }}'}
@@ -31,6 +32,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_ceph_rgw_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Creating the ResellerAdmin role
@@ -42,4 +44,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_ceph_rgw_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/cinder/tasks/check.yml b/ansible/roles/cinder/tasks/check.yml
index fb58e02470..635acac119 100644
--- a/ansible/roles/cinder/tasks/check.yml
+++ b/ansible/roles/cinder/tasks/check.yml
@@ -9,6 +9,7 @@
       size: 1
       display_name: kolla_test_volume
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   delegate_to: "{{ groups['cinder-api'][0] }}"
   when: kolla_enable_sanity_cinder | bool
@@ -22,6 +23,7 @@
       state: absent
       display_name: kolla_test_volume
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   delegate_to: "{{ groups['cinder-api'][0] }}"
   when: kolla_enable_sanity_cinder | bool
diff --git a/ansible/roles/cinder/tasks/register.yml b/ansible/roles/cinder/tasks/register.yml
index f013f89408..579b28b925 100644
--- a/ansible/roles/cinder/tasks/register.yml
+++ b/ansible/roles/cinder/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_cinder_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ cinder_v2_admin_endpoint }}', 'service_name': 'cinderv2', 'service_type': 'volumev2'}
@@ -34,4 +35,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_cinder_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/cloudkitty/tasks/register.yml b/ansible/roles/cloudkitty/tasks/register.yml
index 7f7cd9e69c..7e487e68d6 100644
--- a/ansible/roles/cloudkitty/tasks/register.yml
+++ b/ansible/roles/cloudkitty/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_cloudkitty_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ cloudkitty_admin_endpoint }}'}
@@ -31,6 +32,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_cloudkitty_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Creating the rating role
@@ -41,4 +43,5 @@
       name: "{{ cloudkitty_openstack_keystone_default_role }}"
       auth: "{{ openstack_cloudkitty_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/congress/tasks/register.yml b/ansible/roles/congress/tasks/register.yml
index bbbd39cac2..8602471976 100644
--- a/ansible/roles/congress/tasks/register.yml
+++ b/ansible/roles/congress/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_congress_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ congress_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_congress_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/cyborg/tasks/register.yml b/ansible/roles/cyborg/tasks/register.yml
index decd02d617..88280ea156 100644
--- a/ansible/roles/cyborg/tasks/register.yml
+++ b/ansible/roles/cyborg/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_cyborg_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ cyborg_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_cyborg_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/designate/tasks/register.yml b/ansible/roles/designate/tasks/register.yml
index 354f3503b0..40f2ce4a4a 100644
--- a/ansible/roles/designate/tasks/register.yml
+++ b/ansible/roles/designate/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_designate_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ designate_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_designate_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/freezer/tasks/register.yml b/ansible/roles/freezer/tasks/register.yml
index 5dfa960114..c0048f126d 100644
--- a/ansible/roles/freezer/tasks/register.yml
+++ b/ansible/roles/freezer/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_freezer_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ freezer_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_freezer_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/glance/tasks/check.yml b/ansible/roles/glance/tasks/check.yml
index 466681bf16..77d09d5e9a 100644
--- a/ansible/roles/glance/tasks/check.yml
+++ b/ansible/roles/glance/tasks/check.yml
@@ -8,6 +8,7 @@
       name: "glance_sanity_check"
       filename: "/etc/hostname"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   delegate_to: "{{ groups['glance-api'][0] }}"
   run_once: True
   register: img_create
@@ -25,6 +26,7 @@
       name: "glance_sanity_check"
       state: absent
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   delegate_to: "{{ groups['glance-api'][0] }}"
   run_once: True
   when: kolla_enable_sanity_glance | bool
diff --git a/ansible/roles/glance/tasks/register.yml b/ansible/roles/glance/tasks/register.yml
index a94c34f8ff..43d922fff1 100644
--- a/ansible/roles/glance/tasks/register.yml
+++ b/ansible/roles/glance/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_glance_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ glance_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_glance_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/gnocchi/tasks/register.yml b/ansible/roles/gnocchi/tasks/register.yml
index 785267f803..417a13dc2d 100644
--- a/ansible/roles/gnocchi/tasks/register.yml
+++ b/ansible/roles/gnocchi/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_gnocchi_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ gnocchi_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_gnocchi_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/heat/tasks/register.yml b/ansible/roles/heat/tasks/register.yml
index b93f64e9bb..1441b36ede 100644
--- a/ansible/roles/heat/tasks/register.yml
+++ b/ansible/roles/heat/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_heat_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ heat_admin_endpoint }}', 'service_name': 'heat', 'service_type': 'orchestration', 'description': 'Orchestration'}
@@ -34,6 +35,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_heat_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Creating the heat_stack_user role
@@ -44,6 +46,7 @@
       name: "{{ heat_stack_user_role }}"
       auth: "{{ openstack_heat_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Creating the heat_stack_owner role
@@ -54,6 +57,7 @@
       name: "{{ heat_stack_owner_role }}"
       auth: "{{ openstack_heat_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Add the heat_stack_owner role to the admin project
@@ -67,4 +71,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_heat_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/horizon/templates/local_settings.j2 b/ansible/roles/horizon/templates/local_settings.j2
index 5fa97b9600..77ba0c0bea 100644
--- a/ansible/roles/horizon/templates/local_settings.j2
+++ b/ansible/roles/horizon/templates/local_settings.j2
@@ -247,7 +247,11 @@ OPENSTACK_KEYSTONE_DEFAULT_ROLE = "{{ keystone_default_user_role }}"
 #OPENSTACK_SSL_NO_VERIFY = True
 
 # The CA certificate to use to verify SSL connections
+{% if openstack_cacert == "" %}
 #OPENSTACK_SSL_CACERT = '/path/to/cacert.pem'
+{% else %}
+OPENSTACK_SSL_CACERT = '{{ openstack_cacert }}'
+{% endif %}
 
 # The OPENSTACK_KEYSTONE_BACKEND settings can be used to identify the
 # capabilities of the auth backend for Keystone.
diff --git a/ansible/roles/ironic/tasks/register.yml b/ansible/roles/ironic/tasks/register.yml
index 07a141d57f..9183f8570d 100644
--- a/ansible/roles/ironic/tasks/register.yml
+++ b/ansible/roles/ironic/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_ironic_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   when: inventory_hostname in groups['ironic-api']
   with_items:
@@ -32,6 +33,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_ironic_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   when: inventory_hostname in groups['ironic-api']
 
@@ -49,6 +51,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_ironic_inspector_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   when: inventory_hostname in groups['ironic-inspector']
   with_items:
@@ -68,5 +71,6 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_ironic_inspector_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   when: inventory_hostname in groups['ironic-inspector']
diff --git a/ansible/roles/karbor/tasks/register.yml b/ansible/roles/karbor/tasks/register.yml
index e1c33f70d5..d62cc2eb0d 100644
--- a/ansible/roles/karbor/tasks/register.yml
+++ b/ansible/roles/karbor/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_karbor_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ karbor_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_karbor_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/keystone/tasks/check.yml b/ansible/roles/keystone/tasks/check.yml
index 58e9b42394..5a62096ce9 100644
--- a/ansible/roles/keystone/tasks/check.yml
+++ b/ansible/roles/keystone/tasks/check.yml
@@ -6,6 +6,7 @@
     module_args:
       auth: "{{ openstack_keystone_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   delegate_to: "{{ groups['keystone'][0] }}"
   when: kolla_enable_sanity_keystone | bool
diff --git a/ansible/roles/keystone/tasks/register.yml b/ansible/roles/keystone/tasks/register.yml
index 9915a84cfd..457e89ddfe 100644
--- a/ansible/roles/keystone/tasks/register.yml
+++ b/ansible/roles/keystone/tasks/register.yml
@@ -24,6 +24,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_keystone_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - { interface: admin, url: "{{ keystone_admin_url }}" }
@@ -38,4 +39,5 @@
       name: "{{ keystone_default_user_role }}"
       auth: "{{ openstack_keystone_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/kuryr/tasks/register.yml b/ansible/roles/kuryr/tasks/register.yml
index 8f4baefdcc..28b24b2e6e 100644
--- a/ansible/roles/kuryr/tasks/register.yml
+++ b/ansible/roles/kuryr/tasks/register.yml
@@ -11,4 +11,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_kuryr_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/magnum/tasks/register.yml b/ansible/roles/magnum/tasks/register.yml
index b0fdd5741b..40e1a01d5d 100644
--- a/ansible/roles/magnum/tasks/register.yml
+++ b/ansible/roles/magnum/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_magnum_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ magnum_admin_endpoint }}'}
@@ -31,6 +32,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_magnum_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Creating Magnum trustee domain
@@ -42,6 +44,7 @@
       description: "Owns users and projects created by magnum"
       auth: "{{ openstack_magnum_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   register: trustee_domain
   run_once: True
 
@@ -55,6 +58,7 @@
       password: "{{ magnum_keystone_password }}"
       auth: "{{ openstack_magnum_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Creating Magnum trustee user role
@@ -67,4 +71,5 @@
       role: "admin"
       auth: "{{ openstack_magnum_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/manila/tasks/register.yml b/ansible/roles/manila/tasks/register.yml
index 46850d17a7..944bb52f50 100644
--- a/ansible/roles/manila/tasks/register.yml
+++ b/ansible/roles/manila/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_manila_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ manila_admin_endpoint }}', 'service_name': 'manila', 'service_type': 'share'}
@@ -34,4 +35,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_manila_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/masakari/tasks/register.yml b/ansible/roles/masakari/tasks/register.yml
index 71ad23d7b3..b74150ab5c 100644
--- a/ansible/roles/masakari/tasks/register.yml
+++ b/ansible/roles/masakari/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_masakari_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ masakari_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_masakari_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/mistral/tasks/register.yml b/ansible/roles/mistral/tasks/register.yml
index d057721b4c..8f3217dbc1 100644
--- a/ansible/roles/mistral/tasks/register.yml
+++ b/ansible/roles/mistral/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_mistral_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ mistral_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_mistral_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/monasca/tasks/register.yml b/ansible/roles/monasca/tasks/register.yml
index 6f609cff32..f6db499ddd 100644
--- a/ansible/roles/monasca/tasks/register.yml
+++ b/ansible/roles/monasca/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ monasca_openstack_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ monasca_api_admin_endpoint }}'}
@@ -33,6 +34,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ monasca_openstack_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ monasca_log_api_admin_endpoint }}'}
@@ -51,6 +53,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ monasca_openstack_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Creating monasca roles
@@ -62,6 +65,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ monasca_openstack_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - "{{ monasca_default_authorized_roles }}"
@@ -81,4 +85,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ monasca_openstack_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/murano/tasks/register.yml b/ansible/roles/murano/tasks/register.yml
index 5945c1a42c..2068a1843c 100644
--- a/ansible/roles/murano/tasks/register.yml
+++ b/ansible/roles/murano/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_murano_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ murano_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_murano_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/neutron/tasks/register.yml b/ansible/roles/neutron/tasks/register.yml
index 7938774fb2..dc575d9ba5 100644
--- a/ansible/roles/neutron/tasks/register.yml
+++ b/ansible/roles/neutron/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_neutron_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ neutron_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_neutron_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/nova/tasks/discover_computes.yml b/ansible/roles/nova/tasks/discover_computes.yml
index 9dd8dded5a..860364ef45 100644
--- a/ansible/roles/nova/tasks/discover_computes.yml
+++ b/ansible/roles/nova/tasks/discover_computes.yml
@@ -40,6 +40,7 @@
     --os-password {{ keystone_admin_password }}
     --os-user-domain-name {{ openstack_auth.domain_name }}
     --os-region-name {{ openstack_region_name }}
+    {% if openstack_cacert != '' %}--os-cacert {{ openstack_cacert }}{% endif %}
     compute service list --format json --column Host --service nova-compute
   register: nova_compute_services
   changed_when: false
diff --git a/ansible/roles/nova/tasks/register.yml b/ansible/roles/nova/tasks/register.yml
index 4c540f8f97..b80ff579d8 100644
--- a/ansible/roles/nova/tasks/register.yml
+++ b/ansible/roles/nova/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_nova_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'name': 'nova_legacy', 'service_type': 'compute_legacy', 'interface': 'admin', 'url': '{{ nova_legacy_admin_endpoint }}', 'description': 'OpenStack Compute Service (Legacy 2.0)'}
@@ -34,4 +35,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_nova_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/octavia/tasks/register.yml b/ansible/roles/octavia/tasks/register.yml
index c89cf0c1ff..cefead8ca5 100644
--- a/ansible/roles/octavia/tasks/register.yml
+++ b/ansible/roles/octavia/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_octavia_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ octavia_admin_endpoint }}'}
@@ -31,6 +32,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_octavia_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Adding octavia user into admin project
@@ -43,6 +45,7 @@
       project: admin
       auth: "{{ openstack_octavia_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Adding octavia related roles
@@ -53,5 +56,6 @@
       name: "{{ item }}"
       auth: "{{ openstack_octavia_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items: "{{ octavia_required_roles }}"
diff --git a/ansible/roles/panko/tasks/register.yml b/ansible/roles/panko/tasks/register.yml
index 579da88f44..115bbee835 100644
--- a/ansible/roles/panko/tasks/register.yml
+++ b/ansible/roles/panko/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_panko_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ panko_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_panko_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/placement/tasks/register.yml b/ansible/roles/placement/tasks/register.yml
index 3ccd87c404..ab0678511c 100644
--- a/ansible/roles/placement/tasks/register.yml
+++ b/ansible/roles/placement/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_placement_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'name': 'placement', 'service_type': 'placement', 'interface': 'admin', 'url': '{{ placement_admin_endpoint }}', 'description': 'Placement Service'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_placement_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/qinling/tasks/register.yml b/ansible/roles/qinling/tasks/register.yml
index f1a8914ab2..fc2ca0428a 100644
--- a/ansible/roles/qinling/tasks/register.yml
+++ b/ansible/roles/qinling/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_qinling_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ qinling_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_qinling_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/sahara/tasks/register.yml b/ansible/roles/sahara/tasks/register.yml
index 2bf18582c9..c4624d9f4f 100644
--- a/ansible/roles/sahara/tasks/register.yml
+++ b/ansible/roles/sahara/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_sahara_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ sahara_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_sahara_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/searchlight/tasks/register.yml b/ansible/roles/searchlight/tasks/register.yml
index 4902aa11e1..d227ebe138 100644
--- a/ansible/roles/searchlight/tasks/register.yml
+++ b/ansible/roles/searchlight/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_searchlight_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ searchlight_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_searchlight_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/senlin/tasks/register.yml b/ansible/roles/senlin/tasks/register.yml
index 0a4be59240..8b22b84011 100644
--- a/ansible/roles/senlin/tasks/register.yml
+++ b/ansible/roles/senlin/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_senlin_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ senlin_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_senlin_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/solum/tasks/register.yml b/ansible/roles/solum/tasks/register.yml
index f31415739e..9ed1bb5039 100644
--- a/ansible/roles/solum/tasks/register.yml
+++ b/ansible/roles/solum/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_solum_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ solum_image_builder_admin_endpoint }}'}
@@ -33,6 +34,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_solum_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ solum_application_deployment_admin_endpoint }}'}
@@ -51,4 +53,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_solum_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/swift/tasks/check.yml b/ansible/roles/swift/tasks/check.yml
index ac26b20abc..9259f2dbf1 100644
--- a/ansible/roles/swift/tasks/check.yml
+++ b/ansible/roles/swift/tasks/check.yml
@@ -9,7 +9,8 @@
         password={{ swift_keystone_password }}
         role=admin
         region_name={{ openstack_region_name }}
-        auth={{ '{{ openstack_swift_auth }}' }}"
+        auth={{ '{{ openstack_swift_auth }}' }}
+        {% if openstack_cacert != '' %}cacert={{ openstack_cacert }}{% endif %}"
     -e "{'openstack_swift_auth':{{ openstack_swift_auth }}}"
   register: swift_sanity
   changed_when: swift_sanity.stdout.find('localhost | SUCCESS => ') != -1 and (swift_sanity.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
diff --git a/ansible/roles/swift/tasks/register.yml b/ansible/roles/swift/tasks/register.yml
index 04f7d958c9..b6c709cb53 100644
--- a/ansible/roles/swift/tasks/register.yml
+++ b/ansible/roles/swift/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_swift_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ swift_admin_endpoint }}'}
@@ -31,6 +32,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_swift_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Creating the ResellerAdmin role
@@ -42,4 +44,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_swift_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/tacker/tasks/register.yml b/ansible/roles/tacker/tasks/register.yml
index 0bb38a7792..f8336d11bb 100644
--- a/ansible/roles/tacker/tasks/register.yml
+++ b/ansible/roles/tacker/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_tacker_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ tacker_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_tacker_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/trove/tasks/register.yml b/ansible/roles/trove/tasks/register.yml
index c24d42db9b..996e0c7529 100644
--- a/ansible/roles/trove/tasks/register.yml
+++ b/ansible/roles/trove/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_trove_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ trove_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_trove_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/vitrage/tasks/register.yml b/ansible/roles/vitrage/tasks/register.yml
index 0be3f1bdb5..53afab62ad 100644
--- a/ansible/roles/vitrage/tasks/register.yml
+++ b/ansible/roles/vitrage/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_vitrage_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ vitrage_admin_endpoint }}'}
@@ -31,6 +32,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_vitrage_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
 
 - name: Adding vitrage user into admin project
@@ -43,4 +45,5 @@
       project: "admin"
       auth: "{{ openstack_vitrage_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/watcher/tasks/register.yml b/ansible/roles/watcher/tasks/register.yml
index 70b4997004..619aab4514 100644
--- a/ansible/roles/watcher/tasks/register.yml
+++ b/ansible/roles/watcher/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_watcher_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ watcher_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_watcher_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/ansible/roles/zun/tasks/register.yml b/ansible/roles/zun/tasks/register.yml
index f6d5e8de39..c5d402b38f 100644
--- a/ansible/roles/zun/tasks/register.yml
+++ b/ansible/roles/zun/tasks/register.yml
@@ -13,6 +13,7 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_zun_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
   with_items:
     - {'interface': 'admin', 'url': '{{ zun_admin_endpoint }}'}
@@ -31,4 +32,5 @@
       region_name: "{{ openstack_region_name }}"
       auth: "{{ openstack_zun_auth }}"
       endpoint_type: "{{ openstack_interface }}"
+      cacert: "{{ openstack_cacert }}"
   run_once: True
diff --git a/releasenotes/notes/trusted-cacert-3c7061e974b5187d.yaml b/releasenotes/notes/trusted-cacert-3c7061e974b5187d.yaml
new file mode 100644
index 0000000000..d873f204d9
--- /dev/null
+++ b/releasenotes/notes/trusted-cacert-3c7061e974b5187d.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Add support for configuration of trusted CA certificate file.
+    CA bundle file must be added to both the Horizon and Kolla Toolbox
+    containers for this to work correctly.