diff --git a/ansible/roles/cinder/tasks/bootstrap.yml b/ansible/roles/cinder/tasks/bootstrap.yml
index 1c0790048d..b3ef61139e 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 184b97a273..06909bd225 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 663e93f6f7..f080d13efc 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 3370da4c1f..f3b739a0f9 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 7a00dd931e..b14ce94db1 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 52e4eef7e6..a27fbf2ccc 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 1e63a1a372..afac4facbf 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 4bc9641255..e32778aee8 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 8056796ab1..c42f4120ca 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 98daa4021c..f00b4f0e6a 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 bd6e526add..facda5d1fd 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 5c48120b7c..50e56814ac 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 a6c08baa87..25d6e52ea2 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 a76d0866dd..13d6447329 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 ebb6cab5dc..b11abe5f97 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 f8eff9ba93..82132ce494 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 b96f045849..30a17dfefb 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 869235f35e..748a19f843 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