diff --git a/ansible/roles/cinder/tasks/bootstrap.yml b/ansible/roles/cinder/tasks/bootstrap.yml
index 1c0790048d1d56dc67a35765be78acbfd9d8c740..b3ef61139e4cac5cdb1c643e0d0a0451a7987e5f 100644
--- a/ansible/roles/cinder/tasks/bootstrap.yml
+++ b/ansible/roles/cinder/tasks/bootstrap.yml
@@ -10,6 +10,7 @@
   changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['cinder-api'][0] }}"
 
 - name: Creating Cinder database user and setting permissions
   command: docker exec -t kolla_ansible /usr/bin/ansible localhost
@@ -26,6 +27,7 @@
   changed_when: "{{ database_user_create.stdout.find('localhost | SUCCESS => ') != -1 and (database_user_create.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database_user_create.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['cinder-api'][0] }}"
 
 - name: Starting Cinder bootstrap container
   docker:
@@ -46,9 +48,8 @@
       KOLLA_BOOTSTRAP:
       KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
   run_once: True
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['cinder-api']
+  delegate_to: "{{ groups['cinder-api'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 # https://github.com/ansible/ansible-modules-core/pull/1031
 - name: Waiting for bootstrap container to exit
@@ -56,9 +57,8 @@
   failed_when: bootstrap_result.stdout != "0"
   register: bootstrap_result
   run_once: True
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['cinder-api']
+  delegate_to: "{{ groups['cinder-api'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 - name: Cleaning up Cinder bootstrap container
   docker:
@@ -66,4 +66,5 @@
     name: bootstrap_cinder
     image: "{{ cinder_api_image_full }}"
     state: absent
+  delegate_to: "{{ groups['cinder-api'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
diff --git a/ansible/roles/cinder/tasks/main.yml b/ansible/roles/cinder/tasks/main.yml
index 184b97a273c68ef77f8004decb1ff53b388bbebb..06909bd2252b26cf41eb8e78a1383a4dde744bf8 100644
--- a/ansible/roles/cinder/tasks/main.yml
+++ b/ansible/roles/cinder/tasks/main.yml
@@ -9,10 +9,7 @@
         inventory_hostname in groups['cinder-backup']
 
 - include: register.yml
-  when: inventory_hostname in groups['cinder-api'] or
-        inventory_hostname in groups['cinder-volume'] or
-        inventory_hostname in groups['cinder-scheduler'] or
-        inventory_hostname in groups['cinder-backup']
+  when: inventory_hostname in groups['cinder-api']
 
 - include: config.yml
   when: inventory_hostname in groups['cinder-api'] or
@@ -21,10 +18,7 @@
         inventory_hostname in groups['cinder-backup']
 
 - include: bootstrap.yml
-  when: inventory_hostname in groups['cinder-api'] or
-        inventory_hostname in groups['cinder-volume'] or
-        inventory_hostname in groups['cinder-scheduler'] or
-        inventory_hostname in groups['cinder-backup']
+  when: inventory_hostname in groups['cinder-api']
 
 - include: start.yml
   when: inventory_hostname in groups['cinder-api'] or
diff --git a/ansible/roles/glance/tasks/bootstrap.yml b/ansible/roles/glance/tasks/bootstrap.yml
index 663e93f6f710b2af7cc8dd1bcb628c2da3075bbe..f080d13efc11fb9bf49a82066f7f51eb000daac0 100644
--- a/ansible/roles/glance/tasks/bootstrap.yml
+++ b/ansible/roles/glance/tasks/bootstrap.yml
@@ -11,6 +11,7 @@
   changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['glance-api'][0] }}"
 
 - name: Creating Glance database user and setting permissions
   command: docker exec -t kolla_ansible /usr/bin/ansible localhost
@@ -27,6 +28,7 @@
   changed_when: "{{ database_user_create.stdout.find('localhost | SUCCESS => ') != -1 and (database_user_create.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database_user_create.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['glance-api'][0] }}"
 
 - name: Starting Glance bootstrap container
   docker:
@@ -47,19 +49,17 @@
       KOLLA_BOOTSTRAP:
       KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
   run_once: True
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['glance-api']
+  delegate_to: "{{ groups['glance-api'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 # https://github.com/ansible/ansible-modules-core/pull/1031
 - name: Waiting for bootstrap container to exit
   command: docker wait bootstrap_glance
   register: bootstrap_result
   run_once: True
+  delegate_to: "{{ groups['glance-api'][0] }}"
   failed_when: bootstrap_result.stdout != "0"
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['glance-api']
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 - name: Cleaning up Glance bootstrap container
   docker:
@@ -67,4 +67,5 @@
     name: bootstrap_glance
     image: "{{ glance_api_image_full }}"
     state: absent
+  delegate_to: "{{ groups['glance-api'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
diff --git a/ansible/roles/glance/tasks/main.yml b/ansible/roles/glance/tasks/main.yml
index 3370da4c1f8574a2b570e186ec791ca2c83c63a5..f3b739a0f95c62ddd9b7713a22f71ac3565410e1 100644
--- a/ansible/roles/glance/tasks/main.yml
+++ b/ansible/roles/glance/tasks/main.yml
@@ -7,16 +7,14 @@
         inventory_hostname in groups['glance-registry']
 
 - include: register.yml
-  when: inventory_hostname in groups['glance-api'] or
-        inventory_hostname in groups['glance-registry']
+  when: inventory_hostname in groups['glance-api']
 
 - include: config.yml
   when: inventory_hostname in groups['glance-api'] or
         inventory_hostname in groups['glance-registry']
 
 - include: bootstrap.yml
-  when: inventory_hostname in groups['glance-api'] or
-        inventory_hostname in groups['glance-registry']
+  when: inventory_hostname in groups['glance-api']
 
 - include: start.yml
   when: inventory_hostname in groups['glance-api'] or
diff --git a/ansible/roles/heat/tasks/bootstrap.yml b/ansible/roles/heat/tasks/bootstrap.yml
index 7a00dd931e1c945ffbcc9a51fc336f74ed02431c..b14ce94db15455c82ec433a8318cdde374e5e107 100644
--- a/ansible/roles/heat/tasks/bootstrap.yml
+++ b/ansible/roles/heat/tasks/bootstrap.yml
@@ -10,6 +10,7 @@
   changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['heat-api'][0] }}"
 
 - name: Creating Heat database user and setting permissions
   command: docker exec -t kolla_ansible /usr/bin/ansible localhost
@@ -26,6 +27,7 @@
   changed_when: "{{ database_user_create.stdout.find('localhost | SUCCESS => ') != -1 and (database_user_create.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database_user_create.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['heat-api'][0] }}"
 
 - name: Starting Heat bootstrap container
   docker:
@@ -52,9 +54,8 @@
       OS_PROJECT_NAME: "{{ openstack_auth.project_name }}"
       HEAT_DOMAIN_ADMIN_PASSWORD: "{{ heat_domain_admin_password }}"
   run_once: True
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['heat-api']
+  delegate_to: "{{ groups['heat-api'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 # https://github.com/ansible/ansible-modules-core/pull/1031
 - name: Waiting for bootstrap container to exit
@@ -62,9 +63,8 @@
   register: bootstrap_result
   run_once: True
   failed_when: bootstrap_result.stdout != "0"
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['heat-api']
+  delegate_to: "{{ groups['heat-api'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 - name: Cleaning up Heat boostrap container
   docker:
@@ -72,4 +72,5 @@
     name: bootstrap_heat
     image: "{{ heat_api_image_full }}"
     state: absent
+  delegate_to: "{{ groups['heat-api'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
diff --git a/ansible/roles/heat/tasks/main.yml b/ansible/roles/heat/tasks/main.yml
index 52e4eef7e6eaa083f6e493ff4a60fe1f81519152..a27fbf2ccc6c6f660d1bf970e6ad9e3062d10321 100644
--- a/ansible/roles/heat/tasks/main.yml
+++ b/ansible/roles/heat/tasks/main.yml
@@ -1,8 +1,6 @@
 ---
 - include: register.yml
-  when: inventory_hostname in groups['heat-api'] or
-        inventory_hostname in groups['heat-api-cfn'] or
-        inventory_hostname in groups['heat-engine']
+  when: inventory_hostname in groups['heat-api']
 
 - include: config.yml
   when: inventory_hostname in groups['heat-api'] or
@@ -10,9 +8,7 @@
         inventory_hostname in groups['heat-engine']
 
 - include: bootstrap.yml
-  when: inventory_hostname in groups['heat-api'] or
-        inventory_hostname in groups['heat-api-cfn'] or
-        inventory_hostname in groups['heat-engine']
+  when: inventory_hostname in groups['heat-api']
 
 - include: start.yml
   when: inventory_hostname in groups['heat-api'] or
diff --git a/ansible/roles/ironic/tasks/bootstrap.yml b/ansible/roles/ironic/tasks/bootstrap.yml
index 1e63a1a372bc05bb73f2e5dbe79a088a190cf24d..afac4facbfc109793b92e8c5b2ae88b3ef76ebf1 100644
--- a/ansible/roles/ironic/tasks/bootstrap.yml
+++ b/ansible/roles/ironic/tasks/bootstrap.yml
@@ -11,6 +11,7 @@
   changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['ironic-api'][0] }}"
 
 - name: Creating Ironic database user and setting permissions
   command: docker exec -t kolla_ansible /usr/bin/ansible localhost
@@ -28,6 +29,7 @@
   changed_when: "{{ database_user_create.stdout.find('localhost | SUCCESS => ') != -1 and (database_user_create.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database_user_create.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['ironic-api'][0] }}"
 
 - name: Starting Ironic bootstrap container
   docker:
@@ -48,17 +50,15 @@
       KOLLA_BOOTSTRAP:
       KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
   run_once: True
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['ironic-api']
+  delegate_to: "{{ groups['ironic-api'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 # https://github.com/ansible/ansible-modules-core/pull/1031
 - name: Waiting for Ironic bootstrap container to exit
   command: docker wait bootstrap_ironic
   run_once: True
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['ironic-api']
+  delegate_to: "{{ groups['ironic-api'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 - name: Cleaning up boostrap container
   docker:
@@ -66,4 +66,5 @@
     name: bootstrap_ironic
     image: "{{ ironic_api_image_full }}"
     state: absent
+  delegate_to: "{{ groups['ironic-api'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
diff --git a/ansible/roles/ironic/tasks/main.yml b/ansible/roles/ironic/tasks/main.yml
index 4bc96412555570d1bc6fee4d5fdc9162ee31e0e0..e32778aee8afb594a20bed3ed9619df8da4c6129 100644
--- a/ansible/roles/ironic/tasks/main.yml
+++ b/ansible/roles/ironic/tasks/main.yml
@@ -1,9 +1,6 @@
 ---
 - include: register.yml
-  when: inventory_hostname in groups['ironic-api'] or
-        inventory_hostname in groups['ironic-conductor'] or
-        inventory_hostname in groups['ironic-discoverd'] or
-        inventory_hostname in groups['ironic-pxe']
+  when: inventory_hostname in groups['ironic-api']
 
 - include: config.yml
   when: inventory_hostname in groups['ironic-api'] or
@@ -12,10 +9,7 @@
         inventory_hostname in groups['ironic-pxe']
 
 - include: bootstrap.yml
-  when: inventory_hostname in groups['ironic-api'] or
-        inventory_hostname in groups['ironic-conductor'] or
-        inventory_hostname in groups['ironic-discoverd'] or
-        inventory_hostname in groups['ironic-pxe']
+  when: inventory_hostname in groups['ironic-api']
 
 - include: start.yml
   when: inventory_hostname in groups['ironic-api'] or
diff --git a/ansible/roles/keystone/tasks/bootstrap.yml b/ansible/roles/keystone/tasks/bootstrap.yml
index 8056796ab128fc68a9927b806a894e7bd1334236..c42f4120ca5b57fed5a26c77b48cbc780284aa1d 100644
--- a/ansible/roles/keystone/tasks/bootstrap.yml
+++ b/ansible/roles/keystone/tasks/bootstrap.yml
@@ -11,6 +11,7 @@
   changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['keystone'][0] }}"
 
 - name: Creating Keystone database user and setting permissions
   command: docker exec -t kolla_ansible /usr/bin/ansible localhost
@@ -28,6 +29,7 @@
   changed_when: "{{ database_user_create.stdout.find('localhost | SUCCESS => ') != -1 and (database_user_create.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database_user_create.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['keystone'][0] }}"
 
 - name: Starting Keystone bootstrap container
   docker:
@@ -55,6 +57,7 @@
       OS_TOKEN: "{{ keystone_admin_token }}"
       OS_URL: "http://{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}:{{ keystone_admin_port }}/v2.0"
   run_once: True
+  delegate_to: "{{ groups['keystone'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 # https://github.com/ansible/ansible-modules-core/pull/1031
@@ -63,6 +66,7 @@
   register: bootstrap_result
   run_once: True
   failed_when: bootstrap_result.stdout != "0"
+  delegate_to: "{{ groups['keystone'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 - name: Cleaning up Keystone bootstrap container
@@ -71,4 +75,5 @@
     name: bootstrap_keystone
     image: "{{ keystone_image_full }}"
     state: absent
+  delegate_to: "{{ groups['keystone'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
diff --git a/ansible/roles/keystone/tasks/main.yml b/ansible/roles/keystone/tasks/main.yml
index 98daa4021c80fe45b12c732676e385a820c53f78..f00b4f0e6a7846639689c888d87324bfcef9130d 100644
--- a/ansible/roles/keystone/tasks/main.yml
+++ b/ansible/roles/keystone/tasks/main.yml
@@ -1,6 +1,9 @@
 ---
 - include: config.yml
+  when: inventory_hostname in groups['keystone']
 
 - include: bootstrap.yml
+  when: inventory_hostname in groups['keystone']
 
 - include: start.yml
+  when: inventory_hostname in groups['keystone']
diff --git a/ansible/roles/magnum/tasks/bootstrap.yml b/ansible/roles/magnum/tasks/bootstrap.yml
index bd6e526adda9e99a5a08c8e1d254dd69f078f6c4..facda5d1fd58c74f179cb348c9a0673d87b74b4b 100644
--- a/ansible/roles/magnum/tasks/bootstrap.yml
+++ b/ansible/roles/magnum/tasks/bootstrap.yml
@@ -10,6 +10,7 @@
   changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['magnum-api'][0] }}"
 
 - name: Creating Magnum database user and setting permissions
   command: docker exec -t kolla_ansible /usr/bin/ansible localhost
@@ -26,6 +27,7 @@
   changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and (database_user_create.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database_user_create.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['magnum-api'][0] }}"
 
 - name: Starting Magnum bootstrap container
   docker:
@@ -46,6 +48,7 @@
       KOLLA_BOOTSTRAP:
       KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
   run_once: True
+  delegate_to: "{{ groups['magnum-api'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 # https://github.com/ansible/ansible-modules-core/pull/1031
@@ -54,6 +57,7 @@
   register: bootstrap_result
   run_once: True
   failed_when: bootstrap_result.stdout != "0"
+  delegate_to: "{{ groups['magnum-api'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 - name: Cleaning up Magnum boostrap container
@@ -62,4 +66,5 @@
     name: bootstrap_magnum
     image: "{{ magnum_api_image_full }}"
     state: absent
+  delegate_to: "{{ groups['magnum-api'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
diff --git a/ansible/roles/magnum/tasks/main.yml b/ansible/roles/magnum/tasks/main.yml
index 5c48120b7c9e6ee00027462c3f23aa25c6b05dd7..50e56814acf53f89e20a3716b302686b497686fa 100644
--- a/ansible/roles/magnum/tasks/main.yml
+++ b/ansible/roles/magnum/tasks/main.yml
@@ -1,8 +1,14 @@
 ---
 - include: register.yml
+  when: inventory_hostname in groups['magnum-api']
 
 - include: config.yml
+  when: inventory_hostname in groups['magnum-api'] or
+        inventory_hostname in groups['magnum-conductor']
 
 - include: bootstrap.yml
+  when: inventory_hostname in groups['magnum-api']
 
 - include: start.yml
+  when: inventory_hostname in groups['magnum-api'] or
+        inventory_hostname in groups['magnum-conductor']
diff --git a/ansible/roles/murano/tasks/bootstrap.yml b/ansible/roles/murano/tasks/bootstrap.yml
index a6c08baa8713951778ba249ab9c2857bfa5daf0e..25d6e52ea267a5481b64f59388b358ea208b6817 100644
--- a/ansible/roles/murano/tasks/bootstrap.yml
+++ b/ansible/roles/murano/tasks/bootstrap.yml
@@ -11,6 +11,7 @@
   changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['murano-api'][0] }}"
 
 - name: Creating Murano database user and setting permissions
   command: docker exec -t kolla_ansible /usr/bin/ansible localhost
@@ -27,6 +28,7 @@
   changed_when: "{{ database_user_create.stdout.find('localhost | SUCCESS => ') != -1 and (database_user_create.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database_user_create.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['murano-api'][0] }}"
 
 - name: Starting Murano bootstrap container
   docker:
@@ -47,17 +49,15 @@
       KOLLA_BOOTSTRAP:
       KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
   run_once: True
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['murano-api']
+  delegate_to: "{{ groups['murano-api'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 # https://github.com/ansible/ansible-modules-core/pull/1031
 - name: Waiting for bootstrap container to exit
   command: docker wait bootstrap_murano
   run_once: True
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['murano-api']
+  delegate_to: "{{ groups['murano-api'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 - name: Cleaning up Murano boostrap container
   docker:
@@ -65,4 +65,5 @@
     name: bootstrap_murano
     image: "{{ murano_api_image_full }}"
     state: absent
+  delegate_to: "{{ groups['murano-api'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
diff --git a/ansible/roles/murano/tasks/main.yml b/ansible/roles/murano/tasks/main.yml
index a76d0866dde5e5253acd21e91ab45743a3c5ca1d..13d6447329e8293efd35fc1db2ffddc3ae0359c1 100644
--- a/ansible/roles/murano/tasks/main.yml
+++ b/ansible/roles/murano/tasks/main.yml
@@ -1,15 +1,13 @@
 ---
 - include: register.yml
-  when: inventory_hostname in groups['murano-api'] or
-        inventory_hostname in groups['murano-engine']
+  when: inventory_hostname in groups['murano-api']
 
 - include: config.yml
   when: inventory_hostname in groups['murano-api'] or
         inventory_hostname in groups['murano-engine']
 
 - include: bootstrap.yml
-  when: inventory_hostname in groups['murano-api'] or
-        inventory_hostname in groups['murano-engine']
+  when: inventory_hostname in groups['murano-api']
 
 - include: start.yml
   when: inventory_hostname in groups['murano-api'] or
diff --git a/ansible/roles/neutron/tasks/bootstrap.yml b/ansible/roles/neutron/tasks/bootstrap.yml
index ebb6cab5dc969bfbbbb67d331ac534e9660f0d76..b11abe5f97d50e2a12132133144376b75f3dee4b 100644
--- a/ansible/roles/neutron/tasks/bootstrap.yml
+++ b/ansible/roles/neutron/tasks/bootstrap.yml
@@ -10,6 +10,7 @@
   changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['neutron-server'][0] }}"
 
 - name: Creating Neutron database user and setting permissions
   command: docker exec -t kolla_ansible /usr/bin/ansible localhost
@@ -26,6 +27,7 @@
   changed_when: "{{ database_user_create.stdout.find('localhost | SUCCESS => ') != -1 and (database_user_create.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database_user_create.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['neutron-server'][0] }}"
 
 - name: Starting Neutron bootstrap container
   docker:
@@ -46,9 +48,8 @@
       KOLLA_BOOTSTRAP:
       KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
   run_once: True
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['neutron-server']
+  delegate_to: "{{ groups['neutron-server'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 # https://github.com/ansible/ansible-modules-core/pull/1031
 - name: Waiting for bootstrap container to exit
@@ -56,9 +57,8 @@
   register: bootstrap_result
   run_once: True
   failed_when: bootstrap_result.stdout != "0"
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['neutron-server']
+  delegate_to: "{{ groups['neutron-server'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 - name: Cleaning up Neutron bootstrap container
   docker:
@@ -66,4 +66,5 @@
     name: bootstrap_neutron
     image: "{{ neutron_server_image_full }}"
     state: absent
+  delegate_to: "{{ groups['neutron-server'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
diff --git a/ansible/roles/neutron/tasks/main.yml b/ansible/roles/neutron/tasks/main.yml
index f8eff9ba93d68ac9098cfcb8e59eb05fdbfd6b46..82132ce494eebd1a028aa14864e981b9201963aa 100644
--- a/ansible/roles/neutron/tasks/main.yml
+++ b/ansible/roles/neutron/tasks/main.yml
@@ -3,9 +3,7 @@
 - include: ironic-check.yml
 
 - include: register.yml
-  when: inventory_hostname in groups['compute'] or
-        inventory_hostname in groups['neutron-agents'] or
-        inventory_hostname in groups['neutron-server']
+  when: inventory_hostname in groups['neutron-server']
 
 - include: config.yml
   when: inventory_hostname in groups['compute'] or
@@ -13,9 +11,7 @@
         inventory_hostname in groups['neutron-server']
 
 - include: bootstrap.yml
-  when: inventory_hostname in groups['compute'] or
-        inventory_hostname in groups['neutron-agents'] or
-        inventory_hostname in groups['neutron-server']
+  when: inventory_hostname in groups['neutron-server']
 
 - include: start.yml
   when: inventory_hostname in groups['compute'] or
diff --git a/ansible/roles/nova/tasks/bootstrap.yml b/ansible/roles/nova/tasks/bootstrap.yml
index b96f045849559eb3de7b20f99f2750732f48d0a9..30a17dfefb1f222e4d122a4367a1775c732ffb6e 100644
--- a/ansible/roles/nova/tasks/bootstrap.yml
+++ b/ansible/roles/nova/tasks/bootstrap.yml
@@ -10,6 +10,7 @@
   changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['nova-api'][0] }}"
 
 - name: Creating Nova database user and setting permissions
   command: docker exec -t kolla_ansible /usr/bin/ansible localhost
@@ -26,6 +27,7 @@
   changed_when: "{{ database_user_create.stdout.find('localhost | SUCCESS => ') != -1 and (database_user_create.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}"
   failed_when: database_user_create.stdout.split()[2] != 'SUCCESS'
   run_once: True
+  delegate_to: "{{ groups['nova-api'][0] }}"
 
 - name: Starting Nova bootstrap container
   docker:
@@ -46,9 +48,8 @@
       KOLLA_BOOTSTRAP:
       KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
   run_once: True
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['nova-api']
+  delegate_to: "{{ groups['nova-api'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 # https://github.com/ansible/ansible-modules-core/pull/1031
 - name: Waiting for bootstrap container to exit
@@ -56,9 +57,8 @@
   register: bootstrap_result
   run_once: True
   failed_when: bootstrap_result.stdout != "0"
-  when:
-    - database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
-    - inventory_hostname in groups['nova-api']
+  delegate_to: "{{ groups['nova-api'][0] }}"
+  when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
 
 - name: Cleaning up Nova bootstrap container
   docker:
@@ -66,4 +66,5 @@
     name: bootstrap_nova
     image: "{{ nova_api_image_full }}"
     state: absent
+  delegate_to: "{{ groups['nova-api'][0] }}"
   when: database.stdout.find('localhost | SUCCESS => ') != -1 and (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed
diff --git a/ansible/roles/nova/tasks/main.yml b/ansible/roles/nova/tasks/main.yml
index 869235f35e7ec38dcbc3c05a2c4d4a79f4fffa6e..748a19f843ee3263258fa14c02923ebecee7ea5a 100644
--- a/ansible/roles/nova/tasks/main.yml
+++ b/ansible/roles/nova/tasks/main.yml
@@ -11,12 +11,7 @@
         inventory_hostname in groups['nova-scheduler']
 
 - include: register.yml
-  when: inventory_hostname in groups['compute'] or
-        inventory_hostname in groups['nova-api'] or
-        inventory_hostname in groups['nova-conductor'] or
-        inventory_hostname in groups['nova-consoleauth'] or
-        inventory_hostname in groups['nova-novncproxy'] or
-        inventory_hostname in groups['nova-scheduler']
+  when: inventory_hostname in groups['nova-api']
 
 - include: config.yml
   when: inventory_hostname in groups['compute'] or
@@ -27,12 +22,7 @@
         inventory_hostname in groups['nova-scheduler']
 
 - include: bootstrap.yml
-  when: inventory_hostname in groups['compute'] or
-        inventory_hostname in groups['nova-api'] or
-        inventory_hostname in groups['nova-conductor'] or
-        inventory_hostname in groups['nova-consoleauth'] or
-        inventory_hostname in groups['nova-novncproxy'] or
-        inventory_hostname in groups['nova-scheduler']
+  when: inventory_hostname in groups['nova-api']
 
 - include: start.yml
   when: inventory_hostname in groups['compute'] or