diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml
index d85a7a6d5b..66fcda7c28 100644
--- a/ansible/group_vars/all.yml
+++ b/ansible/group_vars/all.yml
@@ -208,6 +208,7 @@ gnocchi_api_port: "8041"
 grafana_server_port: "3000"
 
 haproxy_stats_port: "1984"
+haproxy_monitor_port: "61313"
 
 heat_api_port: "8004"
 heat_api_cfn_port: "8000"
diff --git a/ansible/inventory/all-in-one b/ansible/inventory/all-in-one
index 1bb26e9226..87bd6ceb0b 100644
--- a/ansible/inventory/all-in-one
+++ b/ansible/inventory/all-in-one
@@ -493,6 +493,12 @@ solum
 [solum-conductor:children]
 solum
 
+[solum-application-deployment:children]
+solum
+
+[solum-image-builder:children]
+solum
+
 # Mistral
 [mistral-api:children]
 mistral
diff --git a/ansible/inventory/multinode b/ansible/inventory/multinode
index 826f6ea6be..77216ca55c 100644
--- a/ansible/inventory/multinode
+++ b/ansible/inventory/multinode
@@ -509,6 +509,12 @@ solum
 [solum-conductor:children]
 solum
 
+[solum-application-deployment:children]
+solum
+
+[solum-image-builder:children]
+solum
+
 # Mistral
 [mistral-api:children]
 mistral
diff --git a/ansible/roles/aodh/defaults/main.yml b/ansible/roles/aodh/defaults/main.yml
index 003d59a044..4fc1993f77 100644
--- a/ansible/roles/aodh/defaults/main.yml
+++ b/ansible/roles/aodh/defaults/main.yml
@@ -14,6 +14,17 @@ aodh_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/aodh/aodh:/var/lib/kolla/venv/lib/python2.7/site-packages/aodh' if aodh_dev_mode | bool else '' }}"
     dimensions: "{{ aodh_api_dimensions }}"
+    haproxy:
+      aodh_api:
+        enabled: "{{ enable_aodh }}"
+        mode: "http"
+        external: false
+        port: "{{ aodh_api_port }}"
+      aodh_api_external:
+        enabled: "{{ enable_aodh }}"
+        mode: "http"
+        external: true
+        port: "{{ aodh_api_port }}"
   aodh-evaluator:
     container_name: aodh_evaluator
     group: aodh-evaluator
diff --git a/ansible/roles/aodh/tasks/loadbalancer.yml b/ansible/roles/aodh/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..2e4ead6dd3
--- /dev/null
+++ b/ansible/roles/aodh/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ aodh_services }}"
+  tags: always
diff --git a/ansible/roles/barbican/defaults/main.yml b/ansible/roles/barbican/defaults/main.yml
index 844c4e63ad..d72d8efec7 100644
--- a/ansible/roles/barbican/defaults/main.yml
+++ b/ansible/roles/barbican/defaults/main.yml
@@ -14,6 +14,17 @@ barbican_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/barbican/barbican:/var/lib/kolla/venv/lib/python2.7/site-packages/barbican' if barbican_dev_mode | bool else '' }}"
     dimensions: "{{ barbican_api_dimensions }}"
+    haproxy:
+      barbican_api:
+        enabled: "{{ enable_barbican }}"
+        mode: "http"
+        external: false
+        port: "{{ barbican_api_port }}"
+      barbican_api_external:
+        enabled: "{{ enable_barbican }}"
+        mode: "http"
+        external: true
+        port: "{{ barbican_api_port }}"
   barbican-keystone-listener:
     container_name: barbican_keystone_listener
     group: barbican-keystone-listener
diff --git a/ansible/roles/barbican/tasks/loadbalancer.yml b/ansible/roles/barbican/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..6a30bf0636
--- /dev/null
+++ b/ansible/roles/barbican/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ barbican_services }}"
+  tags: always
diff --git a/ansible/roles/blazar/defaults/main.yml b/ansible/roles/blazar/defaults/main.yml
index 5dc41af547..2c4271d4b6 100644
--- a/ansible/roles/blazar/defaults/main.yml
+++ b/ansible/roles/blazar/defaults/main.yml
@@ -13,6 +13,17 @@ blazar_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/blazar/blazar:/var/lib/kolla/venv/lib/python2.7/site-packages/blazar' if blazar_dev_mode | bool else '' }}"
     dimensions: "{{ blazar_api_dimensions }}"
+    haproxy:
+      blazar_api:
+        enabled: "{{ enable_blazar }}"
+        mode: "http"
+        external: false
+        port: "{{ blazar_api_port }}"
+      blazar_api_external:
+        enabled: "{{ enable_blazar }}"
+        mode: "http"
+        external: true
+        port: "{{ blazar_api_port }}"
   blazar-manager:
     container_name: blazar_manager
     group: blazar-manager
diff --git a/ansible/roles/blazar/tasks/loadbalancer.yml b/ansible/roles/blazar/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..928bfba7ae
--- /dev/null
+++ b/ansible/roles/blazar/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ blazar_services }}"
+  tags: always
diff --git a/ansible/roles/ceph/defaults/main.yml b/ansible/roles/ceph/defaults/main.yml
index 56817ab3ae..43dfc646cc 100644
--- a/ansible/roles/ceph/defaults/main.yml
+++ b/ansible/roles/ceph/defaults/main.yml
@@ -1,6 +1,22 @@
 ---
 project_name: "ceph"
 
+ceph_services:
+  ceph-rgw:
+    group: ceph-rgw
+    enabled: "{{ enable_ceph_rgw|bool }}"
+    haproxy:
+      radosgw:
+        enabled: "{{ enable_ceph|bool and enable_ceph_rgw|bool }}"
+        mode: "http"
+        external: false
+        port: "{{ rgw_port }}"
+      radosgw_external:
+        enabled: "{{ enable_ceph|bool and enable_ceph_rgw|bool }}"
+        mode: "http"
+        external: true
+        port: "{{ rgw_port }}"
+
 
 ####################
 # Docker
diff --git a/ansible/roles/ceph/tasks/loadbalancer.yml b/ansible/roles/ceph/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..9c776685e3
--- /dev/null
+++ b/ansible/roles/ceph/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ ceph_services }}"
+  tags: always
diff --git a/ansible/roles/cinder/defaults/main.yml b/ansible/roles/cinder/defaults/main.yml
index d52f96da47..b813979cb0 100644
--- a/ansible/roles/cinder/defaults/main.yml
+++ b/ansible/roles/cinder/defaults/main.yml
@@ -13,6 +13,17 @@ cinder_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/cinder/cinder:/var/lib/kolla/venv/lib/python2.7/site-packages/cinder' if cinder_dev_mode | bool else '' }}"
     dimensions: "{{ cinder_api_dimensions }}"
+    haproxy:
+      cinder_api:
+        enabled: "{{ enable_cinder }}"
+        mode: "http"
+        external: false
+        port: "{{ cinder_api_port }}"
+      cinder_api_external:
+        enabled: "{{ enable_cinder }}"
+        mode: "http"
+        external: true
+        port: "{{ cinder_api_port }}"
   cinder-scheduler:
     container_name: cinder_scheduler
     group: cinder-scheduler
diff --git a/ansible/roles/cinder/tasks/loadbalancer.yml b/ansible/roles/cinder/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..16dd82c0e6
--- /dev/null
+++ b/ansible/roles/cinder/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ cinder_services }}"
+  tags: always
diff --git a/ansible/roles/cloudkitty/defaults/main.yml b/ansible/roles/cloudkitty/defaults/main.yml
index 673616efac..663720adf6 100644
--- a/ansible/roles/cloudkitty/defaults/main.yml
+++ b/ansible/roles/cloudkitty/defaults/main.yml
@@ -13,6 +13,17 @@ cloudkitty_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/cloudkitty/cloudkitty:/var/lib/kolla/venv/lib/python2.7/site-packages/cloudkitty' if cloudkitty_dev_mode | bool else '' }}"
     dimensions: "{{ cloudkitty_api_dimensions }}"
+    haproxy:
+      cloudkitty_api:
+        enabled: "{{ enable_cloudkitty }}"
+        mode: "http"
+        external: false
+        port: "{{ cloudkitty_api_port }}"
+      cloudkitty_api_external:
+        enabled: "{{ enable_cloudkitty }}"
+        mode: "http"
+        external: true
+        port: "{{ cloudkitty_api_port }}"
   cloudkitty-processor:
     container_name: "cloudkitty_processor"
     group: "cloudkitty-processor"
diff --git a/ansible/roles/cloudkitty/tasks/loadbalancer.yml b/ansible/roles/cloudkitty/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..4119b9fd03
--- /dev/null
+++ b/ansible/roles/cloudkitty/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ cloudkitty_services }}"
+  tags: always
diff --git a/ansible/roles/congress/defaults/main.yml b/ansible/roles/congress/defaults/main.yml
index b2118b1469..1a6af4d1db 100644
--- a/ansible/roles/congress/defaults/main.yml
+++ b/ansible/roles/congress/defaults/main.yml
@@ -13,6 +13,17 @@ congress_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/congress/congress:/var/lib/kolla/venv/lib/python2.7/site-packages/congress' if congress_dev_mode | bool else '' }}"
     dimensions: "{{ congress_api_dimensions }}"
+    haproxy:
+      congress_api:
+        enabled: "{{ enable_congress }}"
+        mode: "http"
+        external: false
+        port: "{{ congress_api_port }}"
+      congress_api_external:
+        enabled: "{{ enable_congress }}"
+        mode: "http"
+        external: true
+        port: "{{ congress_api_port }}"
   congress-policy-engine:
     container_name: congress_policy_engine
     group: congress-policy-engine
diff --git a/ansible/roles/congress/tasks/loadbalancer.yml b/ansible/roles/congress/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..5c985b80d4
--- /dev/null
+++ b/ansible/roles/congress/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ congress_services }}"
+  tags: always
diff --git a/ansible/roles/designate/defaults/main.yml b/ansible/roles/designate/defaults/main.yml
index 774f27e98a..2e1646c966 100644
--- a/ansible/roles/designate/defaults/main.yml
+++ b/ansible/roles/designate/defaults/main.yml
@@ -13,6 +13,17 @@ designate_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/designate/designate:/var/lib/kolla/venv/lib/python2.7/site-packages/designate' if designate_dev_mode | bool else '' }}"
     dimensions: "{{ designate_api_dimensions }}"
+    haproxy:
+      designate_api:
+        enabled: "{{ enable_designate }}"
+        mode: "http"
+        external: false
+        port: "{{ designate_api_port }}"
+      designate_api_external:
+        enabled: "{{ enable_designate }}"
+        mode: "http"
+        external: true
+        port: "{{ designate_api_port }}"
   designate-backend-bind9:
     container_name: designate_backend_bind9
     group: designate-backend-bind9
diff --git a/ansible/roles/designate/tasks/loadbalancer.yml b/ansible/roles/designate/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..b8e2a76b89
--- /dev/null
+++ b/ansible/roles/designate/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ designate_services }}"
+  tags: always
diff --git a/ansible/roles/elasticsearch/defaults/main.yml b/ansible/roles/elasticsearch/defaults/main.yml
index 8be79d7cf8..10908a820a 100644
--- a/ansible/roles/elasticsearch/defaults/main.yml
+++ b/ansible/roles/elasticsearch/defaults/main.yml
@@ -12,6 +12,14 @@ elasticsearch_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "elasticsearch:/var/lib/elasticsearch/data"
     dimensions: "{{ elasticsearch_dimensions }}"
+    haproxy:
+      elasticsearch:
+        enabled: "{{ enable_elasticsearch }}"
+        mode: "http"
+        external: false
+        port: "{{ elasticsearch_port }}"
+        frontend_http_extra:
+          - "option dontlog-normal"
 
 
 ####################
diff --git a/ansible/roles/elasticsearch/tasks/loadbalancer.yml b/ansible/roles/elasticsearch/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..bdf431f56a
--- /dev/null
+++ b/ansible/roles/elasticsearch/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ elasticsearch_services }}"
+  tags: always
diff --git a/ansible/roles/freezer/defaults/main.yml b/ansible/roles/freezer/defaults/main.yml
index b7a046ed86..2bf7232816 100644
--- a/ansible/roles/freezer/defaults/main.yml
+++ b/ansible/roles/freezer/defaults/main.yml
@@ -14,6 +14,17 @@ freezer_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/freezer-api/freezer_api:/var/lib/kolla/venv/lib/python2.7/site-packages/freezer_api' if freezer_dev_mode | bool else '' }}"
     dimensions: "{{ freezer_api_dimensions }}"
+    haproxy:
+      freezer_api:
+        enabled: "{{ enable_freezer }}"
+        mode: "http"
+        external: false
+        port: "{{ freezer_api_port }}"
+      freezer_api_external:
+        enabled: "{{ enable_freezer }}"
+        mode: "http"
+        external: true
+        port: "{{ freezer_api_port }}"
   freezer-scheduler:
     container_name: freezer_scheduler
     group: freezer-scheduler
diff --git a/ansible/roles/freezer/tasks/loadbalancer.yml b/ansible/roles/freezer/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..7e95c94d68
--- /dev/null
+++ b/ansible/roles/freezer/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ freezer_services }}"
+  tags: always
diff --git a/ansible/roles/glance/defaults/main.yml b/ansible/roles/glance/defaults/main.yml
index 6c9f493fa0..8f1764a43f 100644
--- a/ansible/roles/glance/defaults/main.yml
+++ b/ansible/roles/glance/defaults/main.yml
@@ -15,6 +15,27 @@ glance_services:
       - "{{ kolla_dev_repos_directory ~ '/glance/glance:/var/lib/kolla/venv/lib/python2.7/site-packages/glance' if glance_dev_mode | bool else '' }}"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ glance_api_dimensions }}"
+    haproxy:
+      glance_api:
+        enabled: "{{ enable_glance }}"
+        mode: "http"
+        external: false
+        port: "{{ glance_api_port }}"
+        frontend_http_extra:
+          - "timeout client {{ haproxy_glance_api_client_timeout }}"
+        backend_http_extra:
+          - "timeout server {{ haproxy_glance_api_server_timeout }}"
+        custom_member_list: "{{ haproxy_members.split(';') }}"
+      glance_api_external:
+        enabled: "{{ enable_glance }}"
+        mode: "http"
+        external: true
+        port: "{{ glance_api_port }}"
+        frontend_http_extra:
+          - "timeout client {{ haproxy_glance_api_client_timeout }}"
+        backend_http_extra:
+          - "timeout server {{ haproxy_glance_api_server_timeout }}"
+        custom_member_list: "{{ haproxy_members.split(';') }}"
   glance-registry:
     container_name: glance_registry
     group: glance-registry
@@ -27,6 +48,11 @@ glance_services:
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ glance_registry_dimensions }}"
 
+####################
+# HAProxy
+####################
+haproxy_members: "{% for host in glance_api_hosts %}server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ glance_api_port }} check inter 2000 rise 2 fall 5;{% endfor %}"
+
 ####################
 # Notification
 ####################
@@ -66,6 +92,13 @@ glance_database_user: "{% if use_preconfigured_databases | bool and use_common_m
 glance_database_address: "{{ database_address }}:{{ database_port }}"
 
 
+####################
+# HAProxy
+####################
+haproxy_glance_api_client_timeout: "6h"
+haproxy_glance_api_server_timeout: "6h"
+
+
 ####################
 # Docker
 ####################
diff --git a/ansible/roles/glance/tasks/loadbalancer.yml b/ansible/roles/glance/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..96ece25ef0
--- /dev/null
+++ b/ansible/roles/glance/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ glance_services }}"
+  tags: always
diff --git a/ansible/roles/gnocchi/defaults/main.yml b/ansible/roles/gnocchi/defaults/main.yml
index c997bbb2b3..fc9f478c4f 100644
--- a/ansible/roles/gnocchi/defaults/main.yml
+++ b/ansible/roles/gnocchi/defaults/main.yml
@@ -13,6 +13,17 @@ gnocchi_services:
       - "gnocchi:/var/lib/gnocchi/"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ gnocchi_api_dimensions }}"
+    haproxy:
+      gnocchi_api:
+        enabled: "{{ enable_gnocchi }}"
+        mode: "http"
+        external: false
+        port: "{{ gnocchi_api_port }}"
+      gnocchi_api_external:
+        enabled: "{{ enable_gnocchi }}"
+        mode: "http"
+        external: true
+        port: "{{ gnocchi_api_port }}"
   gnocchi-metricd:
     container_name: gnocchi_metricd
     group: gnocchi-metricd
diff --git a/ansible/roles/gnocchi/tasks/loadbalancer.yml b/ansible/roles/gnocchi/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..2535c4dd74
--- /dev/null
+++ b/ansible/roles/gnocchi/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ gnocchi_services }}"
+  tags: always
diff --git a/ansible/roles/grafana/defaults/main.yml b/ansible/roles/grafana/defaults/main.yml
index 759e0356f8..2e08ae5338 100644
--- a/ansible/roles/grafana/defaults/main.yml
+++ b/ansible/roles/grafana/defaults/main.yml
@@ -13,6 +13,17 @@ grafana_services:
       - "grafana:/var/lib/grafana/"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ grafana_dimensions }}"
+    haproxy:
+      grafana_server:
+        enabled: "{{ enable_grafana }}"
+        mode: "http"
+        external: false
+        port: "{{ grafana_server_port }}"
+      grafana_server_external:
+        enabled: "{{ enable_grafana }}"
+        mode: "http"
+        external: true
+        port: "{{ grafana_server_port }}"
 
 ####################
 # Database
diff --git a/ansible/roles/grafana/tasks/loadbalancer.yml b/ansible/roles/grafana/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..74c484277d
--- /dev/null
+++ b/ansible/roles/grafana/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ grafana_services }}"
+  tags: always
diff --git a/ansible/roles/haproxy-config/defaults/main.yml b/ansible/roles/haproxy-config/defaults/main.yml
new file mode 100644
index 0000000000..9071ef5248
--- /dev/null
+++ b/ansible/roles/haproxy-config/defaults/main.yml
@@ -0,0 +1,13 @@
+---
+haproxy_service_template: "haproxy_single_service_listen.cfg.j2"
+
+# Extra frontend/backend options (additive with locally defined options)
+haproxy_frontend_http_extra:
+  - "option httplog"
+  - "option forwardfor"
+haproxy_frontend_tcp_extra:
+  - "option tcplog"
+haproxy_backend_http_extra: []
+haproxy_backend_tcp_extra: []
+
+haproxy_health_check: "check inter 2000 rise 2 fall 5"
diff --git a/ansible/roles/haproxy-config/handlers/main.yml b/ansible/roles/haproxy-config/handlers/main.yml
new file mode 100644
index 0000000000..dc4b1305f2
--- /dev/null
+++ b/ansible/roles/haproxy-config/handlers/main.yml
@@ -0,0 +1,17 @@
+---
+- name: Restart haproxy container
+  become: true
+  kolla_docker:
+    action: "restart_container"
+    name: haproxy
+  when:
+    - kolla_action != "config"
+    - inventory_hostname in groups['haproxy']
+    - enable_haproxy | bool
+  notify:
+    - Waiting for haproxy to start
+
+- name: Waiting for haproxy to start
+  wait_for:
+    host: "{{ api_interface_address }}"
+    port: "{{ haproxy_stats_port }}"
diff --git a/ansible/roles/haproxy-config/tasks/main.yml b/ansible/roles/haproxy-config/tasks/main.yml
new file mode 100644
index 0000000000..07caf04463
--- /dev/null
+++ b/ansible/roles/haproxy-config/tasks/main.yml
@@ -0,0 +1,21 @@
+---
+- name: "Copying over {{ project_name }} haproxy config"
+  vars:
+    service: "{{ item.value }}"
+    haproxy_templates:
+      - "{{ node_custom_config }}/haproxy-config/{{ inventory_hostname }}/{{ haproxy_service_template }}"
+      - "{{ node_custom_config }}/haproxy-config/{{ haproxy_service_template }}"
+      - "templates/{{ haproxy_service_template }}"
+    template_file: "{{ query('first_found', haproxy_templates) | first }}"
+  template:
+    src: "{{ template_file }}"
+    dest: "{{ node_config_directory }}/haproxy/services.d/{{ item.key }}.cfg"
+    mode: "0660"
+  become: true
+  when:
+    - service.enabled | bool
+    - service.haproxy is defined
+    - enable_haproxy | bool
+  with_dict: "{{ project_services }}"
+  notify:
+    - Restart haproxy container
diff --git a/ansible/roles/haproxy-config/templates/haproxy_single_service_listen.cfg.j2 b/ansible/roles/haproxy-config/templates/haproxy_single_service_listen.cfg.j2
new file mode 100644
index 0000000000..0baa25cc80
--- /dev/null
+++ b/ansible/roles/haproxy-config/templates/haproxy_single_service_listen.cfg.j2
@@ -0,0 +1,91 @@
+#jinja2: lstrip_blocks: True
+{%- set tls_bind_info = 'ssl crt /etc/haproxy/haproxy.pem' if kolla_enable_tls_external|bool else '' %}
+
+{%- macro userlist_macro(service_name, auth_user, auth_pass) %}
+userlist {{ service_name }}-user
+  user {{ auth_user }} insecure-password {{ auth_pass }}
+{% endmacro %}
+
+{%- macro listen_macro(service_name, service_port, service_mode, external,
+                       haproxy_http_extra, haproxy_tcp_extra, host_group,
+                       custom_member_list, auth_user, auth_pass) %}
+listen {{ service_name }}
+    {% if service_mode == 'redirect' %}
+    mode http
+    {% else %}
+    mode {{ service_mode }}
+    {% endif %}
+    {% if service_mode == 'http' %}
+        {# Set up auth if required #}
+        {% if auth_user and auth_pass %}
+    acl auth_acl http_auth({{ service_name }}-user)
+    http-request auth realm basicauth unless auth_acl
+        {% endif %}
+    {# Delete any pre-populated XFP header #}
+    http-request del-header X-Forwarded-Proto
+        {% for http_option in haproxy_http_extra %}
+    {{ http_option }}
+        {% endfor %}
+    {% elif service_mode == 'tcp' %}
+        {% for tcp_option in haproxy_tcp_extra %}
+    {{ tcp_option }}
+        {% endfor %}
+    {% endif %}
+    {% set tls_option = '' %}
+    {% if external|bool %}
+        {% set vip_address = kolla_external_vip_address %}
+        {% if service_mode == 'http' %}
+            {% set tls_option = tls_bind_info %}
+    {# Replace the XFP header for external https requests #}
+    http-request set-header X-Forwarded-Proto https if { ssl_fc }
+        {% endif %}
+    {% else %}
+        {% set vip_address = kolla_internal_vip_address %}
+    {% endif %}
+    {{ "bind %s:%s %s"|e|format(vip_address, service_port, tls_option)|trim() }}
+    {# Redirect mode sets a redirect scheme instead of members #}
+    {% if service_mode == 'redirect' %}
+    redirect scheme https code 301 if !{ ssl_fc }
+    {% else %}
+        {% if custom_member_list is not none %}
+            {% for custom_member in custom_member_list %}
+    {{ custom_member }}
+            {% endfor %}
+        {% else %}
+            {% for host in groups[host_group] %}
+                {% set api_interface = "ansible_%s"|format(hostvars[host]['api_interface']) %}
+                {% set host_name = hostvars[host]['ansible_hostname'] %}
+                {% set host_ip = hostvars[host][api_interface]['ipv4']['address'] %}
+    server {{ host_name }} {{ host_ip }}:{{ service_port }} {{ haproxy_health_check }}
+            {% endfor %}
+        {% endif %}
+    {% endif %}
+{% endmacro %}
+
+{%- set haproxy = service.haproxy|default({}) %}
+{%- for haproxy_name, haproxy_service in haproxy.items() %}
+    {# External defaults to false #}
+    {% set external = haproxy_service.external|default(false)|bool %}
+    {# Skip anything that is external when the external vip is not enabled #}
+    {% if haproxy_service.enabled|bool and (not external or haproxy_enable_external_vip|bool)%}
+        {# Here we define variables and their defaults #}
+        {# Custom member list can use jinja to generate a semicolon separated list #}
+        {% set custom_member_list = haproxy_service.custom_member_list|default(none) %}
+        {# Mode defaults to http #}
+        {% set mode = haproxy_service.mode|default('http') %}
+        {# Use the parent host group but allow it to be overridden #}
+        {% set host_group = haproxy_service.host_group|default(service.group) %}
+        {# Additional options can be defined in config, and are additive to the global extras #}
+        {% set haproxy_tcp_extra = haproxy_service.frontend_tcp_extra|default([]) + haproxy_service.backend_tcp_extra|default([]) + haproxy_frontend_tcp_extra + haproxy_backend_tcp_extra %}
+        {% set haproxy_http_extra = haproxy_service.frontend_http_extra|default([]) + haproxy_service.backend_http_extra|default([]) + haproxy_frontend_http_extra + haproxy_backend_http_extra %}
+        {# Allow for basic auth #}
+        {% set auth_user = haproxy_service.auth_user|default() %}
+        {% set auth_pass = haproxy_service.auth_pass|default() %}
+        {% if auth_user and auth_pass %}
+{{ userlist_macro(haproxy_name, auth_user, auth_pass) }}
+        {% endif %}
+{{ listen_macro(haproxy_name, haproxy_service.port, mode, external,
+                haproxy_http_extra, haproxy_tcp_extra, host_group,
+                custom_member_list, auth_user, auth_pass) }}
+    {% endif %}
+{%- endfor -%}
diff --git a/ansible/roles/haproxy-config/templates/haproxy_single_service_split.cfg.j2 b/ansible/roles/haproxy-config/templates/haproxy_single_service_split.cfg.j2
new file mode 100644
index 0000000000..f20418ebcb
--- /dev/null
+++ b/ansible/roles/haproxy-config/templates/haproxy_single_service_split.cfg.j2
@@ -0,0 +1,118 @@
+#jinja2: lstrip_blocks: True
+{%- set tls_bind_info = 'ssl crt /etc/haproxy/haproxy.pem' if kolla_enable_tls_external|bool else '' %}
+
+{%- macro userlist_macro(service_name, auth_user, auth_pass) %}
+userlist {{ service_name }}-user
+  user {{ auth_user }} insecure-password {{ auth_pass }}
+{% endmacro %}
+
+{%- macro frontend_macro(service_name, service_port, service_mode, external,
+                         frontend_http_extra, frontend_tcp_extra) %}
+frontend {{ service_name }}_front
+    {% if service_mode == 'redirect' %}
+    mode http
+    {% else %}
+    mode {{ service_mode }}
+    {% endif %}
+    {% if service_mode == 'http' %}
+    {# Delete any pre-populated XFP header #}
+    http-request del-header X-Forwarded-Proto
+        {% for http_option in frontend_http_extra %}
+    {{ http_option }}
+        {% endfor %}
+    {% elif service_mode == 'tcp' %}
+        {% for tcp_option in frontend_tcp_extra %}
+    {{ tcp_option }}
+        {% endfor %}
+    {% endif %}
+    {% set tls_option = '' %}
+    {% if external|bool %}
+        {% set vip_address = kolla_external_vip_address %}
+        {% if service_mode == 'http' %}
+            {% set tls_option = tls_bind_info %}
+    {# Replace the XFP header for external https requests #}
+    http-request set-header X-Forwarded-Proto https if { ssl_fc }
+        {% endif %}
+    {% else %}
+        {% set vip_address = kolla_internal_vip_address %}
+    {% endif %}
+    {{ "bind %s:%s %s"|e|format(vip_address, service_port, tls_option)|trim() }}
+    {# Redirect mode sets a redirect scheme instead of a backend #}
+    {% if service_mode == 'redirect' %}
+    redirect scheme https code 301 if !{ ssl_fc }
+    {% else %}
+    default_backend {{ service_name }}_back
+    {% endif %}
+{% endmacro %}
+
+{%- macro backend_macro(service_name, service_port, service_mode, host_group,
+                        custom_member_list, backend_http_extra,
+                        backend_tcp_extra, auth_user, auth_pass) %}
+backend {{ service_name }}_back
+    {% if service_mode == 'redirect' %}
+    mode http
+    {% else %}
+    mode {{ service_mode }}
+    {% endif %}
+    {% if service_mode == 'http' %}
+        {# Set up auth if required #}
+        {% if auth_user and auth_pass %}
+    acl auth_acl http_auth({{ service_name }}-user)
+    http-request auth realm basicauth unless auth_acl
+        {% endif %}
+        {% for http_option in backend_http_extra %}
+    {{ http_option }}
+        {% endfor %}
+    {% elif service_mode == 'tcp' %}
+        {% for tcp_option in backend_tcp_extra %}
+    {{ tcp_option }}
+        {% endfor %}
+    {% endif %}
+    {% if custom_member_list is not none %}
+        {% for custom_member in custom_member_list %}
+    {{ custom_member }}
+        {% endfor %}
+    {% else %}
+        {% for host in groups[host_group] %}
+            {% set api_interface = "ansible_%s"|format(hostvars[host]['api_interface']) %}
+            {% set host_name = hostvars[host]['ansible_hostname'] %}
+            {% set host_ip = hostvars[host][api_interface]['ipv4']['address'] %}
+    server {{ host_name }} {{ host_ip }}:{{ service_port }} {{ haproxy_health_check }}
+        {% endfor %}
+    {% endif %}
+{% endmacro %}
+
+{%- set haproxy = service.haproxy|default({}) %}
+{%- for haproxy_name, haproxy_service in haproxy.items() %}
+    {# External defaults to false #}
+    {% set external = haproxy_service.external|default(false)|bool %}
+    {# Skip anything that is external when the external vip is not enabled #}
+    {% if haproxy_service.enabled|bool and (not external or haproxy_enable_external_vip|bool)%}
+        {# Here we define variables and their defaults #}
+        {# Custom member list can use jinja to generate a semicolon separated list #}
+        {% set custom_member_list = haproxy_service.custom_member_list|default() %}
+        {# Mode defaults to http #}
+        {% set mode = haproxy_service.mode|default('http') %}
+        {# Use the parent host group but allow it to be overridden #}
+        {% set host_group = haproxy_service.host_group|default(service.group) %}
+        {# Additional options can be defined in config, and are additive to the global extras #}
+        {% set frontend_tcp_extra = haproxy_service.frontend_tcp_extra|default([]) + haproxy_frontend_tcp_extra %}
+        {% set backend_tcp_extra = haproxy_service.backend_tcp_extra|default([]) %}
+        {% set frontend_http_extra = haproxy_service.frontend_http_extra|default([]) + haproxy_frontend_http_extra %}
+        {% set backend_http_extra = haproxy_service.backend_http_extra|default([]) %}
+        {# Allow for basic auth #}
+        {% set auth_user = haproxy_service.auth_user|default() %}
+        {% set auth_pass = haproxy_service.auth_pass|default() %}
+        {% if auth_user and auth_pass %}
+{{ userlist_macro(haproxy_name, auth_user, auth_pass) }}
+        {% endif %}
+{{ frontend_macro(haproxy_name, haproxy_service.port, mode, external,
+                  frontend_http_extra, frontend_tcp_extra) }}
+        {# Redirect (to https) is a special case, as it does not include a backend #}
+        {% if haproxy_service.mode != 'redirect' %}
+{{ backend_macro(haproxy_name, haproxy_service.port, mode, host_group,
+                 custom_member_list, backend_http_extra, backend_tcp_extra,
+                 auth_user, auth_pass) }}
+        {% endif %}
+    {% endif %}
+{%- endfor -%}
diff --git a/ansible/roles/haproxy/defaults/main.yml b/ansible/roles/haproxy/defaults/main.yml
index 1dafa84fa3..597866ba39 100644
--- a/ansible/roles/haproxy/defaults/main.yml
+++ b/ansible/roles/haproxy/defaults/main.yml
@@ -38,27 +38,12 @@ haproxy_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_
 haproxy_tag: "{{ openstack_release }}"
 haproxy_image_full: "{{ haproxy_image }}:{{ haproxy_tag }}"
 
-haproxy_client_timeout: "1m"
-haproxy_server_timeout: "1m"
-
-# Check http://www.haproxy.org/download/1.5/doc/configuration.txt for available options
-haproxy_defaults_balance: "roundrobin"
-
-haproxy_glance_api_client_timeout: "6h"
-haproxy_glance_api_server_timeout: "6h"
-
-haproxy_outward_rabbitmq_client_timeout: "1h"
-haproxy_outward_rabbitmq_server_timeout: "1h"
-
 syslog_server: "{{ api_interface_address }}"
 syslog_haproxy_facility: "local1"
 
 # Traffic mode. Valid options are [ multicast, unicast ]
 keepalived_traffic_mode: "multicast"
 
-haproxy_listen_tcp_extra: []
-haproxy_listen_http_extra: []
-
 # Extended global configuration, optimization options.
 haproxy_max_connections: 4000
 haproxy_processes: 1
@@ -66,3 +51,14 @@ haproxy_process_cpu_map: "no"
 
 haproxy_dimensions: "{{ default_container_dimensions }}"
 keepalived_dimensions: "{{ default_container_dimensions }}"
+
+# Default timeout values
+haproxy_http_request_timeout: "10s"
+haproxy_queue_timeout: "1m"
+haproxy_connect_timeout: "10s"
+haproxy_client_timeout: "1m"
+haproxy_server_timeout: "1m"
+haproxy_check_timeout: "10s"
+
+# Check http://www.haproxy.org/download/1.5/doc/configuration.txt for available options
+haproxy_defaults_balance: "roundrobin"
diff --git a/ansible/roles/haproxy/handlers/main.yml b/ansible/roles/haproxy/handlers/main.yml
index 9ba40a562f..60fa5a03e3 100644
--- a/ansible/roles/haproxy/handlers/main.yml
+++ b/ansible/roles/haproxy/handlers/main.yml
@@ -3,8 +3,6 @@
   vars:
     service_name: "haproxy"
     service: "{{ haproxy_services[service_name] }}"
-    config_json: "{{ haproxy_config_jsons.results|selectattr('item.key', 'equalto', service_name)|first }}"
-    haproxy_container: "{{ check_haproxy_containers.results|selectattr('item.key', 'equalto', service_name)|first }}"
   become: true
   kolla_docker:
     action: "recreate_or_restart_container"
@@ -18,19 +16,13 @@
     - kolla_action != "config"
     - inventory_hostname in groups[service.group]
     - service.enabled | bool
-    - config_json.changed | bool
-      or haproxy_cfg.changed | bool
-      or haproxy_pem.changed | bool
-      or haproxy_container.changed | bool
   notify:
-    - Waiting for virtual IP to appear
+    - Waiting for haproxy to start
 
 - name: Restart keepalived container
   vars:
     service_name: "keepalived"
     service: "{{ haproxy_services[service_name] }}"
-    config_json: "{{ haproxy_config_jsons.results|selectattr('item.key', 'equalto', service_name)|first }}"
-    keepalived_container: "{{ check_haproxy_containers.results|selectattr('item.key', 'equalto', service_name)|first }}"
   become: true
   kolla_docker:
     action: "recreate_or_restart_container"
@@ -44,26 +36,15 @@
     - kolla_action != "config"
     - inventory_hostname in groups[service.group]
     - service.enabled | bool
-    - config_json.changed | bool
-      or keepalived_conf.changed | bool
-      or keepalived_container.changed | bool
   notify:
     - Waiting for virtual IP to appear
 
-- name: Ensuring latest haproxy config is used
-  command: docker exec haproxy /usr/local/bin/kolla_ensure_haproxy_latest_config
-  register: status
-  changed_when: status.stdout.find('changed') != -1
-  when:
-    - kolla_action != "config"
-    - haproxy_config_jsons.changed | bool
-      or haproxy_cfg.changed | bool
-      or haproxy_pem.changed | bool
+- name: Waiting for haproxy to start
+  wait_for:
+    host: "{{ api_interface_address }}"
+    port: "{{ haproxy_monitor_port }}"
 
 - name: Waiting for virtual IP to appear
   wait_for:
     host: "{{ kolla_internal_vip_address }}"
-    port: "{{ database_port }}"
-  when:
-    - enable_mariadb | bool
-      or enable_external_mariadb_load_balancer | bool
+    port: "{{ haproxy_monitor_port }}"
diff --git a/ansible/roles/haproxy/tasks/config.yml b/ansible/roles/haproxy/tasks/config.yml
index d687cf44de..acf75855c5 100644
--- a/ansible/roles/haproxy/tasks/config.yml
+++ b/ansible/roles/haproxy/tasks/config.yml
@@ -20,20 +20,32 @@
     - item.value.enabled | bool
   with_dict: "{{ haproxy_services }}"
 
+- name: Ensuring service config subdir exists
+  vars:
+    service: "{{ haproxy_services['haproxy'] }}"
+  file:
+    path: "{{ node_config_directory }}/haproxy/services.d"
+    state: "directory"
+    owner: "{{ config_owner_user }}"
+    group: "{{ config_owner_group }}"
+    mode: "0770"
+  become: true
+  when:
+    - inventory_hostname in groups[service.group]
+    - service.enabled | bool
+
 - name: Copying over config.json files for services
   template:
     src: "{{ item.key }}.json.j2"
     dest: "{{ node_config_directory }}/{{ item.key }}/config.json"
     mode: "0660"
   become: true
-  register: haproxy_config_jsons
   when:
     - inventory_hostname in groups[item.value.group]
     - item.value.enabled | bool
   with_dict: "{{ haproxy_services }}"
   notify:
     - "Restart {{ item.key }} container"
-    - Ensuring latest haproxy config is used
 
 - name: Copying over haproxy.cfg
   vars:
@@ -43,17 +55,15 @@
     dest: "{{ node_config_directory }}/haproxy/haproxy.cfg"
     mode: "0660"
   become: true
-  register: haproxy_cfg
   when:
     - inventory_hostname in groups[service.group]
     - service.enabled | bool
   with_first_found:
-    - "{{ node_custom_config }}/haproxy/{{ inventory_hostname }}/haproxy.cfg"
-    - "{{ node_custom_config }}/haproxy/haproxy.cfg"
-    - "haproxy.cfg.j2"
+    - "{{ node_custom_config }}/haproxy/{{ inventory_hostname }}/haproxy_main.cfg"
+    - "{{ node_custom_config }}/haproxy/haproxy_main.cfg"
+    - "haproxy_main.cfg.j2"
   notify:
     - Restart haproxy container
-    - Ensuring latest haproxy config is used
 
 - name: Copying over keepalived.conf
   vars:
@@ -63,7 +73,6 @@
     dest: "{{ node_config_directory }}/keepalived/keepalived.conf"
     mode: "0660"
   become: true
-  register: keepalived_conf
   when:
     - inventory_hostname in groups[service.group]
     - service.enabled | bool
@@ -82,7 +91,6 @@
     dest: "{{ node_config_directory }}/haproxy/{{ item }}"
     mode: "0660"
   become: true
-  register: haproxy_pem
   when:
     - kolla_enable_tls_external | bool
     - inventory_hostname in groups[service.group]
@@ -91,7 +99,24 @@
     - "haproxy.pem"
   notify:
     - Restart haproxy container
-    - Ensuring latest haproxy config is used
+
+- name: Copying over haproxy start script
+  vars:
+    service: "{{ haproxy_services['haproxy'] }}"
+  template:
+    src: "{{ item }}"
+    dest: "{{ node_config_directory }}/haproxy/haproxy_run.sh"
+    mode: "0770"
+  become: true
+  when:
+    - inventory_hostname in groups[service.group]
+    - service.enabled | bool
+  with_first_found:
+    - "{{ node_custom_config }}/haproxy/{{ inventory_hostname }}/haproxy_run.sh"
+    - "{{ node_custom_config }}/haproxy/haproxy_run.sh"
+    - "haproxy_run.sh.j2"
+  notify:
+    - Restart haproxy container
 
 - name: Check haproxy containers
   become: true
@@ -103,7 +128,6 @@
     volumes: "{{ item.value.volumes }}"
     dimensions: "{{ item.value.dimensions }}"
     privileged: "{{ item.value.privileged | default(False) }}"
-  register: check_haproxy_containers
   when:
     - kolla_action != "config"
     - inventory_hostname in groups[item.value.group]
diff --git a/ansible/roles/haproxy/tasks/precheck.yml b/ansible/roles/haproxy/tasks/precheck.yml
index e5631d8f91..b8f48000b0 100644
--- a/ansible/roles/haproxy/tasks/precheck.yml
+++ b/ansible/roles/haproxy/tasks/precheck.yml
@@ -108,7 +108,7 @@
 
 - name: Checking free port for HAProxy stats
   wait_for:
-    host: "{{ kolla_internal_vip_address }}"
+    host: "{{ api_interface_address }}"
     port: "{{ haproxy_stats_port }}"
     connect_timeout: 1
     timeout: 1
@@ -118,6 +118,31 @@
     - container_facts['haproxy'] is not defined
     - inventory_hostname in groups['haproxy']
 
+- name: Checking free port for HAProxy monitor (api interface)
+  wait_for:
+    host: "{{ api_interface_address }}"
+    port: "{{ haproxy_monitor_port }}"
+    connect_timeout: 1
+    timeout: 1
+    state: stopped
+  when:
+    - enable_haproxy | bool
+    - container_facts['haproxy'] is not defined
+    - inventory_hostname in groups['haproxy']
+
+- name: Checking free port for HAProxy monitor (vip interface)
+  wait_for:
+    host: "{{ kolla_internal_vip_address }}"
+    port: "{{ haproxy_monitor_port }}"
+    connect_timeout: 1
+    timeout: 1
+    state: stopped
+  when:
+    - enable_haproxy | bool
+    - container_facts['haproxy'] is not defined
+    - inventory_hostname in groups['haproxy']
+    - api_interface_address != kolla_internal_vip_address
+
 - 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
diff --git a/ansible/roles/haproxy/templates/haproxy.cfg.j2 b/ansible/roles/haproxy/templates/haproxy.cfg.j2
deleted file mode 100644
index 09dfc530fe..0000000000
--- a/ansible/roles/haproxy/templates/haproxy.cfg.j2
+++ /dev/null
@@ -1,1431 +0,0 @@
-#jinja2: trim_blocks: False
-{% set tls_bind_info = 'ssl crt /etc/haproxy/haproxy.pem' if kolla_enable_tls_external | bool else '' %}
-global
-  chroot /var/lib/haproxy
-  user haproxy
-  group haproxy
-  daemon
-  log {{ syslog_server }}:{{ syslog_udp_port }} {{ syslog_haproxy_facility }}
-  maxconn {{ haproxy_max_connections }}
-  nbproc {{ haproxy_processes }}
-{% if haproxy_processes > 1 and haproxy_process_cpu_map | bool %}
-{% for cpu_idx in range(0, haproxy_processes) %}
-  cpu-map {{cpu_idx+1}} {{cpu_idx}}
-{% endfor %}
-{% endif %}
-  stats socket /var/lib/kolla/haproxy/haproxy.sock group kolla mode 660
-{% if kolla_enable_tls_external | bool %}
-  ssl-default-bind-ciphers DEFAULT:!MEDIUM:!3DES
-  ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
-  tune.ssl.default-dh-param 4096
-{% endif %}
-
-defaults
-  log global
-  mode http
-  option redispatch
-  option httplog
-  option forwardfor
-  retries 3
-  timeout http-request 10s
-  timeout queue 1m
-  timeout connect 10s
-  timeout client {{ haproxy_client_timeout }}
-  timeout server {{ haproxy_server_timeout }}
-  timeout check 10s
-  balance {{ haproxy_defaults_balance }}
-
-listen stats
-   bind {{ api_interface_address }}:{{ haproxy_stats_port }}
-   mode http
-   stats enable
-   stats uri /
-   stats refresh 15s
-   stats realm Haproxy\ Stats
-   stats auth {{ haproxy_user }}:{{ haproxy_password }}
-
-{% if enable_rabbitmq | bool %}
-listen rabbitmq_management
-  bind {{ kolla_internal_vip_address }}:{{ rabbitmq_management_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['rabbitmq'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ rabbitmq_management_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-{% if enable_outward_rabbitmq | bool %}
-listen outward_rabbitmq_management
-  bind {{ kolla_internal_vip_address }}:{{ outward_rabbitmq_management_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['outward-rabbitmq'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ outward_rabbitmq_management_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen outward_rabbitmq_external
-  mode tcp
-  option tcplog
-  timeout client {{ haproxy_outward_rabbitmq_client_timeout }}
-  timeout server {{ haproxy_outward_rabbitmq_server_timeout }}
-  bind {{ kolla_external_vip_address }}:{{ outward_rabbitmq_port }}
-{% for tcp_option in haproxy_listen_tcp_extra %}
-  {{ tcp_option }}
-{% endfor %}
-{% for host in groups['outward-rabbitmq'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ outward_rabbitmq_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_mongodb | bool %}
-listen mongodb
-  bind {{ kolla_internal_vip_address }}:{{ mongodb_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['mongodb'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ mongodb_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-
-{% if enable_keystone | bool %}
-listen keystone_internal
-  bind {{ kolla_internal_vip_address }}:{{ keystone_public_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['keystone'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ keystone_public_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen keystone_external
-  bind {{ kolla_external_vip_address }}:{{ keystone_public_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['keystone'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ keystone_public_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-
-listen keystone_admin
-  bind {{ kolla_internal_vip_address }}:{{ keystone_admin_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['keystone'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ keystone_admin_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-
-{% if enable_glance | bool %}
-listen glance_registry
-  bind {{ kolla_internal_vip_address }}:{{ glance_registry_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['glance-registry'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ glance_registry_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen glance_api
-  bind {{ kolla_internal_vip_address }}:{{ glance_api_port }}
-  http-request del-header X-Forwarded-Proto
-  timeout client {{ haproxy_glance_api_client_timeout }}
-  timeout server {{ haproxy_glance_api_server_timeout }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in glance_api_hosts %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ glance_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen glance_api_external
-  bind {{ kolla_external_vip_address }}:{{ glance_api_port }} {{ tls_bind_info }}
-  timeout client {{ haproxy_glance_api_client_timeout }}
-  timeout server {{ haproxy_glance_api_server_timeout }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in glance_api_hosts %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ glance_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_influxdb | bool %}
-listen influxdb_admin
-  bind {{ kolla_internal_vip_address }}:{{ influxdb_admin_port }}
-{% for host in groups['influxdb'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ influxdb_admin_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen influxdb_http
-  bind {{ kolla_internal_vip_address }}:{{ influxdb_http_port }}
-{% for host in groups['influxdb'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ influxdb_http_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-
-{% if enable_monasca | bool %}
-listen monasca_api_internal
-  bind {{ kolla_internal_vip_address }}:{{ monasca_api_port }}
-  http-request del-header X-Forwarded-Proto if { ssl_fc }
-{% for host in groups['monasca-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ monasca_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen monasca_log_api_internal
-  bind {{ kolla_internal_vip_address }}:{{ monasca_log_api_port }}
-  http-request del-header X-Forwarded-Proto if { ssl_fc }
-{% for host in groups['monasca-log-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ monasca_log_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-{% if haproxy_enable_external_vip | bool %}
-listen monasca_api_external
-  bind {{ kolla_external_vip_address }}:{{ monasca_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto if { ssl_fc }
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['monasca-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ monasca_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen monasca_log_api_external
-  bind {{ kolla_external_vip_address }}:{{ monasca_log_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto if { ssl_fc }
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['monasca-log-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ monasca_log_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_nova | bool %}
-listen nova_api
-  bind {{ kolla_internal_vip_address }}:{{ nova_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['nova-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ nova_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen nova_metadata
-  bind {{ kolla_internal_vip_address }}:{{ nova_metadata_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['nova-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ nova_metadata_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen placement_api
-  bind {{ kolla_internal_vip_address }}:{{ placement_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['placement-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ placement_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-{% if nova_console == 'novnc' %}
-listen nova_novncproxy
-  bind {{ kolla_internal_vip_address }}:{{ nova_novncproxy_port }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-  timeout tunnel 1h
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['nova-novncproxy'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ nova_novncproxy_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% elif nova_console == 'spice' %}
-listen nova_spicehtml5proxy
-  bind {{ kolla_internal_vip_address }}:{{ nova_spicehtml5proxy_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['nova-spicehtml5proxy'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ nova_spicehtml5proxy_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% elif nova_console == 'rdp' %}
-listen nova_rdp
-  bind {{ kolla_internal_vip_address }}:{{ rdp_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['hyperv'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {% for ip in hostvars[host]['ansible_ip_addresses'] %}{% if host == ip %}{{ ip }}{% endif %}{% endfor %}:{{ rdp_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-
-{% if enable_nova_serialconsole_proxy | bool %}
-listen nova_serialconsole_proxy
-  bind {{ kolla_internal_vip_address }}:{{ nova_serialproxy_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['nova-serialproxy'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ nova_serialproxy_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen nova_api_external
-  bind {{ kolla_external_vip_address }}:{{ nova_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['nova-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ nova_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen nova_metadata_external
-  bind {{ kolla_external_vip_address }}:{{ nova_metadata_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['nova-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ nova_metadata_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen placement_api_external
-  bind {{ kolla_external_vip_address }}:{{ placement_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['placement-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ placement_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-{% if nova_console == 'novnc' %}
-listen nova_novncproxy_external
-  bind {{ kolla_external_vip_address }}:{{ nova_novncproxy_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['nova-novncproxy'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ nova_novncproxy_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% elif nova_console == 'spice' %}
-listen nova_spicehtml5proxy_external
-  bind {{ kolla_external_vip_address }}:{{ nova_spicehtml5proxy_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['nova-spicehtml5proxy'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ nova_spicehtml5proxy_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-
-{% if enable_nova_serialconsole_proxy | bool %}
-listen nova_serialconsole_proxy_external
-  bind {{ kolla_external_vip_address }}:{{ nova_serialproxy_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['nova-serialproxy'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ nova_serialproxy_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-{% endif %}
-
-{% if enable_neutron | bool %}
-listen neutron_server
-  option http-tunnel
-  bind {{ kolla_internal_vip_address }}:{{ neutron_server_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['neutron-server'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ neutron_server_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen neutron_server_external
-  option http-tunnel
-  bind {{ kolla_external_vip_address }}:{{ neutron_server_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['neutron-server'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ neutron_server_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_horizon | bool %}
-listen horizon
-  bind {{ kolla_internal_vip_address }}:{{ horizon_port }}
-  balance source
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['horizon'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ horizon_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-{% if haproxy_enable_external_vip | bool %}
-{% if kolla_enable_tls_external | bool %}
-listen horizon_external
-  bind {{ kolla_external_vip_address }}:443 {{ tls_bind_info }}
-  balance source
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['horizon'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ horizon_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-frontend horizon_external_redirect
-   bind {{ kolla_external_vip_address }}:{{ horizon_port }}
-   redirect scheme https code 301 if !{ ssl_fc }
-{% else %}
-listen horizon_external
-  bind {{ kolla_external_vip_address }}:{{ horizon_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['horizon'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ horizon_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-{% endif %}
-
-{% if enable_cinder | bool %}
-listen cinder_api
-  bind {{ kolla_internal_vip_address }}:{{ cinder_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['cinder-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ cinder_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen cinder_api_external
-  bind {{ kolla_external_vip_address }}:{{ cinder_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['cinder-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ cinder_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_cloudkitty | bool %}
-listen cloudkitty_api
-  bind {{ kolla_internal_vip_address }}:{{ cloudkitty_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['cloudkitty-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ cloudkitty_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen cloudkitty_api_external
-  bind {{ kolla_external_vip_address }}:{{ cloudkitty_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['cloudkitty-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ cloudkitty_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_octavia | bool %}
-listen octavia_api
-  bind {{ kolla_internal_vip_address }}:{{ octavia_api_port }}
-  http-request del-header X-Forwarded-Proto
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['octavia-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ octavia_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-{% if haproxy_enable_external_vip | bool %}
-listen octavia_api_external
-  bind {{ kolla_external_vip_address }}:{{ octavia_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['octavia-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ octavia_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_panko | bool %}
-listen panko_api
-  bind {{ kolla_internal_vip_address }}:{{ panko_api_port }}
-  http-request del-header X-Forwarded-Proto
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['panko-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ panko_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen panko_api_external
-  bind {{ kolla_external_vip_address }}:{{ panko_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['panko-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ panko_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_heat | bool %}
-listen heat_api
-  bind {{ kolla_internal_vip_address }}:{{ heat_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['heat-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ heat_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen heat_api_cfn
-  bind {{ kolla_internal_vip_address }}:{{ heat_api_cfn_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['heat-api-cfn'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ heat_api_cfn_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen heat_api_external
-  bind {{ kolla_external_vip_address }}:{{ heat_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['heat-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ heat_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen heat_api_cfn_external
-  bind {{ kolla_external_vip_address }}:{{ heat_api_cfn_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['heat-api-cfn'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ heat_api_cfn_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_grafana | bool %}
-listen grafana_server
-  bind {{ kolla_internal_vip_address }}:{{ grafana_server_port }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['grafana'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ grafana_server_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen grafana_server_external
-  bind {{ kolla_external_vip_address }}:{{ grafana_server_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['grafana'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ grafana_server_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_ironic | bool %}
-listen ironic_api
-  bind {{ kolla_internal_vip_address }}:{{ ironic_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['ironic-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ ironic_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-listen ironic_inspector
-  bind {{ kolla_internal_vip_address }}:{{ ironic_inspector_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['ironic-inspector'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ ironic_inspector_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen ironic_api_external
-  bind {{ kolla_external_vip_address }}:{{ ironic_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['ironic-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ ironic_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-listen ironic_inspector_external
-  bind {{ kolla_external_vip_address }}:{{ ironic_inspector_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['ironic-inspector'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ ironic_inspector_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_karbor | bool %}
-listen karbor_api
-  bind {{ kolla_internal_vip_address }}:{{ karbor_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['karbor-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ karbor_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen karbor_api_external
-  bind {{ kolla_external_vip_address }}:{{ karbor_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['karbor-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ karbor_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-
-{% if enable_freezer | bool %}
-listen freezer_api
-  bind {{ kolla_internal_vip_address }}:{{ freezer_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['freezer-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ freezer_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen freezer_api_external
-  bind {{ kolla_external_vip_address }}:{{ freezer_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['freezer-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ freezer_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-
-{% if enable_senlin | bool %}
-listen senlin_api
-  bind {{ kolla_internal_vip_address }}:{{ senlin_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['senlin-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ senlin_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen senlin_api_external
-  bind {{ kolla_external_vip_address }}:{{ senlin_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['senlin-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ senlin_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_solum | bool %}
-listen solum_application_deployment
-  bind {{ kolla_internal_vip_address }}:{{ solum_application_deployment_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['solum-application-deployment'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ solum_application_deployment_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen solum_image_builder
-  bind {{ kolla_internal_vip_address }}:{{ solum_image_builder_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['solum-image-builder'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ solum_image_builder_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen solum_application_deployment_external
-  bind {{ kolla_external_vip_address }}:{{ solum_application_deployment_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['solum-application-deployment'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ solum_application_deployment_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen solum_image_builder_external
-  bind {{ kolla_external_vip_address }}:{{ solum_image_builder_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['solum-image-builder'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ solum_image_builder_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_swift | bool %}
-listen swift_api
-  bind {{ kolla_internal_vip_address }}:{{ swift_proxy_server_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['swift-proxy-server'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ swift_proxy_server_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen swift_api_external
-  bind {{ kolla_external_vip_address }}:{{ swift_proxy_server_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['swift-proxy-server'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ swift_proxy_server_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_murano | bool %}
-listen murano_api
-  bind {{ kolla_internal_vip_address }}:{{ murano_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['murano-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ murano_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen murano_api_external
-  bind {{ kolla_external_vip_address }}:{{ murano_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['murano-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ murano_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_manila | bool %}
-listen manila_api
-  bind {{ kolla_internal_vip_address }}:{{ manila_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['manila-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ manila_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen manila_api_external
-  bind {{ kolla_external_vip_address }}:{{ manila_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['manila-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ manila_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_magnum | bool %}
-listen magnum_api
-  bind {{ kolla_internal_vip_address }}:{{ magnum_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['magnum-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ magnum_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen magnum_api_external
-  bind {{ kolla_external_vip_address }}:{{ magnum_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['magnum-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ magnum_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_watcher | bool and enable_ceilometer | bool %}
-listen watcher_api
-  bind {{ kolla_internal_vip_address }}:{{ watcher_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['watcher-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ watcher_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen watcher_api_external
-  bind {{ kolla_external_vip_address }}:{{ watcher_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['watcher-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ watcher_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_sahara | bool %}
-listen sahara_api
-  bind {{ kolla_internal_vip_address }}:{{ sahara_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['sahara-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ sahara_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen sahara_api_external
-  bind {{ kolla_external_vip_address }}:{{ sahara_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['sahara-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ sahara_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_searchlight | bool %}
-listen searchlight_api
-  bind {{ kolla_internal_vip_address }}:{{ searchlight_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['searchlight-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ searchlight_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen searchlight_api_external
-  bind {{ kolla_external_vip_address }}:{{ searchlight_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['searchlight-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ searchlight_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_ceph | bool and enable_ceph_rgw | bool %}
-listen radosgw
-  bind {{ kolla_internal_vip_address }}:{{ rgw_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['ceph-rgw'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ rgw_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen radosgw_external
-  bind {{ kolla_external_vip_address }}:{{ rgw_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['ceph-rgw'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ rgw_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_kibana | bool %}
-
-userlist kibanauser
-  user {{ kibana_user }} insecure-password {{ kibana_password }}
-
-listen kibana
-  bind {{ kolla_internal_vip_address }}:{{ kibana_server_port }}
-  acl auth_acl http_auth(kibanauser)
-  http-request auth realm basicauth unless auth_acl
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['kibana'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ kibana_server_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen kibana_external
-  bind {{ kolla_external_vip_address }}:{{ kibana_server_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-  acl auth_acl http_auth(kibanauser)
-  http-request auth realm basicauth unless auth_acl
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['kibana'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ kibana_server_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_gnocchi | bool %}
-listen gnocchi_api
-  bind {{ kolla_internal_vip_address }}:{{ gnocchi_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['gnocchi-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ gnocchi_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen gnocchi_api_external
-  bind {{ kolla_external_vip_address }}:{{ gnocchi_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['gnocchi-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ gnocchi_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_elasticsearch | bool %}
-listen elasticsearch
-  option dontlog-normal
-  bind {{ kolla_internal_vip_address }}:{{ elasticsearch_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['elasticsearch'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ elasticsearch_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-
-{% if enable_barbican | bool %}
-listen barbican_api
-  bind {{ kolla_internal_vip_address }}:{{ barbican_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['barbican-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ barbican_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen barbican_api_external
-  bind {{ kolla_external_vip_address }}:{{ barbican_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['barbican-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ barbican_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_aodh | bool %}
-listen aodh_api
-  bind {{ kolla_internal_vip_address }}:{{ aodh_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['aodh-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ aodh_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen aodh_api_external
-  bind {{ kolla_external_vip_address }}:{{ aodh_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['aodh-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ aodh_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_trove | bool %}
-listen trove_api
-  bind {{ kolla_internal_vip_address }}:{{ trove_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['trove-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ trove_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen trove_api_external
-  bind {{ kolla_external_vip_address }}:{{ trove_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['trove-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ trove_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_congress | bool %}
-listen congress_api
-  bind {{ kolla_internal_vip_address }}:{{ congress_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['congress-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ congress_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen congress_api_external
-  bind {{ kolla_external_vip_address }}:{{ congress_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['congress-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ congress_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_designate | bool %}
-listen designate_api
-  bind {{ kolla_internal_vip_address }}:{{ designate_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['designate-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ designate_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen designate_api_external
-  bind {{ kolla_external_vip_address }}:{{ designate_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for host in groups['designate-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ designate_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_mistral | bool %}
-listen mistral_api
-  bind {{ kolla_internal_vip_address }}:{{ mistral_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['mistral-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ mistral_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen mistral_api_external
-  bind {{ kolla_external_vip_address }}:{{ mistral_api_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['mistral-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ mistral_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_tacker | bool %}
-listen tacker_server
-  bind {{ kolla_internal_vip_address }}:{{ tacker_server_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['tacker'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ tacker_server_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen tacker_server_external
-  bind {{ kolla_external_vip_address }}:{{ tacker_server_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['tacker'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ tacker_server_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_zun | bool %}
-listen zun_api
-  bind {{ kolla_internal_vip_address }}:{{ zun_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['zun-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ zun_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen zun_wsproxy
-  bind {{ kolla_internal_vip_address }}:{{ zun_wsproxy_port }}
-  http-request del-header X-Forwarded-Proto if { ssl_fc }
-{% for host in groups['zun-wsproxy'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ zun_wsproxy_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen zun_api_external
-  bind {{ kolla_external_vip_address }}:{{ zun_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['zun-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ zun_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-
-listen zun_wsproxy_external
-  bind {{ kolla_external_vip_address }}:{{ zun_wsproxy_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['zun-wsproxy'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ zun_wsproxy_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_skydive | bool %}
-listen skydive_server
-  bind {{ kolla_internal_vip_address }}:{{ skydive_analyzer_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['skydive-analyzer'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ skydive_analyzer_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen skydive_server_external
-  bind {{ kolla_external_vip_address }}:{{ skydive_analyzer_port }} {{ tls_bind_info }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['skydive-analyzer'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ skydive_analyzer_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_vitrage | bool %}
-listen vitrage_api
-  bind {{ kolla_internal_vip_address }}:{{ vitrage_api_port }}
-  http-request del-header X-Forwarded-Proto
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['vitrage-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ vitrage_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen vitrage_api_external
-  bind {{ kolla_external_vip_address }}:{{ vitrage_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['vitrage-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ vitrage_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_blazar | bool %}
-listen blazar_api
-  bind {{ kolla_internal_vip_address }}:{{ blazar_api_port }}
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-  http-request del-header X-Forwarded-Proto
-{% for host in groups['blazar-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ blazar_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen blazar_api_external
-  bind {{ kolla_external_vip_address }}:{{ blazar_api_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['blazar-api'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ blazar_api_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
-
-{% if enable_prometheus | bool %}
-listen prometheus_server
-  bind {{ kolla_internal_vip_address }}:{{ prometheus_port }}
-  http-request del-header X-Forwarded-Proto
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['prometheus'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ prometheus_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-
-# (NOTE): This defaults section deletes forwardfor as recommended by:
-#         https://marc.info/?l=haproxy&m=141684110710132&w=1
-
-defaults
-  log global
-  mode http
-  option redispatch
-  option httplog
-  retries 3
-  timeout http-request 10s
-  timeout queue 1m
-  timeout connect 10s
-  timeout client {{ haproxy_client_timeout }}
-  timeout server {{ haproxy_server_timeout }}
-  timeout check 10s
-
-{% if enable_mariadb | bool or enable_external_mariadb_load_balancer | bool %}
-listen mariadb
-  mode tcp
-  timeout client 3600s
-  timeout server 3600s
-  option tcplog
-  option tcpka
-{% if not enable_external_mariadb_load_balancer | bool %}
-  option mysql-check user haproxy post-41
-{% endif %}
-  bind {{ kolla_internal_vip_address }}:{{ mariadb_port }}
-{% for tcp_option in haproxy_listen_tcp_extra %}
-  {{ tcp_option }}
-{% endfor %}
-{% for host in groups['mariadb'] %}
-
-{% if not enable_external_mariadb_load_balancer | bool %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ mariadb_port }} check inter 2000 rise 2 fall 5 {% if not loop.first %}backup{% endif %}
-{% else %}
-  server {{ host }} {{ host }}:{{ mariadb_port }} check inter 2000 rise 2 fall 5 {% if not loop.first %}backup{% endif %}
-{% endif %}
-{% endfor %}
-{% endif %}
-
-{% if enable_memcached | bool and enable_haproxy_memcached | bool %}
-listen memcached
-  mode tcp
-  timeout client 3600s
-  timeout server 3600s
-  option tcplog
-  option tcpka
-{% for tcp_option in haproxy_listen_tcp_extra %}
-  {{ tcp_option }}
-{% endfor %}
-  bind {{ kolla_internal_vip_address }}:{{ memcached_port }}
-{% for host in groups['memcached'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ memcached_port }} check inter 2000 rise 2 fall 5 {% if not loop.first %}backup{% endif %}
-
-{% endfor %}
-{% endif %}
-
-{% if enable_opendaylight | bool %}
-listen opendaylight_api
-  bind {{ kolla_internal_vip_address }}:{{ opendaylight_haproxy_restconf_port }}
-  balance source
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['opendaylight'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ opendaylight_restconf_port }} check fall 5 inter 2000 rise 2
-{% endfor %}
-
-listen opendaylight_api_backup
-  bind {{ kolla_internal_vip_address }}:{{ opendaylight_haproxy_restconf_port_backup }}
-  balance source
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['opendaylight'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ opendaylight_restconf_port_backup }} check fall 5 inter 2000 rise 2
-{% endfor %}
-
-listen opendaylight_websocket
-  bind {{ kolla_internal_vip_address }}:{{ opendaylight_websocket_port }}
-  balance source
-{% for host in groups['opendaylight'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ opendaylight_websocket_port }} check fall 5 inter 2000 rise 2
-{% endfor %}
-
-{% endif %}
-
-{% if enable_prometheus_alertmanager | bool %}
-
-userlist prometheus-alertmanager-user
-  user {{ prometheus_alertmanager_user }} insecure-password {{ prometheus_alertmanager_password }}
-
-listen prometheus_alertmanager
-  bind {{ kolla_internal_vip_address }}:{{ prometheus_alertmanager_port }}
-  acl auth_acl http_auth(prometheus-alertmanager-user)
-  http-request auth realm basicauth unless auth_acl
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['prometheus-alertmanager'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ prometheus_alertmanager_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% if haproxy_enable_external_vip | bool %}
-
-listen prometheus_alertmanager_external
-  bind {{ kolla_external_vip_address }}:{{ prometheus_alertmanager_port }} {{ tls_bind_info }}
-  http-request del-header X-Forwarded-Proto
-  http-request set-header X-Forwarded-Proto https if { ssl_fc }
-  acl auth_acl http_auth(prometheus-alertmanager-user)
-  http-request auth realm basicauth unless auth_acl
-{% for http_option in haproxy_listen_http_extra %}
-  {{ http_option }}
-{% endfor %}
-{% for host in groups['prometheus-alertmanager'] %}
-  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ prometheus_alertmanager_port }} check inter 2000 rise 2 fall 5
-{% endfor %}
-{% endif %}
-{% endif %}
diff --git a/ansible/roles/haproxy/templates/haproxy.json.j2 b/ansible/roles/haproxy/templates/haproxy.json.j2
index 31ed4c5972..9cd43adb94 100644
--- a/ansible/roles/haproxy/templates/haproxy.json.j2
+++ b/ansible/roles/haproxy/templates/haproxy.json.j2
@@ -1,13 +1,24 @@
-{% set haproxy_cmd='/usr/sbin/haproxy -W -db' if kolla_base_distro in ['ubuntu']  else '/usr/sbin/haproxy-systemd-wrapper' %}
 {
-    "command": "{{ haproxy_cmd }} -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid",
+    "command": "/etc/haproxy/haproxy_run.sh",
     "config_files": [
+        {
+            "source": "{{ container_config_directory }}/haproxy_run.sh",
+            "dest": "/etc/haproxy/haproxy_run.sh",
+            "owner": "root",
+            "perm": "0700"
+        },
         {
             "source": "{{ container_config_directory }}/haproxy.cfg",
             "dest": "/etc/haproxy/haproxy.cfg",
             "owner": "root",
             "perm": "0600"
         },
+        {
+            "source": "{{ container_config_directory }}/services.d/",
+            "dest": "/etc/haproxy/services.d",
+            "owner": "root",
+            "perm": "0700"
+        },
         {
             "source": "{{ container_config_directory }}/haproxy.pem",
             "dest": "/etc/haproxy/haproxy.pem",
diff --git a/ansible/roles/haproxy/templates/haproxy_main.cfg.j2 b/ansible/roles/haproxy/templates/haproxy_main.cfg.j2
new file mode 100644
index 0000000000..34f2c453a6
--- /dev/null
+++ b/ansible/roles/haproxy/templates/haproxy_main.cfg.j2
@@ -0,0 +1,49 @@
+#jinja2: lstrip_blocks: True
+global
+    chroot /var/lib/haproxy
+    user haproxy
+    group haproxy
+    daemon
+    log {{ syslog_server }}:{{ syslog_udp_port }} {{ syslog_haproxy_facility }}
+    maxconn {{ haproxy_max_connections }}
+    nbproc {{ haproxy_processes }}
+    {% if haproxy_processes > 1 and haproxy_process_cpu_map | bool %}
+        {% for cpu_idx in range(0, haproxy_processes) %}
+    cpu-map {{ cpu_idx + 1 }} {{ cpu_idx }}
+        {% endfor %}
+    {% endif %}
+    stats socket /var/lib/kolla/haproxy/haproxy.sock group kolla mode 660
+    {% if kolla_enable_tls_external | bool %}
+    ssl-default-bind-ciphers DEFAULT:!MEDIUM:!3DES
+    ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
+    tune.ssl.default-dh-param 4096
+    {% endif %}
+
+defaults
+    log global
+    option redispatch
+    retries 3
+    timeout http-request {{ haproxy_http_request_timeout }}
+    timeout queue {{ haproxy_queue_timeout }}
+    timeout connect {{ haproxy_connect_timeout }}
+    timeout client {{ haproxy_client_timeout }}
+    timeout server {{ haproxy_server_timeout }}
+    timeout check {{ haproxy_check_timeout }}
+    balance {{ haproxy_defaults_balance }}
+
+listen stats
+   bind {{ api_interface_address }}:{{ haproxy_stats_port }}
+   mode http
+   stats enable
+   stats uri /
+   stats refresh 15s
+   stats realm Haproxy\ Stats
+   stats auth {{ haproxy_user }}:{{ haproxy_password }}
+
+frontend status
+    bind {{ api_interface_address }}:{{ haproxy_monitor_port }}
+    {% if api_interface_address != kolla_internal_vip_address %}
+    bind {{ kolla_internal_vip_address }}:{{ haproxy_monitor_port }}
+    {% endif %}
+    mode http
+    monitor-uri /
diff --git a/ansible/roles/haproxy/templates/haproxy_run.sh.j2 b/ansible/roles/haproxy/templates/haproxy_run.sh.j2
new file mode 100644
index 0000000000..9419e70e67
--- /dev/null
+++ b/ansible/roles/haproxy/templates/haproxy_run.sh.j2
@@ -0,0 +1,10 @@
+#!/bin/bash -x
+{% set haproxy_cmd='/usr/sbin/haproxy -W -db' if kolla_base_distro in ['ubuntu']  else '/usr/sbin/haproxy-systemd-wrapper' %}
+
+# We need to run haproxy with one `-f` for each service, because including an
+# entire config directory was not a feature until version 1.7 of HAProxy.
+# So, append "-f $cfg" to the haproxy command for each service file.
+# This will run haproxy_cmd *exactly once*.
+find /etc/haproxy/services.d/ -mindepth 1 -print0 | \
+    xargs -0 -Icfg echo -f cfg | \
+    xargs {{ haproxy_cmd }} -p /run/haproxy.pid -f /etc/haproxy/haproxy.cfg
diff --git a/ansible/roles/heat/defaults/main.yml b/ansible/roles/heat/defaults/main.yml
index ecfe421385..078adf2beb 100644
--- a/ansible/roles/heat/defaults/main.yml
+++ b/ansible/roles/heat/defaults/main.yml
@@ -13,6 +13,17 @@ heat_services:
       - "{{ kolla_dev_repos_directory ~ '/heat/heat:/var/lib/kolla/venv/lib/python2.7/site-packages/heat' if heat_dev_mode | bool else '' }}"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ heat_api_dimensions }}"
+    haproxy:
+      heat_api:
+        enabled: "{{ enable_heat }}"
+        mode: "http"
+        external: false
+        port: "{{ heat_api_port }}"
+      heat_api_external:
+        enabled: "{{ enable_heat }}"
+        mode: "http"
+        external: true
+        port: "{{ heat_api_port }}"
   heat-api-cfn:
     container_name: heat_api_cfn
     group: heat-api-cfn
@@ -24,6 +35,17 @@ heat_services:
       - "{{ kolla_dev_repos_directory ~ '/heat/heat:/var/lib/kolla/venv/lib/python2.7/site-packages/heat' if heat_dev_mode | bool else '' }}"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ heat_api_cfn_dimensions }}"
+    haproxy:
+      heat_api_cfn:
+        enabled: "{{ enable_heat }}"
+        mode: "http"
+        external: false
+        port: "{{ heat_api_cfn_port }}"
+      heat_api_cfn_external:
+        enabled: "{{ enable_heat }}"
+        mode: "http"
+        external: true
+        port: "{{ heat_api_cfn_port }}"
   heat-engine:
     container_name: heat_engine
     group: heat-engine
diff --git a/ansible/roles/heat/tasks/loadbalancer.yml b/ansible/roles/heat/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..ddce7154e4
--- /dev/null
+++ b/ansible/roles/heat/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ heat_services }}"
+  tags: always
diff --git a/ansible/roles/horizon/defaults/main.yml b/ansible/roles/horizon/defaults/main.yml
index 71fa903211..8322668753 100644
--- a/ansible/roles/horizon/defaults/main.yml
+++ b/ansible/roles/horizon/defaults/main.yml
@@ -43,6 +43,26 @@ horizon_services:
       - "kolla_logs:/var/log/kolla/"
       - "/tmp:/tmp"
     dimensions: "{{ horizon_dimensions }}"
+    haproxy:
+      horizon:
+        enabled: "{{ enable_horizon }}"
+        mode: "http"
+        external: false
+        port: "{{ horizon_port }}"
+        frontend_http_extra:
+          - "balance source"
+      horizon_external:
+        enabled: "{{ enable_horizon }}"
+        mode: "http"
+        external: true
+        port: "{% if kolla_enable_tls_external|bool %}443{% else %}{{ horizon_port }}{% endif %}"
+        frontend_http_extra:
+          - "balance source"
+      horizon_external_redirect:
+        enabled: "{{ enable_horizon|bool and kolla_enable_tls_external|bool }}"
+        mode: "redirect"
+        external: true
+        port: "{{ horizon_port }}"
 horizon_keystone_domain_choices:
   Default: default
 
diff --git a/ansible/roles/horizon/tasks/loadbalancer.yml b/ansible/roles/horizon/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..4a16fc14c1
--- /dev/null
+++ b/ansible/roles/horizon/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ horizon_services }}"
+  tags: always
diff --git a/ansible/roles/influxdb/defaults/main.yml b/ansible/roles/influxdb/defaults/main.yml
index 76f06a8074..f6e8596bbc 100644
--- a/ansible/roles/influxdb/defaults/main.yml
+++ b/ansible/roles/influxdb/defaults/main.yml
@@ -13,6 +13,17 @@ influxdb_services:
       - "influxdb:/var/lib/influxdb"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ influxdb_dimensions }}"
+    haproxy:
+      influxdb_admin:
+        enabled: "{{ enable_influxdb }}"
+        mode: "http"
+        external: false
+        port: "{{ influxdb_admin_port }}"
+      influxdb_http:
+        enabled: "{{ enable_influxdb }}"
+        mode: "http"
+        external: false
+        port: "{{ influxdb_http_port }}"
 
 
 ####################
diff --git a/ansible/roles/influxdb/tasks/loadbalancer.yml b/ansible/roles/influxdb/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..37a0ac7771
--- /dev/null
+++ b/ansible/roles/influxdb/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ influxdb_services }}"
+  tags: always
diff --git a/ansible/roles/ironic/defaults/main.yml b/ansible/roles/ironic/defaults/main.yml
index ddd26e9415..6e1628ffa7 100644
--- a/ansible/roles/ironic/defaults/main.yml
+++ b/ansible/roles/ironic/defaults/main.yml
@@ -13,6 +13,17 @@ ironic_services:
       - "kolla_logs:/var/log/kolla"
       - "{{ kolla_dev_repos_directory ~ '/ironic/ironic:/var/lib/kolla/venv/lib/python2.7/site-packages/ironic' if ironic_dev_mode | bool else '' }}"
     dimensions: "{{ ironic_api_dimensions }}"
+    haproxy:
+      ironic_api:
+        enabled: "{{ enable_ironic }}"
+        mode: "http"
+        external: false
+        port: "{{ ironic_api_port }}"
+      ironic_api_external:
+        enabled: "{{ enable_ironic }}"
+        mode: "http"
+        external: true
+        port: "{{ ironic_api_port }}"
   ironic-conductor:
     container_name: ironic_conductor
     group: ironic-conductor
@@ -44,6 +55,17 @@ ironic_services:
       - "kolla_logs:/var/log/kolla"
       - "{{ kolla_dev_repos_directory ~ '/ironic-inspector/ironic_inspector:/var/lib/kolla/venv/lib/python2.7/site-packages/ironic_inspector' if ironic_dev_mode | bool else '' }}"
     dimensions: "{{ ironic_inspector_dimensions }}"
+    haproxy:
+      ironic_inspector:
+        enabled: "{{ enable_ironic }}"
+        mode: "http"
+        external: false
+        port: "{{ ironic_inspector_port }}"
+      ironic_inspector_external:
+        enabled: "{{ enable_ironic }}"
+        mode: "http"
+        external: true
+        port: "{{ ironic_inspector_port }}"
   ironic-pxe:
     container_name: ironic_pxe
     group: ironic-pxe
diff --git a/ansible/roles/ironic/tasks/loadbalancer.yml b/ansible/roles/ironic/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..5dc896f19f
--- /dev/null
+++ b/ansible/roles/ironic/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ ironic_services }}"
+  tags: always
diff --git a/ansible/roles/karbor/defaults/main.yml b/ansible/roles/karbor/defaults/main.yml
index aed8e0ef0b..209d3a4142 100644
--- a/ansible/roles/karbor/defaults/main.yml
+++ b/ansible/roles/karbor/defaults/main.yml
@@ -12,6 +12,17 @@ karbor_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ karbor_api_dimensions }}"
+    haproxy:
+      karbor_api:
+        enabled: "{{ enable_karbor }}"
+        mode: "http"
+        external: false
+        port: "{{ karbor_api_port }}"
+      karbor_api_external:
+        enabled: "{{ enable_karbor }}"
+        mode: "http"
+        external: true
+        port: "{{ karbor_api_port }}"
   karbor-protection:
     container_name: karbor_protection
     group: karbor-protection
diff --git a/ansible/roles/karbor/tasks/loadbalancer.yml b/ansible/roles/karbor/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..4ddb12f67d
--- /dev/null
+++ b/ansible/roles/karbor/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ karbor_services }}"
+  tags: always
diff --git a/ansible/roles/keystone/defaults/main.yml b/ansible/roles/keystone/defaults/main.yml
index 25afb256b5..64c40b1100 100644
--- a/ansible/roles/keystone/defaults/main.yml
+++ b/ansible/roles/keystone/defaults/main.yml
@@ -14,6 +14,22 @@ keystone_services:
       - "kolla_logs:/var/log/kolla/"
       - "{% if keystone_token_provider == 'fernet' %}keystone_fernet_tokens:/etc/keystone/fernet-keys{% endif %}"
     dimensions: "{{ keystone_dimensions }}"
+    haproxy:
+      keystone_internal:
+        enabled: "{{ enable_keystone }}"
+        mode: "http"
+        external: false
+        port: "{{ keystone_public_port }}"
+      keystone_external:
+        enabled: "{{ enable_keystone }}"
+        mode: "http"
+        external: true
+        port: "{{ keystone_public_port }}"
+      keystone_admin:
+        enabled: "{{ enable_keystone }}"
+        mode: "http"
+        external: false
+        port: "{{ keystone_admin_port }}"
   keystone-ssh:
     container_name: "keystone_ssh"
     group: "keystone"
diff --git a/ansible/roles/keystone/tasks/loadbalancer.yml b/ansible/roles/keystone/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..8983ab529a
--- /dev/null
+++ b/ansible/roles/keystone/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ keystone_services }}"
+  tags: always
diff --git a/ansible/roles/kibana/defaults/main.yml b/ansible/roles/kibana/defaults/main.yml
index b6c2bc8dea..f917f85490 100644
--- a/ansible/roles/kibana/defaults/main.yml
+++ b/ansible/roles/kibana/defaults/main.yml
@@ -12,6 +12,21 @@ kibana_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ kibana_dimensions }}"
+    haproxy:
+      kibana:
+        enabled: "{{ enable_kibana }}"
+        mode: "http"
+        external: false
+        port: "{{ kibana_server_port }}"
+        auth_user: "{{ kibana_user }}"
+        auth_pass: "{{ kibana_password }}"
+      kibana_external:
+        enabled: "{{ enable_kibana }}"
+        mode: "http"
+        external: true
+        port: "{{ kibana_server_port }}"
+        auth_user: "{{ kibana_user }}"
+        auth_pass: "{{ kibana_password }}"
 
 
 ####################
diff --git a/ansible/roles/kibana/tasks/loadbalancer.yml b/ansible/roles/kibana/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..e3b452aefc
--- /dev/null
+++ b/ansible/roles/kibana/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ kibana_services }}"
+  tags: always
diff --git a/ansible/roles/magnum/defaults/main.yml b/ansible/roles/magnum/defaults/main.yml
index 5c9cbb5d7b..781bc1f81b 100644
--- a/ansible/roles/magnum/defaults/main.yml
+++ b/ansible/roles/magnum/defaults/main.yml
@@ -15,6 +15,17 @@ magnum_services:
       - "{{ kolla_dev_repos_directory ~ '/magnum/magnum:/var/lib/kolla/venv/lib/python2.7/site-packages/magnum' if magnum_dev_mode | bool else '' }}"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ magnum_api_dimensions }}"
+    haproxy:
+      magnum_api:
+        enabled: "{{ enable_magnum }}"
+        mode: "http"
+        external: false
+        port: "{{ magnum_api_port }}"
+      magnum_api_external:
+        enabled: "{{ enable_magnum }}"
+        mode: "http"
+        external: true
+        port: "{{ magnum_api_port }}"
   magnum-conductor:
     container_name: magnum_conductor
     group: magnum-conductor
diff --git a/ansible/roles/magnum/tasks/loadbalancer.yml b/ansible/roles/magnum/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..0356c77cd0
--- /dev/null
+++ b/ansible/roles/magnum/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ magnum_services }}"
+  tags: always
diff --git a/ansible/roles/manila/defaults/main.yml b/ansible/roles/manila/defaults/main.yml
index b77abbc625..dcdb783905 100644
--- a/ansible/roles/manila/defaults/main.yml
+++ b/ansible/roles/manila/defaults/main.yml
@@ -13,6 +13,17 @@ manila_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/manila/manila:/var/lib/kolla/venv/lib/python2.7/site-packages/manila' if manila_dev_mode | bool else '' }}"
     dimensions: "{{ manila_api_dimensions }}"
+    haproxy:
+      manila_api:
+        enabled: "{{ enable_manila }}"
+        mode: "http"
+        external: false
+        port: "{{ manila_api_port }}"
+      manila_api_external:
+        enabled: "{{ enable_manila }}"
+        mode: "http"
+        external: true
+        port: "{{ manila_api_port }}"
   manila-scheduler:
     container_name: "manila_scheduler"
     group: "manila-scheduler"
diff --git a/ansible/roles/manila/tasks/loadbalancer.yml b/ansible/roles/manila/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..9204d82f77
--- /dev/null
+++ b/ansible/roles/manila/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ manila_services }}"
+  tags: always
diff --git a/ansible/roles/mariadb/defaults/main.yml b/ansible/roles/mariadb/defaults/main.yml
index 3d3870d256..0b07e68035 100644
--- a/ansible/roles/mariadb/defaults/main.yml
+++ b/ansible/roles/mariadb/defaults/main.yml
@@ -13,7 +13,30 @@ mariadb_services:
       - "mariadb:/var/lib/mysql"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ mariadb_dimensions }}"
-
+    haproxy:
+      mariadb:
+        enabled: "{{ enable_mariadb|bool and not enable_external_mariadb_load_balancer|bool }}"
+        mode: "tcp"
+        port: "{{ mariadb_port }}"
+        frontend_tcp_extra:
+          - "option clitcpka"
+          - "timeout client 3600s"
+        backend_tcp_extra:
+          - "option srvtcpka"
+          - "timeout server 3600s"
+          - "option mysql-check user haproxy post-41"
+        custom_member_list: "{{ internal_haproxy_members.split(';') }}"
+      mariadb_external_lb:
+        enabled: "{{ enable_mariadb|bool and enable_external_mariadb_load_balancer|bool }}"
+        mode: "tcp"
+        port: "{{ mariadb_port }}"
+        frontend_tcp_extra:
+          - "option clitcpka"
+          - "timeout client 3600s"
+        backend_tcp_extra:
+          - "option srvtcpka"
+          - "timeout server 3600s"
+        custom_member_list: "{{ external_haproxy_members.split(';') }}"
 
 ####################
 # Database
@@ -21,6 +44,12 @@ mariadb_services:
 database_cluster_name: "openstack"
 database_max_timeout: 120
 
+####################
+# HAProxy
+####################
+internal_haproxy_members: "{% for host in groups['mariadb'] %}server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ mariadb_port }} check inter 2000 rise 2 fall 5{% if not loop.first %} backup{% endif %};{% endfor %}"
+external_haproxy_members: "{% for host in groups['mariadb'] %}server {{ host }} {{ host }}:{{ mariadb_port }} check inter 2000 rise 2 fall 5{% if not loop.first %} backup{% endif %};{% endfor %}"
+
 ####################
 # Docker
 ####################
diff --git a/ansible/roles/mariadb/tasks/loadbalancer.yml b/ansible/roles/mariadb/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..c72b8f0b79
--- /dev/null
+++ b/ansible/roles/mariadb/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ mariadb_services }}"
+  tags: always
diff --git a/ansible/roles/memcached/defaults/main.yml b/ansible/roles/memcached/defaults/main.yml
index 604ac565b6..f41635ede8 100644
--- a/ansible/roles/memcached/defaults/main.yml
+++ b/ansible/roles/memcached/defaults/main.yml
@@ -11,7 +11,23 @@ memcached_services:
       - "{{ node_config_directory }}/memcached/:{{ container_config_directory }}/:ro"
       - "/etc/localtime:/etc/localtime:ro"
     dimensions: "{{ memcached_dimensions }}"
+    haproxy:
+      memcached:
+        enabled: "{{ enable_memcached|bool and enable_haproxy_memcached|bool }}"
+        mode: "tcp"
+        port: "{{ memcached_port }}"
+        frontend_tcp_extra:
+          - "option clitcpka"
+          - "timeout client 3600s"
+        backend_tcp_extra:
+          - "option srvtcpka"
+          - "timeout server 3600s"
+        custom_member_list: "{{ haproxy_members.split(';') }}"
 
+####################
+# HAProxy
+####################
+haproxy_members: "{% for host in groups['memcached'] %}server {{ host }} {{ host }}:{{ memcached_port }} check inter 2000 rise 2 fall 5{% if not loop.first %} backup{% endif %};{% endfor %}"
 
 ####################
 # Docker
diff --git a/ansible/roles/memcached/tasks/loadbalancer.yml b/ansible/roles/memcached/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..b21c7632a8
--- /dev/null
+++ b/ansible/roles/memcached/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ memcached_services }}"
+  tags: always
diff --git a/ansible/roles/mistral/defaults/main.yml b/ansible/roles/mistral/defaults/main.yml
index a4fa556e44..9eaafe843c 100644
--- a/ansible/roles/mistral/defaults/main.yml
+++ b/ansible/roles/mistral/defaults/main.yml
@@ -13,6 +13,17 @@ mistral_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/mistral/mistral:/var/lib/kolla/venv/lib/python2.7/site-packages/mistral' if mistral_dev_mode | bool else '' }}"
     dimensions: "{{ mistral_api_dimensions }}"
+    haproxy:
+      mistral_api:
+        enabled: "{{ enable_mistral }}"
+        mode: "http"
+        external: false
+        port: "{{ mistral_api_port }}"
+      mistral_api_external:
+        enabled: "{{ enable_mistral }}"
+        mode: "http"
+        external: true
+        port: "{{ mistral_api_port }}"
   mistral-engine:
     container_name: mistral_engine
     group: mistral-engine
diff --git a/ansible/roles/mistral/tasks/loadbalancer.yml b/ansible/roles/mistral/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..2dd1f3ccd1
--- /dev/null
+++ b/ansible/roles/mistral/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ mistral_services }}"
+  tags: always
diff --git a/ansible/roles/monasca/defaults/main.yml b/ansible/roles/monasca/defaults/main.yml
index 309d545dd3..ee71601227 100644
--- a/ansible/roles/monasca/defaults/main.yml
+++ b/ansible/roles/monasca/defaults/main.yml
@@ -10,6 +10,17 @@ monasca_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "kolla_logs:/var/log/kolla"
     dimensions: "{{ monasca_api_dimensions }}"
+    haproxy:
+      monasca_api:
+        enabled: "{{ enable_monasca }}"
+        mode: "http"
+        external: false
+        port: "{{ monasca_api_port }}"
+      monasca_api_external:
+        enabled: "{{ enable_monasca }}"
+        mode: "http"
+        external: true
+        port: "{{ monasca_api_port }}"
   monasca-log-api:
     container_name: monasca_log_api
     group: monasca-log-api
@@ -20,6 +31,17 @@ monasca_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "kolla_logs:/var/log/kolla"
     dimensions: "{{ monasca_log_api_dimensions }}"
+    haproxy:
+      monasca_log_api:
+        enabled: "{{ enable_monasca }}"
+        mode: "http"
+        external: false
+        port: "{{ monasca_log_api_port }}"
+      monasca_log_api_external:
+        enabled: "{{ enable_monasca }}"
+        mode: "http"
+        external: true
+        port: "{{ monasca_log_api_port }}"
   monasca-log-transformer:
     container_name: monasca_log_transformer
     group: monasca-log-transformer
diff --git a/ansible/roles/monasca/tasks/loadbalancer.yml b/ansible/roles/monasca/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..2aa16b070c
--- /dev/null
+++ b/ansible/roles/monasca/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ monasca_services }}"
+  tags: always
diff --git a/ansible/roles/mongodb/defaults/main.yml b/ansible/roles/mongodb/defaults/main.yml
index 9885eedbe8..25b3af8844 100644
--- a/ansible/roles/mongodb/defaults/main.yml
+++ b/ansible/roles/mongodb/defaults/main.yml
@@ -14,6 +14,12 @@ mongodb_services:
       - "kolla_logs:/var/log/kolla/"
       - "mongodb:/var/lib/mongodb"
     dimensions: "{{ mongodb_dimensions }}"
+    haproxy:
+      mongodb:
+        enabled: "{{ enable_mongodb }}"
+        mode: "http"
+        external: false
+        port: "{{ mongodb_port }}"
 
 
 ####################
diff --git a/ansible/roles/mongodb/tasks/loadbalancer.yml b/ansible/roles/mongodb/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..070834d4e7
--- /dev/null
+++ b/ansible/roles/mongodb/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ mongodb_services }}"
+  tags: always
diff --git a/ansible/roles/murano/defaults/main.yml b/ansible/roles/murano/defaults/main.yml
index da5f950975..74bcf52f3a 100644
--- a/ansible/roles/murano/defaults/main.yml
+++ b/ansible/roles/murano/defaults/main.yml
@@ -13,6 +13,17 @@ murano_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ murano_api_dimensions }}"
+    haproxy:
+      murano_api:
+        enabled: "{{ enable_murano }}"
+        mode: "http"
+        external: false
+        port: "{{ murano_api_port }}"
+      murano_api_external:
+        enabled: "{{ enable_murano }}"
+        mode: "http"
+        external: true
+        port: "{{ murano_api_port }}"
   murano-engine:
     container_name: murano_engine
     group: murano-engine
diff --git a/ansible/roles/murano/tasks/loadbalancer.yml b/ansible/roles/murano/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..7fa492b737
--- /dev/null
+++ b/ansible/roles/murano/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ murano_services }}"
+  tags: always
diff --git a/ansible/roles/neutron/defaults/main.yml b/ansible/roles/neutron/defaults/main.yml
index 640d790965..eba7335bba 100644
--- a/ansible/roles/neutron/defaults/main.yml
+++ b/ansible/roles/neutron/defaults/main.yml
@@ -13,6 +13,19 @@ neutron_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ neutron_server_dimensions }}"
+    haproxy:
+      neutron_server:
+        enabled: "{{ enable_neutron }}"
+        mode: "http"
+        external: false
+        port: "{{ neutron_server_port }}"
+        frontend_http_extra:
+          - "option http-tunnel"
+      neutron_server_external:
+        enabled: "{{ enable_neutron }}"
+        mode: "http"
+        external: true
+        port: "{{ neutron_server_port }}"
   neutron-openvswitch-agent:
     container_name: "neutron_openvswitch_agent"
     image: "{{ neutron_openvswitch_agent_image_full }}"
diff --git a/ansible/roles/neutron/tasks/loadbalancer.yml b/ansible/roles/neutron/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..aaa85b1e62
--- /dev/null
+++ b/ansible/roles/neutron/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ neutron_services }}"
+  tags: always
diff --git a/ansible/roles/nova/defaults/main.yml b/ansible/roles/nova/defaults/main.yml
index f57e37fad2..1ab5eb0cfc 100644
--- a/ansible/roles/nova/defaults/main.yml
+++ b/ansible/roles/nova/defaults/main.yml
@@ -47,6 +47,17 @@ nova_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/nova/nova:/var/lib/kolla/venv/lib/python2.7/site-packages/nova' if nova_dev_mode | bool else '' }}"
     dimensions: "{{ placement_api_dimensions }}"
+    haproxy:
+      placement_api:
+        enabled: "{{ enable_nova }}"
+        mode: "http"
+        external: false
+        port: "{{ placement_api_port }}"
+      placement_api_external:
+        enabled: "{{ enable_nova }}"
+        mode: "http"
+        external: true
+        port: "{{ placement_api_port }}"
   nova-api:
     container_name: "nova_api"
     group: "nova-api"
@@ -60,6 +71,33 @@ nova_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/nova/nova:/var/lib/kolla/venv/lib/python2.7/site-packages/nova' if nova_dev_mode | bool else '' }}"
     dimensions: "{{ nova_api_dimensions }}"
+    haproxy:
+      nova_api:
+        enabled: "{{ enable_nova }}"
+        mode: "http"
+        external: false
+        port: "{{ nova_api_port }}"
+      nova_api_external:
+        enabled: "{{ enable_nova }}"
+        mode: "http"
+        external: true
+        port: "{{ nova_api_port }}"
+      nova_metadata:
+        enabled: "{{ enable_nova }}"
+        mode: "http"
+        external: false
+        port: "{{ nova_metadata_port }}"
+      nova_metadata_external:
+        enabled: "{{ enable_nova }}"
+        mode: "http"
+        external: true
+        port: "{{ nova_metadata_port }}"
+      nova_rdp:
+        enabled: "{{ enable_nova|bool and nova_console == 'rdp' }}"
+        mode: "http"
+        external: false
+        port: "{{ rdp_port }}"
+        host_group: "hyperv"
   nova-consoleauth:
     container_name: "nova_consoleauth"
     group: "nova-consoleauth"
@@ -82,6 +120,19 @@ nova_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/nova/nova:/var/lib/kolla/venv/lib/python2.7/site-packages/nova' if nova_dev_mode | bool else '' }}"
     dimensions: "{{ nova_novncproxy_dimensions }}"
+    haproxy:
+      nova_novncproxy:
+        enabled: "{{ enable_nova|bool and nova_console == 'novnc' }}"
+        mode: "http"
+        external: false
+        port: "{{ nova_novncproxy_port }}"
+        backend_http_extra:
+          - "timeout tunnel 1h"
+      nova_novncproxy_external:
+        enabled: "{{ enable_nova|bool and nova_console == 'novnc' }}"
+        mode: "http"
+        external: true
+        port: "{{ nova_novncproxy_port }}"
   nova-scheduler:
     container_name: "nova_scheduler"
     group: "nova-scheduler"
@@ -104,6 +155,17 @@ nova_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/nova/nova:/var/lib/kolla/venv/lib/python2.7/site-packages/nova' if nova_dev_mode | bool else '' }}"
     dimensions: "{{ nova_spicehtml5proxy_dimensions }}"
+    haproxy:
+      nova_spicehtml5proxy:
+        enabled: "{{ enable_nova|bool and nova_console == 'spice' }}"
+        mode: "http"
+        external: false
+        port: "{{ nova_spicehtml5proxy_port }}"
+      nova_spicehtml5proxy_external:
+        enabled: "{{ enable_nova|bool and nova_console == 'spice' }}"
+        mode: "http"
+        external: true
+        port: "{{ nova_spicehtml5proxy_port }}"
   nova-serialproxy:
     container_name: "nova_serialproxy"
     group: "nova-serialproxy"
@@ -115,6 +177,17 @@ nova_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/nova/nova:/var/lib/kolla/venv/lib/python2.7/site-packages/nova' if nova_dev_mode | bool else '' }}"
     dimensions: "{{ nova_serialproxy_dimensions }}"
+    haproxy:
+      nova_serialconsole_proxy:
+        enabled: "{{ enable_nova|bool and enable_nova_serialconsole_proxy|bool }}"
+        mode: "http"
+        external: false
+        port: "{{ nova_serialproxy_port }}"
+      nova_serialconsole_proxy_external:
+        enabled: "{{ enable_nova|bool and enable_nova_serialconsole_proxy|bool }}"
+        mode: "http"
+        external: true
+        port: "{{ nova_serialproxy_port }}"
   nova-conductor:
     container_name: "nova_conductor"
     group: "nova-conductor"
diff --git a/ansible/roles/nova/tasks/loadbalancer.yml b/ansible/roles/nova/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..32b58e292c
--- /dev/null
+++ b/ansible/roles/nova/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ nova_services }}"
+  tags: always
diff --git a/ansible/roles/octavia/defaults/main.yml b/ansible/roles/octavia/defaults/main.yml
index 66ee76b62f..753dbf9563 100644
--- a/ansible/roles/octavia/defaults/main.yml
+++ b/ansible/roles/octavia/defaults/main.yml
@@ -12,6 +12,17 @@ octavia_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ octavia_api_dimensions }}"
+    haproxy:
+      octavia_api:
+        enabled: "{{ enable_octavia }}"
+        mode: "http"
+        external: false
+        port: "{{ octavia_api_port }}"
+      octavia_api_external:
+        enabled: "{{ enable_octavia }}"
+        mode: "http"
+        external: true
+        port: "{{ octavia_api_port }}"
   octavia-health-manager:
     container_name: octavia_health_manager
     group: octavia-health-manager
diff --git a/ansible/roles/octavia/tasks/loadbalancer.yml b/ansible/roles/octavia/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..543f284cb7
--- /dev/null
+++ b/ansible/roles/octavia/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ octavia_services }}"
+  tags: always
diff --git a/ansible/roles/opendaylight/defaults/main.yml b/ansible/roles/opendaylight/defaults/main.yml
index 42278c9857..2383fe6300 100644
--- a/ansible/roles/opendaylight/defaults/main.yml
+++ b/ansible/roles/opendaylight/defaults/main.yml
@@ -14,6 +14,33 @@ opendaylight_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ opendaylight_dimensions }}"
+    haproxy:
+      opendaylight_api:
+        enabled: "{{ enable_opendaylight }}"
+        mode: "http"
+        port: "{{ opendaylight_haproxy_restconf_port }}"
+        backend_http_extra:
+          - "balance source"
+        custom_member_list: "{{ api_haproxy_members.split(';') }}"
+      opendaylight_api_backup:
+        enabled: "{{ enable_opendaylight }}"
+        mode: "http"
+        port: "{{ opendaylight_haproxy_restconf_port_backup }}"
+        backend_http_extra:
+          - "balance source"
+        custom_member_list: "{{ backup_api_haproxy_members.split(';') }}"
+      opendaylight_websocket:
+        enabled: "{{ enable_opendaylight }}"
+        mode: "http"
+        port: "{{ opendaylight_websocket_port }}"
+        backend_http_extra:
+          - "balance source"
+
+####################
+# HAProxy
+####################
+api_haproxy_members: "{% for host in groups['opendaylight'] %}server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ opendaylight_restconf_port }} check inter 2000 rise 2 fall 5;{% endfor %}"
+backup_api_haproxy_members: "{% for host in groups['opendaylight'] %}server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ opendaylight_restconf_port_backup }} check inter 2000 rise 2 fall 5;{% endfor %}"
 
 ####################
 # Docker
diff --git a/ansible/roles/opendaylight/tasks/loadbalancer.yml b/ansible/roles/opendaylight/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..db3edf1b81
--- /dev/null
+++ b/ansible/roles/opendaylight/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ opendaylight_services }}"
+  tags: always
diff --git a/ansible/roles/panko/defaults/main.yml b/ansible/roles/panko/defaults/main.yml
index e70f170c40..18f51fe1c6 100644
--- a/ansible/roles/panko/defaults/main.yml
+++ b/ansible/roles/panko/defaults/main.yml
@@ -12,6 +12,17 @@ panko_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ panko_api_dimensions }}"
+    haproxy:
+      panko_api:
+        enabled: "{{ enable_panko }}"
+        mode: "http"
+        external: false
+        port: "{{ panko_api_port }}"
+      panko_api_external:
+        enabled: "{{ enable_panko }}"
+        mode: "http"
+        external: true
+        port: "{{ panko_api_port }}"
 
 
 ####################
diff --git a/ansible/roles/panko/tasks/loadbalancer.yml b/ansible/roles/panko/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..53016b9ded
--- /dev/null
+++ b/ansible/roles/panko/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ panko_services }}"
+  tags: always
diff --git a/ansible/roles/prometheus/defaults/main.yml b/ansible/roles/prometheus/defaults/main.yml
index 0ca3242ec7..4a6dd96379 100644
--- a/ansible/roles/prometheus/defaults/main.yml
+++ b/ansible/roles/prometheus/defaults/main.yml
@@ -13,6 +13,12 @@ prometheus_services:
       - "prometheus:/var/lib/prometheus"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ prometheus_server_dimensions }}"
+    haproxy:
+      prometheus_server:
+        enabled: "{{ enable_prometheus }}"
+        mode: "http"
+        external: false
+        port: "{{ prometheus_port }}"
   prometheus-node-exporter:
     container_name: prometheus_node_exporter
     group: prometheus-node-exporter
@@ -83,6 +89,21 @@ prometheus_services:
       - "kolla_logs:/var/log/kolla/"
       - "prometheus:/var/lib/prometheus"
     dimensions: "{{ prometheus_alertmanager_dimensions }}"
+    haproxy:
+      prometheus_alertmanager:
+        enabled: "{{ enable_prometheus_alertmanager }}"
+        mode: "http"
+        external: false
+        port: "{{ prometheus_alertmanager_port }}"
+        auth_user: "{{ prometheus_alertmanager_user }}"
+        auth_pass: "{{ prometheus_alertmanager_password }}"
+      prometheus_alertmanager_external:
+        enabled: "{{ enable_prometheus_alertmanager }}"
+        mode: "http"
+        external: true
+        port: "{{ prometheus_alertmanager_port }}"
+        auth_user: "{{ prometheus_alertmanager_user }}"
+        auth_pass: "{{ prometheus_alertmanager_password }}"
 
 ####################
 # Database
diff --git a/ansible/roles/prometheus/tasks/loadbalancer.yml b/ansible/roles/prometheus/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..8f0161af67
--- /dev/null
+++ b/ansible/roles/prometheus/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ prometheus_services }}"
+  tags: always
diff --git a/ansible/roles/rabbitmq/defaults/main.yml b/ansible/roles/rabbitmq/defaults/main.yml
index d9b92040ef..a72e50efec 100644
--- a/ansible/roles/rabbitmq/defaults/main.yml
+++ b/ansible/roles/rabbitmq/defaults/main.yml
@@ -22,6 +22,34 @@ rabbitmq_services:
       - "{{ project_name }}:/var/lib/rabbitmq/"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ rabbitmq_dimensions }}"
+    haproxy:
+      rabbitmq_management:
+        enabled: "{{ enable_rabbitmq }}"
+        mode: "http"
+        port: "{{ rabbitmq_management_port }}"
+        host_group: "rabbitmq"
+      rabbitmq_outward_management:
+        enabled: "{{ enable_outward_rabbitmq }}"
+        mode: "http"
+        port: "{{ outward_rabbitmq_management_port }}"
+        host_group: "outward-rabbitmq"
+      rabbitmq_outward_external:
+        enabled: "{{ enable_outward_rabbitmq }}"
+        mode: "tcp"
+        external: true
+        port: "{{ outward_rabbitmq_port }}"
+        host_group: "outward-rabbitmq"
+        frontend_tcp_extra:
+          - "timeout client {{ haproxy_outward_rabbitmq_client_timeout }}"
+        backend_tcp_extra:
+          - "timeout server {{ haproxy_outward_rabbitmq_server_timeout }}"
+
+
+####################
+# HAProxy
+####################
+haproxy_outward_rabbitmq_client_timeout: "1h"
+haproxy_outward_rabbitmq_server_timeout: "1h"
 
 
 ####################
diff --git a/ansible/roles/rabbitmq/tasks/loadbalancer.yml b/ansible/roles/rabbitmq/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..918c7796e0
--- /dev/null
+++ b/ansible/roles/rabbitmq/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ rabbitmq_services }}"
+  tags: always
diff --git a/ansible/roles/sahara/defaults/main.yml b/ansible/roles/sahara/defaults/main.yml
index 43502b3cd8..75fa50d5d1 100644
--- a/ansible/roles/sahara/defaults/main.yml
+++ b/ansible/roles/sahara/defaults/main.yml
@@ -14,6 +14,17 @@ sahara_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/sahara/sahara:/var/lib/kolla/venv/lib/python2.7/site-packages/sahara' if sahara_dev_mode | bool else '' }}"
     dimensions: "{{ sahara_api_dimensions }}"
+    haproxy:
+      sahara_api:
+        enabled: "{{ enable_sahara }}"
+        mode: "http"
+        external: false
+        port: "{{ sahara_api_port }}"
+      sahara_api_external:
+        enabled: "{{ enable_sahara }}"
+        mode: "http"
+        external: true
+        port: "{{ sahara_api_port }}"
   sahara-engine:
     container_name: sahara_engine
     group: sahara-engine
diff --git a/ansible/roles/sahara/tasks/loadbalancer.yml b/ansible/roles/sahara/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..b8c3edb547
--- /dev/null
+++ b/ansible/roles/sahara/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ sahara_services }}"
+  tags: always
diff --git a/ansible/roles/searchlight/defaults/main.yml b/ansible/roles/searchlight/defaults/main.yml
index 9b0110d856..2006b8f50d 100644
--- a/ansible/roles/searchlight/defaults/main.yml
+++ b/ansible/roles/searchlight/defaults/main.yml
@@ -12,6 +12,17 @@ searchlight_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ searchlight_api_dimensions }}"
+    haproxy:
+      searchlight_api:
+        enabled: "{{ enable_searchlight }}"
+        mode: "http"
+        external: false
+        port: "{{ searchlight_api_port }}"
+      searchlight_api_external:
+        enabled: "{{ enable_searchlight }}"
+        mode: "http"
+        external: true
+        port: "{{ searchlight_api_port }}"
   searchlight-listener:
     container_name: searchlight_listener
     group: searchlight-listener
diff --git a/ansible/roles/searchlight/tasks/loadbalancer.yml b/ansible/roles/searchlight/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..b911642e51
--- /dev/null
+++ b/ansible/roles/searchlight/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ searchlight_services }}"
+  tags: always
diff --git a/ansible/roles/senlin/defaults/main.yml b/ansible/roles/senlin/defaults/main.yml
index f79b53e8b8..eafd89c4f6 100644
--- a/ansible/roles/senlin/defaults/main.yml
+++ b/ansible/roles/senlin/defaults/main.yml
@@ -13,6 +13,17 @@ senlin_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/senlin/senlin:/var/lib/kolla/venv/lib/python2.7/site-packages/senlin' if senlin_dev_mode | bool else '' }}"
     dimensions: "{{ senlin_api_dimensions }}"
+    haproxy:
+      senlin_api:
+        enabled: "{{ enable_senlin }}"
+        mode: "http"
+        external: false
+        port: "{{ senlin_api_port }}"
+      senlin_api_external:
+        enabled: "{{ enable_senlin }}"
+        mode: "http"
+        external: true
+        port: "{{ senlin_api_port }}"
   senlin-engine:
     container_name: senlin_engine
     group: senlin-engine
diff --git a/ansible/roles/senlin/tasks/loadbalancer.yml b/ansible/roles/senlin/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..47b2c0d140
--- /dev/null
+++ b/ansible/roles/senlin/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ senlin_services }}"
+  tags: always
diff --git a/ansible/roles/skydive/defaults/main.yml b/ansible/roles/skydive/defaults/main.yml
index 019fbd3517..084bcb2f70 100644
--- a/ansible/roles/skydive/defaults/main.yml
+++ b/ansible/roles/skydive/defaults/main.yml
@@ -12,6 +12,17 @@ skydive_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ skydive_analyzer_dimensions }}"
+    haproxy:
+      skydive_server:
+        enabled: "{{ enable_skydive }}"
+        mode: "http"
+        external: false
+        port: "{{ skydive_analyzer_port }}"
+      skydive_server_external:
+        enabled: "{{ enable_skydive }}"
+        mode: "http"
+        external: true
+        port: "{{ skydive_analyzer_port }}"
   skydive-agent:
     container_name: skydive_agent
     group: skydive-agent
diff --git a/ansible/roles/skydive/tasks/loadbalancer.yml b/ansible/roles/skydive/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..74078cd396
--- /dev/null
+++ b/ansible/roles/skydive/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ skydive_services }}"
+  tags: always
diff --git a/ansible/roles/solum/defaults/main.yml b/ansible/roles/solum/defaults/main.yml
index 150fd0b74f..b75c56abe4 100644
--- a/ansible/roles/solum/defaults/main.yml
+++ b/ansible/roles/solum/defaults/main.yml
@@ -35,6 +35,31 @@ solum_services:
       - "kolla_logs:/var/log/kolla/"
       - "{{ kolla_dev_repos_directory ~ '/solum/solum:/var/lib/kolla/venv/lib/python2.7/site-packages/solum' if solum_dev_mode | bool else '' }}"
     dimensions: "{{ solum_deployer_dimensions }}"
+    haproxy:
+      solum_application_deployment:
+        enabled: "{{ enable_solum }}"
+        mode: "http"
+        external: false
+        port: "{{ solum_application_deployment_port }}"
+        host_group: "solum-application-deployment"
+      solum_application_deployment_external:
+        enabled: "{{ enable_solum }}"
+        mode: "http"
+        external: true
+        port: "{{ solum_application_deployment_port }}"
+        host_group: "solum-application-deployment"
+      solum_image_builder:
+        enabled: "{{ enable_solum }}"
+        mode: "http"
+        external: false
+        port: "{{ solum_image_builder_port }}"
+        host_group: "solum-image-builder"
+      solum_image_builder_external:
+        enabled: "{{ enable_solum }}"
+        mode: "http"
+        external: true
+        port: "{{ solum_image_builder_port }}"
+        host_group: "solum-image-builder"
   solum-conductor:
     container_name: solum_conductor
     group: solum-conductor
@@ -47,7 +72,6 @@ solum_services:
       - "{{ kolla_dev_repos_directory ~ '/solum/solum:/var/lib/kolla/venv/lib/python2.7/site-packages/solum' if solum_dev_mode | bool else '' }}"
     dimensions: "{{ solum_conductor_dimensions }}"
 
-
 ####################
 # Database
 ####################
diff --git a/ansible/roles/solum/tasks/loadbalancer.yml b/ansible/roles/solum/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..f6d8ed8612
--- /dev/null
+++ b/ansible/roles/solum/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ solum_services }}"
+  tags: always
diff --git a/ansible/roles/swift/defaults/main.yml b/ansible/roles/swift/defaults/main.yml
index 465c75f714..b3743409e5 100644
--- a/ansible/roles/swift/defaults/main.yml
+++ b/ansible/roles/swift/defaults/main.yml
@@ -1,6 +1,22 @@
 ---
 project_name: "swift"
 
+swift_services:
+  swift-api:
+    group: swift-proxy-server
+    enabled: true
+    haproxy:
+      swift_api:
+        enabled: "{{ enable_swift }}"
+        mode: "http"
+        external: false
+        port: "{{ swift_proxy_server_port }}"
+      swift_api_external:
+        enabled: "{{ enable_swift }}"
+        mode: "http"
+        external: true
+        port: "{{ swift_proxy_server_port }}"
+
 ####################
 # Docker
 ####################
diff --git a/ansible/roles/swift/tasks/loadbalancer.yml b/ansible/roles/swift/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..7393ec9323
--- /dev/null
+++ b/ansible/roles/swift/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ swift_services }}"
+  tags: always
diff --git a/ansible/roles/tacker/defaults/main.yml b/ansible/roles/tacker/defaults/main.yml
index dbcbae4e7f..e53cdc55df 100644
--- a/ansible/roles/tacker/defaults/main.yml
+++ b/ansible/roles/tacker/defaults/main.yml
@@ -13,6 +13,17 @@ tacker_services:
       - "/etc/localtime:/etc/localtime:ro"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ tacker_server_dimensions }}"
+    haproxy:
+      tacker_server:
+        enabled: "{{ enable_tacker }}"
+        mode: "http"
+        external: false
+        port: "{{ tacker_server_port }}"
+      tacker_server_external:
+        enabled: "{{ enable_tacker }}"
+        mode: "http"
+        external: true
+        port: "{{ tacker_server_port }}"
   tacker-conductor:
     container_name: "tacker_conductor"
     group: "tacker-conductor"
diff --git a/ansible/roles/tacker/tasks/loadbalancer.yml b/ansible/roles/tacker/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..b53160caa8
--- /dev/null
+++ b/ansible/roles/tacker/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ tacker_services }}"
+  tags: always
diff --git a/ansible/roles/trove/defaults/main.yml b/ansible/roles/trove/defaults/main.yml
index 01bb1e66e6..6dfb89ff73 100644
--- a/ansible/roles/trove/defaults/main.yml
+++ b/ansible/roles/trove/defaults/main.yml
@@ -14,6 +14,17 @@ trove_services:
       - "{{ kolla_dev_repos_directory ~ '/trove/trove:/var/lib/kolla/venv/lib/python2.7/site-packages/trove' if trove_dev_mode | bool else '' }}"
       - "trove:/var/lib/trove/"
     dimensions: "{{ trove_api_dimensions }}"
+    haproxy:
+      trove_api:
+        enabled: "{{ enable_trove }}"
+        mode: "http"
+        external: false
+        port: "{{ trove_api_port }}"
+      trove_api_external:
+        enabled: "{{ enable_trove }}"
+        mode: "http"
+        external: true
+        port: "{{ trove_api_port }}"
   trove-conductor:
     container_name: trove_conductor
     group: trove-conductor
diff --git a/ansible/roles/trove/tasks/loadbalancer.yml b/ansible/roles/trove/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..1cfff7979a
--- /dev/null
+++ b/ansible/roles/trove/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ trove_services }}"
+  tags: always
diff --git a/ansible/roles/vitrage/defaults/main.yml b/ansible/roles/vitrage/defaults/main.yml
index 6b04b7631c..5c4c22d507 100644
--- a/ansible/roles/vitrage/defaults/main.yml
+++ b/ansible/roles/vitrage/defaults/main.yml
@@ -13,6 +13,17 @@ vitrage_services:
       - "{{ kolla_dev_repos_directory ~ '/vitrage/vitrage:/var/lib/kolla/venv/lib/python2.7/site-packages/vitrage' if vitrage_dev_mode | bool else '' }}"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ vitrage_api_dimensions }}"
+    haproxy:
+      vitrage_api:
+        enabled: "{{ enable_vitrage }}"
+        mode: "http"
+        external: false
+        port: "{{ vitrage_api_port }}"
+      vitrage_api_external:
+        enabled: "{{ enable_vitrage }}"
+        mode: "http"
+        external: true
+        port: "{{ vitrage_api_port }}"
   vitrage-collector:
     container_name: vitrage_collector
     group: vitrage-collector
diff --git a/ansible/roles/vitrage/tasks/loadbalancer.yml b/ansible/roles/vitrage/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..07fcf7fa07
--- /dev/null
+++ b/ansible/roles/vitrage/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ vitrage_services }}"
+  tags: always
diff --git a/ansible/roles/watcher/defaults/main.yml b/ansible/roles/watcher/defaults/main.yml
index b50833d343..aab03f6e7c 100644
--- a/ansible/roles/watcher/defaults/main.yml
+++ b/ansible/roles/watcher/defaults/main.yml
@@ -13,6 +13,17 @@ watcher_services:
       - "{{ kolla_dev_repos_directory ~ '/watcher/watcher:/var/lib/kolla/venv/lib/python2.7/site-packages/watcher' if watcher_dev_mode | bool else '' }}"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ watcher_api_dimensions }}"
+    haproxy:
+      watcher_api:
+        enabled: "{{ enable_watcher }}"
+        mode: "http"
+        external: false
+        port: "{{ watcher_api_port }}"
+      watcher_api_external:
+        enabled: "{{ enable_watcher }}"
+        mode: "http"
+        external: true
+        port: "{{ watcher_api_port }}"
   watcher-applier:
     container_name: watcher_applier
     group: watcher-applier
diff --git a/ansible/roles/watcher/tasks/loadbalancer.yml b/ansible/roles/watcher/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..013a1812e0
--- /dev/null
+++ b/ansible/roles/watcher/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ watcher_services }}"
+  tags: always
diff --git a/ansible/roles/zun/defaults/main.yml b/ansible/roles/zun/defaults/main.yml
index 40d7a4c893..5220370924 100644
--- a/ansible/roles/zun/defaults/main.yml
+++ b/ansible/roles/zun/defaults/main.yml
@@ -13,6 +13,17 @@ zun_services:
       - "{{ kolla_dev_repos_directory ~ '/zun/zun:/var/lib/kolla/venv/lib/python2.7/site-packages/zun' if zun_dev_mode | bool else '' }}"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ zun_api_dimensions }}"
+    haproxy:
+      zun_api:
+        enabled: "{{ enable_zun }}"
+        mode: "http"
+        external: false
+        port: "{{ zun_api_port }}"
+      zun_api_external:
+        enabled: "{{ enable_zun }}"
+        mode: "http"
+        external: true
+        port: "{{ zun_api_port }}"
   zun-wsproxy:
     container_name: zun_wsproxy
     group: zun-wsproxy
@@ -24,6 +35,17 @@ zun_services:
       - "{{ kolla_dev_repos_directory ~ '/zun/zun:/var/lib/kolla/venv/lib/python2.7/site-packages/zun' if zun_dev_mode | bool else '' }}"
       - "kolla_logs:/var/log/kolla/"
     dimensions: "{{ zun_wsproxy_dimensions }}"
+    haproxy:
+      zun_wsproxy:
+        enabled: "{{ enable_zun }}"
+        mode: "http"
+        external: false
+        port: "{{ zun_wsproxy_port }}"
+      zun_wsproxy_external:
+        enabled: "{{ enable_zun }}"
+        mode: "http"
+        external: true
+        port: "{{ zun_wsproxy_port }}"
   zun-compute:
     container_name: zun_compute
     group: zun-compute
diff --git a/ansible/roles/zun/tasks/loadbalancer.yml b/ansible/roles/zun/tasks/loadbalancer.yml
new file mode 100644
index 0000000000..b6dde18491
--- /dev/null
+++ b/ansible/roles/zun/tasks/loadbalancer.yml
@@ -0,0 +1,7 @@
+---
+- name: "Configure haproxy for {{ project_name }}"
+  import_role:
+    role: haproxy-config
+  vars:
+    project_services: "{{ zun_services }}"
+  tags: always
diff --git a/ansible/site.yml b/ansible/site.yml
index e6267b9308..694d3f7e40 100644
--- a/ansible/site.yml
+++ b/ansible/site.yml
@@ -67,6 +67,253 @@
         tags: chrony,
         when: enable_chrony | bool }
 
+- name: Apply role haproxy
+  gather_facts: false
+  hosts:
+    - haproxy
+  roles:
+    - { role: haproxy,
+        tags: haproxy,
+        when: enable_haproxy | bool }
+  tasks:
+    - block:
+        - include_role:
+            role: aodh
+            tasks_from: loadbalancer
+          tags: aodh
+          when: enable_aodh | bool
+        - include_role:
+            role: barbican
+            tasks_from: loadbalancer
+          tags: barbican
+          when: enable_barbican | bool
+        - include_role:
+            role: blazar
+            tasks_from: loadbalancer
+          tags: blazar
+          when: enable_blazar | bool
+        - include_role:
+            role: ceph
+            tasks_from: loadbalancer
+          tags: ceph
+          when: enable_ceph | bool
+        - include_role:
+            role: cinder
+            tasks_from: loadbalancer
+          tags: cinder
+          when: enable_cinder | bool
+        - include_role:
+            role: cloudkitty
+            tasks_from: loadbalancer
+          tags: cloudkitty
+          when: enable_cloudkitty | bool
+        - include_role:
+            role: congress
+            tasks_from: loadbalancer
+          tags: congress
+          when: enable_congress | bool
+        - include_role:
+            role: designate
+            tasks_from: loadbalancer
+          tags: designate
+          when: enable_designate | bool
+        - include_role:
+            role: elasticsearch
+            tasks_from: loadbalancer
+          tags: elasticsearch
+          when: enable_elasticsearch | bool
+        - include_role:
+            role: freezer
+            tasks_from: loadbalancer
+          tags: freezer
+          when: enable_freezer | bool
+        - include_role:
+            role: glance
+            tasks_from: loadbalancer
+          tags: glance
+          when: enable_glance | bool
+        - include_role:
+            role: gnocchi
+            tasks_from: loadbalancer
+          tags: gnocchi
+          when: enable_gnocchi | bool
+        - include_role:
+            role: grafana
+            tasks_from: loadbalancer
+          tags: grafana
+          when: enable_grafana | bool
+        - include_role:
+            role: heat
+            tasks_from: loadbalancer
+          tags: heat
+          when: enable_heat | bool
+        - include_role:
+            role: horizon
+            tasks_from: loadbalancer
+          tags: horizon
+          when: enable_horizon | bool
+        - include_role:
+            role: influxdb
+            tasks_from: loadbalancer
+          tags: influxdb
+          when: enable_influxdb | bool
+        - include_role:
+            role: ironic
+            tasks_from: loadbalancer
+          tags: ironic
+          when: enable_ironic | bool
+        - include_role:
+            role: karbor
+            tasks_from: loadbalancer
+          tags: karbor
+          when: enable_karbor | bool
+        - include_role:
+            role: keystone
+            tasks_from: loadbalancer
+          tags: keystone
+          when: enable_keystone | bool
+        - include_role:
+            role: kibana
+            tasks_from: loadbalancer
+          tags: kibana
+          when: enable_kibana | bool
+        - include_role:
+            role: magnum
+            tasks_from: loadbalancer
+          tags: magnum
+          when: enable_magnum | bool
+        - include_role:
+            role: manila
+            tasks_from: loadbalancer
+          tags: manila
+          when: enable_manila | bool
+        - include_role:
+            role: mariadb
+            tasks_from: loadbalancer
+          tags: mariadb
+          when: enable_mariadb | bool
+        - include_role:
+            role: memcached
+            tasks_from: loadbalancer
+          tags: memcached
+          when: enable_memcached | bool
+        - include_role:
+            role: mistral
+            tasks_from: loadbalancer
+          tags: mistral
+          when: enable_mistral | bool
+        - include_role:
+            role: monasca
+            tasks_from: loadbalancer
+          tags: monasca
+          when: enable_monasca | bool
+        - include_role:
+            role: mongodb
+            tasks_from: loadbalancer
+          tags: mongodb
+          when: enable_mongodb | bool
+        - include_role:
+            role: murano
+            tasks_from: loadbalancer
+          tags: murano
+          when: enable_murano | bool
+        - include_role:
+            role: neutron
+            tasks_from: loadbalancer
+          tags: neutron
+          when: enable_neutron | bool
+        - include_role:
+            role: nova
+            tasks_from: loadbalancer
+          tags: nova
+          when: enable_nova | bool
+        - include_role:
+            role: octavia
+            tasks_from: loadbalancer
+          tags: octavia
+          when: enable_octavia | bool
+        - include_role:
+            role: opendaylight
+            tasks_from: loadbalancer
+          tags: opendaylight
+          when: enable_opendaylight | bool
+        - include_role:
+            role: panko
+            tasks_from: loadbalancer
+          tags: panko
+          when: enable_panko | bool
+        - include_role:
+            role: prometheus
+            tasks_from: loadbalancer
+          tags: prometheus
+          when: enable_prometheus | bool
+        - include_role:
+            role: rabbitmq
+            tasks_from: loadbalancer
+          tags: rabbitmq
+          vars:
+            role_rabbitmq_cluster_cookie:
+            role_rabbitmq_groups:
+          when: enable_rabbitmq | bool or enable_outward_rabbitmq | bool
+        - include_role:
+            role: sahara
+            tasks_from: loadbalancer
+          tags: sahara
+          when: enable_sahara | bool
+        - include_role:
+            role: searchlight
+            tasks_from: loadbalancer
+          tags: searchlight
+          when: enable_searchlight | bool
+        - include_role:
+            role: senlin
+            tasks_from: loadbalancer
+          tags: senlin
+          when: enable_senlin | bool
+        - include_role:
+            role: skydive
+            tasks_from: loadbalancer
+          tags: skydive
+          when: enable_skydive | bool
+        - include_role:
+            role: solum
+            tasks_from: loadbalancer
+          tags: solum
+          when: enable_solum | bool
+        - include_role:
+            role: swift
+            tasks_from: loadbalancer
+          tags: swift
+          when: enable_swift | bool
+        - include_role:
+            role: tacker
+            tasks_from: loadbalancer
+          tags: tacker
+          when: enable_tacker | bool
+        - include_role:
+            role: trove
+            tasks_from: loadbalancer
+          tags: trove
+          when: enable_trove | bool
+        - include_role:
+            role: vitrage
+            tasks_from: loadbalancer
+          tags: vitrage
+          when: enable_vitrage | bool
+        - include_role:
+            role: watcher
+            tasks_from: loadbalancer
+          tags: watcher
+          when: enable_watcher | bool
+        - include_role:
+            role: zun
+            tasks_from: loadbalancer
+          tags: zun
+          when: enable_zun | bool
+      when:
+        - enable_haproxy | bool
+        - kolla_action in ['deploy', 'reconfigure', 'upgrade', 'config']
+
 - name: Apply role collectd
   gather_facts: false
   hosts: collectd
@@ -123,15 +370,6 @@
         tags: redis,
         when: enable_redis | bool }
 
-- name: Apply role haproxy
-  gather_facts: false
-  hosts:
-    - haproxy
-  roles:
-    - { role: haproxy,
-        tags: haproxy,
-        when: enable_haproxy | bool }
-
 - name: Apply role kibana
   gather_facts: false
   hosts: kibana
@@ -141,6 +379,14 @@
         tags: kibana,
         when: enable_kibana | bool }
 
+- name: Apply role mariadb
+  gather_facts: false
+  hosts: mariadb
+  roles:
+    - { role: mariadb,
+        tags: mariadb,
+        when: enable_mariadb | bool }
+
 - name: Apply role memcached
   gather_facts: false
   hosts: memcached
@@ -150,14 +396,6 @@
         tags: [memcache, memcached],
         when: enable_memcached | bool }
 
-- name: Apply role mariadb
-  gather_facts: false
-  hosts: mariadb
-  roles:
-    - { role: mariadb,
-        tags: mariadb,
-        when: enable_mariadb | bool }
-
 - name: Apply role prometheus
   gather_facts: false
   hosts:
diff --git a/releasenotes/notes/split-haproxy-config-by-service-90c2d89de1829e8a.yaml b/releasenotes/notes/split-haproxy-config-by-service-90c2d89de1829e8a.yaml
new file mode 100644
index 0000000000..a51c248332
--- /dev/null
+++ b/releasenotes/notes/split-haproxy-config-by-service-90c2d89de1829e8a.yaml
@@ -0,0 +1,26 @@
+---
+features:
+  - |
+    HAProxy configuration is now split per service, which makes creating and
+    updating service configs much simpler.
+upgrade:
+  - |
+    All haproxy related variables have been moved from the ``haproxy`` role to
+    the ``haproxy-common`` role, with the exception of the following which were
+    also split and renamed after the move\:
+
+    * ``haproxy_listen_tcp_extra`` becomes ``haproxy_frontend_tcp_extra`` and
+      ``haproxy_backend_tcp_extra``
+    * ``haproxy_listen_http_extra`` becomes ``haproxy_frontend_http_extra`` and
+      ``haproxy_backend_http_extra``
+  - |
+    The following additional haproxy related variables have been created in the
+    ``haproxy-common`` role\:
+
+    * ``haproxy_http_request_timeout``\: default http request timeout for
+      haproxy
+    * ``haproxy_queue_timeout``\: default queue timeout for haproxy
+    * ``haproxy_connect_timeout``\: default connect timeout for haproxy
+    * ``haproxy_check_timeout``\: default check timeout for haproxy
+    * ``haproxy_health_check``\: default health check string for haproxy
+    * ``haproxy_service_template``\: select which haproxy config style to use