diff --git a/ansible/roles/ceilometer/tasks/precheck.yml b/ansible/roles/ceilometer/tasks/precheck.yml
index 224cc2a50b..5f45ba3c32 100644
--- a/ansible/roles/ceilometer/tasks/precheck.yml
+++ b/ansible/roles/ceilometer/tasks/precheck.yml
@@ -14,3 +14,12 @@
   when:
     - container_facts['ceilometer_api'] is not defined
     - inventory_hostname in groups['ceilometer-api']
+
+- name: Checking mongodb backend for ceilometer
+  run_once: True
+  local_action: fail msg="ceilometer_database_type set to 'mongodb' but mongodb is not enabled"
+  changed_when: false
+  when:
+    - enable_ceilometer | bool
+    - not enable_mongodb | bool
+    - ceilometer_database_type == "mongodb"
diff --git a/ansible/roles/cinder/tasks/precheck.yml b/ansible/roles/cinder/tasks/precheck.yml
index 6e44a2c799..0a8b8d81ef 100644
--- a/ansible/roles/cinder/tasks/precheck.yml
+++ b/ansible/roles/cinder/tasks/precheck.yml
@@ -14,3 +14,13 @@
   when:
     - container_facts['cinder_api'] is not defined
     - inventory_hostname in groups['cinder-api']
+
+- name: Checking LVM volume group exists for Cinder
+  command: "vgs {{ cinder_volume_group }}"
+  register: result
+  changed_when: false
+  failed_when: result | failed
+  when:
+    - enable_cinder | bool
+    - enable_cinder_backend_lvm | bool
+    - inventory_hostname in groups['cinder-volume']
diff --git a/ansible/roles/glance/tasks/precheck.yml b/ansible/roles/glance/tasks/precheck.yml
index 117912b753..9c6e032733 100644
--- a/ansible/roles/glance/tasks/precheck.yml
+++ b/ansible/roles/glance/tasks/precheck.yml
@@ -1,7 +1,7 @@
 ---
 - name: Get container facts
   kolla_container_facts:
-    name: "{{ glance_services.keys() }}"
+    name: "{{ glance_services.values()|map(attribute='container_name')|list }}"
   register: container_facts
 
 - name: Checking free port for Glance API
diff --git a/ansible/roles/haproxy/tasks/precheck.yml b/ansible/roles/haproxy/tasks/precheck.yml
index 20779bb128..f15384f056 100644
--- a/ansible/roles/haproxy/tasks/precheck.yml
+++ b/ansible/roles/haproxy/tasks/precheck.yml
@@ -1,9 +1,74 @@
 ---
 - name: Get container facts
   kolla_container_facts:
-    name: haproxy
+    name:
+      - haproxy
+      - keepalived
   register: container_facts
 
+- name: Clearing temp kolla_keepalived_running file
+  local_action: file path=/tmp/kolla_keepalived_running state=absent
+  changed_when: False
+  always_run: True
+
+- name: Create empty temp kolla_keepalived_running file
+  local_action: copy content=None dest=/tmp/kolla_keepalived_running mode=0644
+  changed_when: False
+  always_run: True
+
+- name: Getting hosts who is running keepalived
+  local_action: copy content={{ ansible_hostname }} dest=/tmp/kolla_keepalived_running mode=0644
+  changed_when: False
+  always_run: True
+  when:
+    - inventory_hostname in groups['haproxy']
+    - container_facts['keepalived'] is defined
+    - enable_haproxy | bool
+
+- name: Registering host running keepalived
+  set_fact:
+    host_running_keepalived: "{{ lookup('file', '/tmp/kolla_keepalived_running') }}"
+
+- name: Clearing temp kolla_keepalived_running file
+  local_action: file path=/tmp/kolla_keepalived_running state=absent
+  changed_when: False
+  always_run: True
+
+- name: Checking if kolla_internal_vip_address and kolla_external_vip_address are not pingable from any node
+  command: ping -c 3 {{ item }}
+  register: ping_output
+  changed_when: false
+  failed_when: ping_output.rc != 1
+  with_items:
+    - "{{ kolla_internal_vip_address }}"
+    - "{{ kolla_external_vip_address }}"
+  when:
+    - "host_running_keepalived == 'None'"
+    - enable_haproxy | bool
+
+- name: Checking free port for HAProxy stats
+  wait_for:
+    host: "{{ kolla_internal_vip_address }}"
+    port: "{{ haproxy_stats_port }}"
+    connect_timeout: 1
+    state: stopped
+  when:
+    - enable_haproxy | bool
+    - container_facts['haproxy'] is not defined
+    - inventory_hostname in groups['haproxy']
+
+- name: Checking if kolla_internal_vip_address is in the same network as api_interface on all nodes
+  command: ip -4 -o addr show dev {{ api_interface }}
+  register: ip_addr_output
+  changed_when: false
+  failed_when: >-
+    '169.254.' not in kolla_internal_vip_address and
+    kolla_internal_vip_address | ipaddr(ip_addr_output.stdout.split()[3]) is none
+  when:
+    - enable_haproxy | bool
+    - container_facts['keepalived'] is not defined
+    - inventory_hostname in groups['haproxy']
+
 - name: Getting haproxy stat
   shell: echo "show stat" | docker exec -i haproxy socat unix-connect:/var/lib/kolla/haproxy/haproxy.sock stdio
   register: haproxy_stat_shell
@@ -252,6 +317,7 @@
     connect_timeout: 1
     state: stopped
   when:
+    - haproxy_enable_external_vip | bool
     - enable_keystone | bool
     - inventory_hostname in groups['haproxy']
     - "{{ 'keystone_external' not in haproxy_stat }}"
diff --git a/ansible/roles/keystone/tasks/precheck.yml b/ansible/roles/keystone/tasks/precheck.yml
index 7b653a3ead..31f8c50802 100644
--- a/ansible/roles/keystone/tasks/precheck.yml
+++ b/ansible/roles/keystone/tasks/precheck.yml
@@ -24,3 +24,10 @@
   when:
     - container_facts['keystone'] is not defined
     - inventory_hostname in groups['keystone']
+
+- name: Checking fernet_token_expiry in globals.yml. Update fernet_token_expiry to allowed value if this task fails
+  run_once: true
+  local_action: command awk '/^fernet_token_expiry/ { print $2 }' "{{ CONFIG_DIR | default('/etc/kolla') }}/globals.yml"
+  register: result
+  changed_when: false
+  failed_when: result.stdout | regex_replace('(60|120|180|240|300|360|600|720|900|1200|1800|3600|7200|10800|14400|21600|28800|43200|86400|604800)', '') | search(".+")
diff --git a/ansible/roles/neutron/tasks/precheck.yml b/ansible/roles/neutron/tasks/precheck.yml
index fd696dfb1c..6933c5203c 100644
--- a/ansible/roles/neutron/tasks/precheck.yml
+++ b/ansible/roles/neutron/tasks/precheck.yml
@@ -14,3 +14,36 @@
   when:
     - container_facts['neutron_server'] is not defined
     - inventory_hostname in groups['neutron-server']
+
+- name: Checking number of network agents
+  local_action: fail msg="Number of network agents are less than two when enabling agent ha"
+  changed_when: false
+  when:
+    - enable_neutron_agent_ha | bool
+    - groups['neutron-dhcp-agent'] | length < 2
+      or groups['neutron-l3-agent'] | length < 2
+
+# When MountFlags is set to shared, a signal bit configured on 20th bit of a number
+# We need to check the 20th bit. 2^20 = 1048576. So we are validating against it.
+- name: Checking if 'MountFlags' for docker service is set to 'shared'
+  command: systemctl show docker
+  register: result
+  changed_when: false
+  failed_when: result.stdout.find('MountFlags=1048576') == -1
+  when:
+    - (inventory_hostname in groups['neutron-dhcp-agent']
+       or inventory_hostname in groups['neutron-l3-agent']
+       or inventory_hostname in groups['neutron-metadata-agent'])
+    - ansible_os_family == 'RedHat'
+       or (ansible_distribution == 'Ubuntu' and ansible_distribution_version > '14.04')
+
+- name: Checking if '/run' mount flag is set to 'shared'
+  command: awk '$5 == "/run" {print $7}' /proc/self/mountinfo
+  register: result
+  changed_when: false
+  failed_when: result.stdout.find('shared') == -1
+  when:
+    - (inventory_hostname in groups['neutron-dhcp-agent']
+       or inventory_hostname in groups['neutron-l3-agent']
+       or inventory_hostname in groups['neutron-metadata-agent'])
+    - ansible_distribution == 'Ubuntu' and ansible_distribution_version == '14.04'
diff --git a/ansible/roles/nova/tasks/precheck.yml b/ansible/roles/nova/tasks/precheck.yml
index a1f5004210..8ef66f68f1 100644
--- a/ansible/roles/nova/tasks/precheck.yml
+++ b/ansible/roles/nova/tasks/precheck.yml
@@ -6,6 +6,7 @@
       - nova_novncproxy
       - nova_serialproxy
       - nova_spicehtml5proxy
+      - nova_libvirt
       - placement_api
   register: container_facts
 
@@ -86,3 +87,13 @@
     - container_facts['placement_api'] is not defined
     - inventory_hostname in groups[placement_api.group]
     - placement_api.enabled | bool
+
+- name: Checking that libvirt is not running
+  vars:
+    nova_libvirt: "{{ nova_services['nova-libvirt'] }}"
+  stat: path=/var/run/libvirt/libvirt-sock
+  register: result
+  failed_when: result.stat.exists
+  when:
+    - container_facts['nova_libvirt'] is not defined
+    - inventory_hostname in groups[nova_libvirt.group]
diff --git a/ansible/roles/prechecks/tasks/port_checks.yml b/ansible/roles/prechecks/tasks/port_checks.yml
index d06583ee51..817f703a87 100644
--- a/ansible/roles/prechecks/tasks/port_checks.yml
+++ b/ansible/roles/prechecks/tasks/port_checks.yml
@@ -14,41 +14,3 @@
 - name: Checking the api_interface ip address configuration
   fail: "msg='Please check the api_interface settings - interface {{ api_interface }} ip address problem'"
   when: hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] is not defined
-
-- name: Checking if kolla_internal_vip_address and kolla_external_vip_address are not pingable from any node
-  command: ping -c 3 {{ item }}
-  register: ping_output
-  changed_when: false
-  with_items:
-    - "{{ kolla_internal_vip_address }}"
-    - "{{ kolla_external_vip_address }}"
-  failed_when: ping_output.rc != 1
-  when: enable_haproxy | bool
-
-- name: Checking if kolla_internal_vip_address is in the same network as api_interface on all nodes
-  command: ip -4 -o addr show dev {{ api_interface }}
-  register: ip_addr_output
-  changed_when: false
-  failed_when: "'169.254.' not in kolla_internal_vip_address and \
-                kolla_internal_vip_address | ipaddr(ip_addr_output.stdout.split()[3]) is none"
-  when: enable_haproxy | bool
-
-- name: Checking free port for HAProxy stats
-  wait_for:
-    host: "{{ kolla_internal_vip_address }}"
-    port: "{{ haproxy_stats_port }}"
-    connect_timeout: 1
-    state: stopped
-  when:
-    - enable_haproxy | bool
-    - inventory_hostname in groups['haproxy']
-
-- name: Checking free port for Rsync
-  wait_for:
-    host: "{{ hostvars[inventory_hostname]['ansible_' + storage_interface]['ipv4']['address'] }}"
-    port: "873"
-    connect_timeout: 1
-    state: stopped
-  when:
-    - inventory_hostname in groups['swift-object-server']
-    - enable_swift | bool
diff --git a/ansible/roles/prechecks/tasks/precheck.yml b/ansible/roles/prechecks/tasks/precheck.yml
deleted file mode 100644
index ed97d539c0..0000000000
--- a/ansible/roles/prechecks/tasks/precheck.yml
+++ /dev/null
@@ -1 +0,0 @@
----
diff --git a/ansible/roles/prechecks/tasks/service_checks.yml b/ansible/roles/prechecks/tasks/service_checks.yml
index f313948fe7..79614881e7 100644
--- a/ansible/roles/prechecks/tasks/service_checks.yml
+++ b/ansible/roles/prechecks/tasks/service_checks.yml
@@ -1,10 +1,4 @@
 ---
-- name: Checking that libvirt is not running
-  stat: path=/var/run/libvirt/libvirt-sock
-  register: result
-  failed_when: result.stat.exists
-  when: inventory_hostname in groups['compute']
-
 - name: Checking Docker version
   command: docker version
   register: result
@@ -12,67 +6,8 @@
   failed_when: result | failed
                or (result.stdout | from_yaml).Server.Version | regex_replace('(\\d+\\.\\d+\\.\\d+).*', '\\1') | version_compare(docker_version_min, '<')
 
-# When MountFlags is set to shared, a signal bit configured on 20th bit of a number
-# We need to check the 20th bit. 2^20 = 1048576. So we are validating against it.
-- name: Checking if 'MountFlags' for docker service is set to 'shared'
-  command: systemctl show docker
-  register: result
-  changed_when: false
-  failed_when: result.stdout.find('MountFlags=1048576') == -1
-  when:
-    - (inventory_hostname in groups['neutron-dhcp-agent']
-       or inventory_hostname in groups['neutron-l3-agent']
-       or inventory_hostname in groups['neutron-metadata-agent'])
-    - ansible_os_family == 'RedHat'
-       or (ansible_distribution == 'Ubuntu' and ansible_distribution_version > '14.04')
-
-- name: Checking if '/run' mount flag is set to 'shared'
-  command: awk '$5 == "/run" {print $7}' /proc/self/mountinfo
-  register: result
-  changed_when: false
-  failed_when: result.stdout.find('shared') == -1
-  when:
-    - (inventory_hostname in groups['neutron-dhcp-agent']
-       or inventory_hostname in groups['neutron-l3-agent']
-       or inventory_hostname in groups['neutron-metadata-agent'])
-    - ansible_distribution == 'Ubuntu' and ansible_distribution_version == '14.04'
-
 - name: Checking empty passwords in passwords.yml. Run kolla-genpwd if this task fails
   local_action: command grep '^[^#].*:\s*$' "{{ CONFIG_DIR | default('/etc/kolla') }}/passwords.yml"
   register: result
   changed_when: false
   failed_when: result.stdout | regex_replace('(.*ssh_key.*)', '') | search(":")
-
-- name: Checking fernet_token_expiry in globals.yml. Update fernet_token_expiry to allowed value if this task fails
-  run_once: true
-  local_action: command awk '/^fernet_token_expiry/ { print $2 }' "{{ CONFIG_DIR | default('/etc/kolla') }}/globals.yml"
-  register: result
-  changed_when: false
-  failed_when: result.stdout | regex_replace('(60|120|180|240|300|360|600|720|900|1200|1800|3600|7200|10800|14400|21600|28800|43200|86400|604800)', '') | search(".+")
-
-- name: Checking number of network agents
-  local_action: fail msg="Number of network agents are less than two when enabling agent ha"
-  changed_when: false
-  when:
-    - enable_neutron_agent_ha | bool
-    - groups['neutron-dhcp-agent'] | length < 2
-      or groups['neutron-l3-agent'] | length < 2
-
-- name: Checking mongodb backend for ceilometer
-  run_once: True
-  local_action: fail msg="ceilometer_database_type set to 'mongodb' but mongodb is not enabled"
-  changed_when: false
-  when:
-    - enable_ceilometer | bool
-    - not enable_mongodb | bool
-    - ceilometer_database_type == "mongodb"
-
-- name: Checking LVM volume group exists for Cinder
-  command: "vgs {{ cinder_volume_group }}"
-  register: result
-  changed_when: false
-  failed_when: result | failed
-  when:
-    - enable_cinder | bool
-    - enable_cinder_backend_lvm | bool
-    - inventory_hostname in groups['cinder-volume']
diff --git a/ansible/roles/swift/tasks/precheck.yml b/ansible/roles/swift/tasks/precheck.yml
index 2c0a649743..13c018b6ee 100644
--- a/ansible/roles/swift/tasks/precheck.yml
+++ b/ansible/roles/swift/tasks/precheck.yml
@@ -38,6 +38,16 @@
     - container_facts['swift_object_server'] is not defined
     - inventory_hostname in groups['swift-object-server']
 
+- name: Checking free port for Rsync
+  wait_for:
+    host: "{{ hostvars[inventory_hostname]['ansible_' + storage_interface]['ipv4']['address'] }}"
+    port: "873"
+    connect_timeout: 1
+    state: stopped
+  when:
+    - container_facts['swift_object_server'] is not defined
+    - inventory_hostname in groups['swift-object-server']
+
 - name: Checking free port for Swift Proxy Server
   wait_for:
     host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}"