diff --git a/ansible/roles/elasticsearch/tasks/config-host.yml b/ansible/roles/elasticsearch/tasks/config-host.yml
new file mode 100644
index 0000000000000000000000000000000000000000..638721a43924111a77102eeb2890f0d6e2355ef2
--- /dev/null
+++ b/ansible/roles/elasticsearch/tasks/config-host.yml
@@ -0,0 +1,12 @@
+---
+- name: Setting sysctl values
+  become: true
+  sysctl:
+    name: "{{ item.name }}"
+    value: "{{ item.value }}"
+    sysctl_set: yes
+  with_items:
+    - { name: "vm.max_map_count", value: 262144}
+  when:
+    - set_sysctl | bool
+    - inventory_hostname in groups['elasticsearch']
diff --git a/ansible/roles/elasticsearch/tasks/config.yml b/ansible/roles/elasticsearch/tasks/config.yml
index 3410732838e93f425b00176ba0c867959c907262..8ba746cfb786dfbc64f42f22adfb22d922a08317 100644
--- a/ansible/roles/elasticsearch/tasks/config.yml
+++ b/ansible/roles/elasticsearch/tasks/config.yml
@@ -1,13 +1,4 @@
 ---
-- name: Setting sysctl values
-  become: true
-  sysctl: name={{ item.name }} value={{ item.value }} sysctl_set=yes
-  with_items:
-    - { name: "vm.max_map_count", value: 262144}
-  when:
-    - set_sysctl | bool
-    - inventory_hostname in groups['elasticsearch']
-
 - name: Ensuring config directories exist
   file:
     path: "{{ node_config_directory }}/{{ item.key }}"
diff --git a/ansible/roles/elasticsearch/tasks/deploy.yml b/ansible/roles/elasticsearch/tasks/deploy.yml
index 375dcad19b188093ce043545f95307dcaab172dd..47683248986b68ab1374c7ef990e66fe3bfddfe8 100644
--- a/ansible/roles/elasticsearch/tasks/deploy.yml
+++ b/ansible/roles/elasticsearch/tasks/deploy.yml
@@ -1,4 +1,6 @@
 ---
+- include_tasks: config-host.yml
+
 - include_tasks: config.yml
 
 - name: Flush handlers
diff --git a/ansible/roles/haproxy/tasks/config-host.yml b/ansible/roles/haproxy/tasks/config-host.yml
new file mode 100644
index 0000000000000000000000000000000000000000..eb5bb4910279324a995a6a47295e638d7af1f888
--- /dev/null
+++ b/ansible/roles/haproxy/tasks/config-host.yml
@@ -0,0 +1,20 @@
+---
+- name: Setting sysctl values
+  sysctl:
+    name: "{{ item.name }}"
+    value: "{{ item.value }}"
+    sysctl_set: yes
+  become: true
+  with_items:
+    - { name: "net.ipv4.ip_nonlocal_bind", value: 1}
+    - { name: "net.ipv6.ip_nonlocal_bind", value: 1}
+    - { name: "net.unix.max_dgram_qlen", value: 128}
+  when:
+    - set_sysctl | bool
+
+- name: Load and persist keepalived module
+  import_role:
+    name: module-load
+  vars:
+    modules:
+      - {'name': ip_vs }
diff --git a/ansible/roles/haproxy/tasks/config.yml b/ansible/roles/haproxy/tasks/config.yml
index fd215a32d08f57733a4dbd165000f22588f08c9f..99ea810fd21be9a73031fc17281b5cea96a1e174 100644
--- a/ansible/roles/haproxy/tasks/config.yml
+++ b/ansible/roles/haproxy/tasks/config.yml
@@ -1,14 +1,4 @@
 ---
-- name: Setting sysctl values
-  sysctl: name={{ item.name }} value={{ item.value }} sysctl_set=yes
-  become: true
-  with_items:
-    - { name: "net.ipv4.ip_nonlocal_bind", value: 1}
-    - { name: "net.ipv6.ip_nonlocal_bind", value: 1}
-    - { name: "net.unix.max_dgram_qlen", value: 128}
-  when:
-    - set_sysctl | bool
-
 - name: Ensuring config directories exist
   file:
     path: "{{ node_config_directory }}/{{ item.key }}"
@@ -83,13 +73,6 @@
   notify:
     - Restart haproxy container
 
-- name: Load and persist keepalived module
-  import_role:
-    name: module-load
-  vars:
-    modules:
-      - {'name': ip_vs }
-
 - name: Copying over keepalived.conf
   vars:
     service: "{{ haproxy_services['keepalived'] }}"
diff --git a/ansible/roles/haproxy/tasks/deploy.yml b/ansible/roles/haproxy/tasks/deploy.yml
index 375dcad19b188093ce043545f95307dcaab172dd..47683248986b68ab1374c7ef990e66fe3bfddfe8 100644
--- a/ansible/roles/haproxy/tasks/deploy.yml
+++ b/ansible/roles/haproxy/tasks/deploy.yml
@@ -1,4 +1,6 @@
 ---
+- include_tasks: config-host.yml
+
 - include_tasks: config.yml
 
 - name: Flush handlers
diff --git a/ansible/roles/ironic/tasks/config-host.yml b/ansible/roles/ironic/tasks/config-host.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6181f7ccd7b623f0809ba4d1248765ff6cc4d50f
--- /dev/null
+++ b/ansible/roles/ironic/tasks/config-host.yml
@@ -0,0 +1,8 @@
+---
+- name: Load and persist iscsi_tcp module
+  import_role:
+    name: module-load
+  vars:
+    modules:
+      - {'name': iscsi_tcp}
+  when: inventory_hostname in groups['ironic-conductor']
diff --git a/ansible/roles/ironic/tasks/config.yml b/ansible/roles/ironic/tasks/config.yml
index bcbd4bf2861cee86d83a170a7779153ec032ffaa..e359e4791741fc93d56aca325493e8b40be73d70 100644
--- a/ansible/roles/ironic/tasks/config.yml
+++ b/ansible/roles/ironic/tasks/config.yml
@@ -1,11 +1,4 @@
 ---
-- name: Load and persist iscsi_tcp module
-  import_role:
-    name: module-load
-  vars:
-    modules:
-      - {'name': iscsi_tcp}
-
 - name: Ensuring config directories exist
   file:
     path: "{{ node_config_directory }}/{{ item.key }}"
diff --git a/ansible/roles/ironic/tasks/deploy.yml b/ansible/roles/ironic/tasks/deploy.yml
index f4c0d8ca648808059f13f7b837ea3fd14cdccc53..4dddfa9b786fbdac1ac9bee297408a2f4896826c 100644
--- a/ansible/roles/ironic/tasks/deploy.yml
+++ b/ansible/roles/ironic/tasks/deploy.yml
@@ -4,6 +4,8 @@
         (inventory_hostname in groups['ironic-api'] or
         inventory_hostname in groups['ironic-inspector'])
 
+- include_tasks: config-host.yml
+
 - include_tasks: config.yml
   when: inventory_hostname in groups['ironic-api'] or
         inventory_hostname in groups['ironic-conductor'] or
diff --git a/ansible/roles/iscsi/tasks/config-host.yml b/ansible/roles/iscsi/tasks/config-host.yml
new file mode 100644
index 0000000000000000000000000000000000000000..302c39f46fe7f37f47ae3fda4a9301271ff02325
--- /dev/null
+++ b/ansible/roles/iscsi/tasks/config-host.yml
@@ -0,0 +1,10 @@
+---
+- name: Load and persist configfs module
+  import_role:
+    name: module-load
+  vars:
+    modules:
+      - name: configfs
+  when:
+    - inventory_hostname in groups[iscsi_services.iscsid.group]
+    - iscsi_services.iscsid.enabled | bool
diff --git a/ansible/roles/iscsi/tasks/config.yml b/ansible/roles/iscsi/tasks/config.yml
index 6bda5f7012eaab001d95d01a9ccceaaa5883e700..e884678ec8ddbc2ecb9db8329f33575339a91171 100644
--- a/ansible/roles/iscsi/tasks/config.yml
+++ b/ansible/roles/iscsi/tasks/config.yml
@@ -1,14 +1,4 @@
 ---
-- name: Load and persist configfs module
-  import_role:
-    name: module-load
-  vars:
-    modules:
-      - name: configfs
-  when:
-    - inventory_hostname in groups[iscsi_services.iscsid.group]
-    - iscsi_services.iscsid.enabled | bool
-
 - name: Ensuring config directories exist
   file:
     path: "{{ node_config_directory }}/{{ item.key }}"
diff --git a/ansible/roles/iscsi/tasks/deploy.yml b/ansible/roles/iscsi/tasks/deploy.yml
index 375dcad19b188093ce043545f95307dcaab172dd..47683248986b68ab1374c7ef990e66fe3bfddfe8 100644
--- a/ansible/roles/iscsi/tasks/deploy.yml
+++ b/ansible/roles/iscsi/tasks/deploy.yml
@@ -1,4 +1,6 @@
 ---
+- include_tasks: config-host.yml
+
 - include_tasks: config.yml
 
 - name: Flush handlers
diff --git a/ansible/roles/multipathd/tasks/config-host.yml b/ansible/roles/multipathd/tasks/config-host.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7c646d7d0dcc0045cd8856a8213a6befa91a2e18
--- /dev/null
+++ b/ansible/roles/multipathd/tasks/config-host.yml
@@ -0,0 +1,7 @@
+---
+- name: Load and persist dm-multipath module
+  import_role:
+    name: module-load
+  vars:
+    modules:
+      - {'name': dm-multipath}
diff --git a/ansible/roles/multipathd/tasks/config.yml b/ansible/roles/multipathd/tasks/config.yml
index b11ea424e30d5ace19dd8c80beba4189e511b1a5..601cdbf485539d2d1591f926f0c166c30b0d6041 100644
--- a/ansible/roles/multipathd/tasks/config.yml
+++ b/ansible/roles/multipathd/tasks/config.yml
@@ -1,11 +1,4 @@
 ---
-- name: Load and persist dm-multipath module
-  import_role:
-    name: module-load
-  vars:
-    modules:
-      - {'name': dm-multipath}
-
 - name: Ensuring config directories exist
   file:
     path: "{{ node_config_directory }}/{{ item.key }}"
diff --git a/ansible/roles/multipathd/tasks/deploy.yml b/ansible/roles/multipathd/tasks/deploy.yml
index 375dcad19b188093ce043545f95307dcaab172dd..47683248986b68ab1374c7ef990e66fe3bfddfe8 100644
--- a/ansible/roles/multipathd/tasks/deploy.yml
+++ b/ansible/roles/multipathd/tasks/deploy.yml
@@ -1,4 +1,6 @@
 ---
+- include_tasks: config-host.yml
+
 - include_tasks: config.yml
 
 - name: Flush handlers
diff --git a/ansible/roles/neutron/tasks/config-host.yml b/ansible/roles/neutron/tasks/config-host.yml
new file mode 100644
index 0000000000000000000000000000000000000000..59db51add869a1df32094b81ef196776ce37be35
--- /dev/null
+++ b/ansible/roles/neutron/tasks/config-host.yml
@@ -0,0 +1,30 @@
+---
+- name: Load and persist ip6_tables module
+  include_role:
+    name: module-load
+  vars:
+    modules:
+      - {'name': ip6_tables}
+  when: neutron_services | select_services_enabled_and_mapped_to_host | list | intersect([ "neutron-l3-agent", "neutron-linuxbridge-agent", "neutron-openvswitch-agent" ]) | list | length > 0
+
+- name: Setting sysctl values
+  become: true
+  vars:
+    neutron_l3_agent: "{{ neutron_services['neutron-l3-agent'] }}"
+  sysctl:
+    name: "{{ item.name }}"
+    value: "{{ item.value }}"
+    sysctl_set: yes
+  with_items:
+    - { name: "net.ipv4.ip_forward", value: 1}
+    - { name: "net.ipv4.conf.all.rp_filter", value: "{{ neutron_l3_agent_host_rp_filter_mode }}"}
+    - { name: "net.ipv4.conf.default.rp_filter", value: "{{ neutron_l3_agent_host_rp_filter_mode }}"}
+    - { name: "net.ipv4.neigh.default.gc_thresh1", value: "{{ neutron_l3_agent_host_ipv4_neigh_gc_thresh1 }}"}
+    - { name: "net.ipv4.neigh.default.gc_thresh2", value: "{{ neutron_l3_agent_host_ipv4_neigh_gc_thresh2 }}"}
+    - { name: "net.ipv4.neigh.default.gc_thresh3", value: "{{ neutron_l3_agent_host_ipv4_neigh_gc_thresh3 }}"}
+    - { name: "net.ipv6.neigh.default.gc_thresh1", value: "{{ neutron_l3_agent_host_ipv6_neigh_gc_thresh1 }}"}
+    - { name: "net.ipv6.neigh.default.gc_thresh2", value: "{{ neutron_l3_agent_host_ipv6_neigh_gc_thresh2 }}"}
+    - { name: "net.ipv6.neigh.default.gc_thresh3", value: "{{ neutron_l3_agent_host_ipv6_neigh_gc_thresh3 }}"}
+  when:
+    - set_sysctl | bool
+    - (neutron_l3_agent.enabled | bool and neutron_l3_agent.host_in_groups | bool)
diff --git a/ansible/roles/neutron/tasks/config.yml b/ansible/roles/neutron/tasks/config.yml
index 107daa4165003db502713564c7165786cd35b990..bf8b3bcb4db567c32f7d8af352c567b8609ba60c 100644
--- a/ansible/roles/neutron/tasks/config.yml
+++ b/ansible/roles/neutron/tasks/config.yml
@@ -1,31 +1,4 @@
 ---
-- name: Load and persist ip6_tables module
-  include_role:
-    name: module-load
-  vars:
-    modules:
-      - {'name': ip6_tables}
-  when: neutron_services | select_services_enabled_and_mapped_to_host | list | intersect([ "neutron-l3-agent", "neutron-linuxbridge-agent", "neutron-openvswitch-agent" ]) | list | length > 0
-
-- name: Setting sysctl values
-  become: true
-  vars:
-    neutron_l3_agent: "{{ neutron_services['neutron-l3-agent'] }}"
-  sysctl: name={{ item.name }} value={{ item.value }} sysctl_set=yes
-  with_items:
-    - { name: "net.ipv4.ip_forward", value: 1}
-    - { name: "net.ipv4.conf.all.rp_filter", value: "{{ neutron_l3_agent_host_rp_filter_mode }}"}
-    - { name: "net.ipv4.conf.default.rp_filter", value: "{{ neutron_l3_agent_host_rp_filter_mode }}"}
-    - { name: "net.ipv4.neigh.default.gc_thresh1", value: "{{ neutron_l3_agent_host_ipv4_neigh_gc_thresh1 }}"}
-    - { name: "net.ipv4.neigh.default.gc_thresh2", value: "{{ neutron_l3_agent_host_ipv4_neigh_gc_thresh2 }}"}
-    - { name: "net.ipv4.neigh.default.gc_thresh3", value: "{{ neutron_l3_agent_host_ipv4_neigh_gc_thresh3 }}"}
-    - { name: "net.ipv6.neigh.default.gc_thresh1", value: "{{ neutron_l3_agent_host_ipv6_neigh_gc_thresh1 }}"}
-    - { name: "net.ipv6.neigh.default.gc_thresh2", value: "{{ neutron_l3_agent_host_ipv6_neigh_gc_thresh2 }}"}
-    - { name: "net.ipv6.neigh.default.gc_thresh3", value: "{{ neutron_l3_agent_host_ipv6_neigh_gc_thresh3 }}"}
-  when:
-    - set_sysctl | bool
-    - (neutron_l3_agent.enabled | bool and neutron_l3_agent.host_in_groups | bool)
-
 - name: Ensuring config directories exist
   become: true
   file:
diff --git a/ansible/roles/neutron/tasks/deploy.yml b/ansible/roles/neutron/tasks/deploy.yml
index 6662124c79886bc80285b58c5ea69e8e14f642ab..86aa7c1cc390020240b747817ac191780003d8b0 100644
--- a/ansible/roles/neutron/tasks/deploy.yml
+++ b/ansible/roles/neutron/tasks/deploy.yml
@@ -5,6 +5,8 @@
 - include_tasks: clone.yml
   when: neutron_dev_mode | bool
 
+- include_tasks: config-host.yml
+
 - include_tasks: config.yml
 
 - include_tasks: config-neutron-fake.yml
diff --git a/ansible/roles/nova-cell/tasks/config-host.yml b/ansible/roles/nova-cell/tasks/config-host.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2737d4ab57d6c27bc44bd9a3680a32b352cbbbc1
--- /dev/null
+++ b/ansible/roles/nova-cell/tasks/config-host.yml
@@ -0,0 +1,15 @@
+---
+- name: Setting sysctl values
+  become: true
+  sysctl:
+    name: "{{ item.name }}"
+    value: "{{ item.value }}"
+    sysctl_set: yes
+  with_items:
+    - { name: "net.bridge.bridge-nf-call-iptables", value: 1}
+    - { name: "net.bridge.bridge-nf-call-ip6tables", value: 1}
+    - { name: "net.ipv4.conf.all.rp_filter", value: "{{ nova_compute_host_rp_filter_mode }}"}
+    - { name: "net.ipv4.conf.default.rp_filter", value: "{{ nova_compute_host_rp_filter_mode }}"}
+  when:
+    - set_sysctl | bool
+    - inventory_hostname in groups[nova_cell_compute_group]
diff --git a/ansible/roles/nova-cell/tasks/config.yml b/ansible/roles/nova-cell/tasks/config.yml
index 04c291fec4fb4cbc52f511772a011371c08e05b2..ca64b96aa5506cbf014be0ea36dcb0cebb2c91ed 100644
--- a/ansible/roles/nova-cell/tasks/config.yml
+++ b/ansible/roles/nova-cell/tasks/config.yml
@@ -1,16 +1,4 @@
 ---
-- name: Setting sysctl values
-  become: true
-  sysctl: name={{ item.name }} value={{ item.value }} sysctl_set=yes
-  with_items:
-    - { name: "net.bridge.bridge-nf-call-iptables", value: 1}
-    - { name: "net.bridge.bridge-nf-call-ip6tables", value: 1}
-    - { name: "net.ipv4.conf.all.rp_filter", value: "{{ nova_compute_host_rp_filter_mode }}"}
-    - { name: "net.ipv4.conf.default.rp_filter", value: "{{ nova_compute_host_rp_filter_mode }}"}
-  when:
-    - set_sysctl | bool
-    - inventory_hostname in groups[nova_cell_compute_group]
-
 - name: Ensuring config directories exist
   become: true
   file:
diff --git a/ansible/roles/nova-cell/tasks/deploy.yml b/ansible/roles/nova-cell/tasks/deploy.yml
index 7e0a9cd222338db4cad5f9d85eead1d1e12ea6ce..37d05f276fb2339932f4e36e41c065a407420c5f 100644
--- a/ansible/roles/nova-cell/tasks/deploy.yml
+++ b/ansible/roles/nova-cell/tasks/deploy.yml
@@ -7,6 +7,8 @@
 - include_tasks: clone.yml
   when: nova_dev_mode | bool
 
+- include_tasks: config-host.yml
+
 - include_tasks: config.yml
 
 - include_tasks: config-nova-fake.yml
diff --git a/ansible/roles/openvswitch/tasks/config-host.yml b/ansible/roles/openvswitch/tasks/config-host.yml
new file mode 100644
index 0000000000000000000000000000000000000000..18dae6a073061da6e5c3f3ab3b871bd827199ec5
--- /dev/null
+++ b/ansible/roles/openvswitch/tasks/config-host.yml
@@ -0,0 +1,7 @@
+---
+- name: Load and persist openvswitch module
+  import_role:
+    name: module-load
+  vars:
+    modules:
+      - {'name': openvswitch}
diff --git a/ansible/roles/openvswitch/tasks/config.yml b/ansible/roles/openvswitch/tasks/config.yml
index 3069071d1bb296ce1e47ccfa95087c27658a0eed..e32c76ec4c47121a91fa1d2bb31622344710b29f 100644
--- a/ansible/roles/openvswitch/tasks/config.yml
+++ b/ansible/roles/openvswitch/tasks/config.yml
@@ -1,11 +1,4 @@
 ---
-- name: Load and persist openvswitch module
-  import_role:
-    name: module-load
-  vars:
-    modules:
-      - {'name': openvswitch}
-
 - name: Ensuring config directories exist
   become: true
   file:
diff --git a/ansible/roles/openvswitch/tasks/deploy.yml b/ansible/roles/openvswitch/tasks/deploy.yml
index 110210a16b37a4124f086e300b7953cc96c2041f..60c9a99024b265a5e4536cc65910e6d7d2ece100 100644
--- a/ansible/roles/openvswitch/tasks/deploy.yml
+++ b/ansible/roles/openvswitch/tasks/deploy.yml
@@ -1,4 +1,6 @@
 ---
+- include_tasks: config-host.yml
+
 - include_tasks: config.yml
 
 - name: Flush Handlers
diff --git a/releasenotes/notes/no-host-config-in-genconfig-7321f0dcfc9d728d.yaml b/releasenotes/notes/no-host-config-in-genconfig-7321f0dcfc9d728d.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9a7214d14ee5d3760defa1a0ee326a2f99b63732
--- /dev/null
+++ b/releasenotes/notes/no-host-config-in-genconfig-7321f0dcfc9d728d.yaml
@@ -0,0 +1,7 @@
+---
+fixes:
+  - |
+    Fixes an issue where host configuration tasks (``sysctl``, loading kernel
+    modules) could be performed during the ``kolla-ansible genconfig`` command.
+    See `bug 1860161 <https://bugs.launchpad.net/kolla-ansible/+bug/1860161>`__
+    for details.