diff --git a/ansible/roles/nova-cell/tasks/create_cells.yml b/ansible/roles/nova-cell/tasks/create_cells.yml
index bb8f21dd0735ccbdf7dc7f66dc602c341cedd617..3bad73c2aa83ca1a23a0568980083039a8074a07 100644
--- a/ansible/roles/nova-cell/tasks/create_cells.yml
+++ b/ansible/roles/nova-cell/tasks/create_cells.yml
@@ -1,5 +1,7 @@
 ---
 - import_tasks: get_cell_settings.yml
+  when:
+    - inventory_hostname == groups[nova_conductor.group][0] | default(None)
 
 - name: Create cell
   vars:
diff --git a/ansible/roles/nova-cell/tasks/deploy.yml b/ansible/roles/nova-cell/tasks/deploy.yml
index 7e0a9cd222338db4cad5f9d85eead1d1e12ea6ce..b45d9826b00e17d68e24ba9cae8841e86cb73ae3 100644
--- a/ansible/roles/nova-cell/tasks/deploy.yml
+++ b/ansible/roles/nova-cell/tasks/deploy.yml
@@ -18,4 +18,22 @@
   meta: flush_handlers
 
 - include_tasks: discover_computes.yml
-  when: inventory_hostname in groups[nova_cell_conductor_group]
+  vars:
+    # List of virtualised compute hypervisors in this Ansible play batch.
+    virt_computes_in_batch: >-
+      {{ groups[nova_cell_compute_group] |
+         intersect(ansible_play_batch) |
+         list }}
+    # List of iroinc compute hosts in this Ansible play batch.
+    ironic_computes_in_batch: >-
+      {{ (groups[nova_cell_compute_ironic_group] |
+          intersect(ansible_play_batch) |
+          list)
+         if nova_cell_services['nova-compute-ironic'].enabled | bool else [] }}
+    all_computes_in_batch: "{{ virt_computes_in_batch + ironic_computes_in_batch }}"
+  when:
+    # Run discovery when one or more compute hosts are in the Ansible batch,
+    # and there is a cell conductor in the inventory to delegate to.
+    - all_computes_in_batch | length > 0
+    - inventory_hostname == all_computes_in_batch[0]
+    - groups[nova_cell_conductor_group] | length > 0
diff --git a/ansible/roles/nova-cell/tasks/discover_computes.yml b/ansible/roles/nova-cell/tasks/discover_computes.yml
index fbdf81011ac25869323c93833d7dd3fafd4b21f3..1f0122ad8f290a33cfb832757ffaacdc7d9b74fc 100644
--- a/ansible/roles/nova-cell/tasks/discover_computes.yml
+++ b/ansible/roles/nova-cell/tasks/discover_computes.yml
@@ -9,22 +9,19 @@
     # is similar to what nova uses internally as its default for the
     # [DEFAULT] host config option.
     virt_compute_service_hosts: >-
-      {{ groups[nova_cell_compute_group] |
-         intersect(ansible_play_batch) |
+      {{ virt_computes_in_batch |
          map('extract', hostvars, 'ansible_nodename') |
          list }}
     # For ironic, use {{ansible_hostname}}-ironic since this is what we
     # configure for [DEFAULT] host in nova.conf.
     ironic_compute_service_hosts: >-
-      {{ (groups[nova_cell_compute_ironic_group] |
-          intersect(ansible_play_batch) |
-          map('extract', hostvars, 'ansible_hostname') |
-          map('regex_replace', '^(.*)$', '\1-ironic') |
-          list)
-         if nova_cell_services['nova-compute-ironic'].enabled | bool else [] }}
+      {{ ironic_computes_in_batch |
+         map('extract', hostvars, 'ansible_hostname') |
+         map('regex_replace', '^(.*)$', '\1-ironic') |
+         list }}
   set_fact:
     expected_compute_service_hosts: "{{ virt_compute_service_hosts + ironic_compute_service_hosts }}"
-  when: inventory_hostname == groups[nova_cell_conductor_group][0] | default(None)
+  delegate_to: "{{ groups[nova_cell_conductor_group][0] }}"
 
 - name: Waiting for nova-compute services to register themselves
   become: true
@@ -60,17 +57,17 @@
        map(attribute='Host') |
        list)
       is superset(expected_compute_service_hosts)
-  when: inventory_hostname == groups[nova_cell_conductor_group][0] | default(None)
+  delegate_to: "{{ groups[nova_cell_conductor_group][0] }}"
 
 - import_tasks: get_cell_settings.yml
+  delegate_to: "{{ groups[nova_cell_conductor_group][0] }}"
 
 - name: Fail if cell settings not found
   fail:
     msg: >-
       Unable to find settings for {{ nova_cell_name or 'the default cell' }}.
-  when:
-    - inventory_hostname == groups[nova_cell_conductor_group][0] | default(None)
-    - not nova_cell_settings
+  when: not nova_cell_settings
+  delegate_to: "{{ groups[nova_cell_conductor_group][0] }}"
 
 # TODO(yoctozepto): no need to do --by-service if ironic not used
 - name: Discover nova hosts
@@ -78,4 +75,4 @@
   command: >
     docker exec nova_conductor nova-manage cell_v2 discover_hosts --by-service --cell_uuid {{ nova_cell_settings.cell_uuid }}
   changed_when: False
-  when: inventory_hostname == groups[nova_cell_conductor_group][0] | default(None)
+  delegate_to: "{{ groups[nova_cell_conductor_group][0] }}"
diff --git a/ansible/roles/nova-cell/tasks/get_cell_settings.yml b/ansible/roles/nova-cell/tasks/get_cell_settings.yml
index ff92c54661a53902e36dbe8e6d210e128d211e65..120b515ca14fe0514a84fe9c2b94a513e6893ad5 100644
--- a/ansible/roles/nova-cell/tasks/get_cell_settings.yml
+++ b/ansible/roles/nova-cell/tasks/get_cell_settings.yml
@@ -18,11 +18,9 @@
   changed_when: false
   failed_when:
     - existing_cells_list.rc != 0
-  when: inventory_hostname == groups[nova_conductor.group][0] | default(None)
 
 - name: Extract current cell settings from list
   vars:
     nova_conductor: "{{ nova_cell_services['nova-conductor'] }}"
   set_fact:
     nova_cell_settings: "{{ existing_cells_list | extract_cell(nova_cell_name) }}"
-  when: inventory_hostname == groups[nova_conductor.group][0] | default(None)
diff --git a/releasenotes/notes/fix-nova-compute-scale-out-ae5245449cff216d.yaml b/releasenotes/notes/fix-nova-compute-scale-out-ae5245449cff216d.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8d9106dbf47499ecd70a30095481e18af2ce7529
--- /dev/null
+++ b/releasenotes/notes/fix-nova-compute-scale-out-ae5245449cff216d.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    Fixes an issue with Nova when deploying new compute hosts using
+    ``--limit``.  `LP#1869371
+    <https://bugs.launchpad.net/kolla-ansible/+bug/1869371>`__.