Implement support for haproxy_accept_both_protocols

Enabling TLS on the internal VIP for existing deployments will cause
downtime until each client is configured to use HTTPS instead of HTTP.

To avoid downtime, it is recommended to enable
`openstack_service_accept_both_protocols` until all services are
configured correctly.
It allows haproxy frontends to accept both HTTP and HTTPS.

Depends-On: https://review.opendev.org/c/openstack/openstack-ansible-haproxy_server/+/864784
Change-Id: Ie6f5b73c54b0a6d1f661a9d4f33b8a301d8c4170
This commit is contained in:
Damian Dabrowski 2023-05-25 19:29:49 +02:00
parent 555ec6abb7
commit b75a9d0dd0
30 changed files with 45 additions and 4 deletions

View File

@ -285,10 +285,9 @@ each OpenStack service and OpenStack services are configured to use http or
https. This means once haproxy is updated to only accept HTTPS connections, the
OpenStack services will stop working until they are updated to use HTTPS.
For this reason it is recommended that TLS for haproxy internal VIP on existing
deployments is deployed at the same time as enabling TLS for Haproxy backends,
as this may also cause downtime. For new deployments this should be enabled from
the start.
To avoid downtime, it is recommended to enable
``openstack_service_accept_both_protocols`` until all services are configured
correctly. It allows haproxy frontends to listen on both HTTP and HTTPS.
TLS for Haproxy Backends
~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -25,6 +25,7 @@ haproxy_adjutant_api_service:
- "httpchk GET / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ adjutant_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ adjutant_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ adjutant_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['adjutant_api'] is defined and groups['adjutant_api'] | length > 0 }}"
adjutant_haproxy_services:

View File

@ -73,6 +73,9 @@ openstack_external_ssl: true
## be encrypted.
openstack_service_backend_ssl: False
## Allows haproxy frontend to accept both HTTP and HTTPS traffic.
openstack_service_accept_both_protocols: False
## OpenStack global Endpoint Protos
openstack_service_publicuri_proto: https
openstack_service_adminuri_proto: http

View File

@ -24,6 +24,7 @@ haproxy_aodh_api_service:
- "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ aodh_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ aodh_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ aodh_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['aodh_api'] is defined and groups['aodh_api'] | length > 0 }}"
aodh_haproxy_services:

View File

@ -24,6 +24,7 @@ haproxy_barbican_service:
- "httpchk GET /healthcheck HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ barbican_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ barbican_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ barbican_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['barbican_api'] is defined and groups['barbican_api'] | length > 0 }}"
barbican_haproxy_services:

View File

@ -26,6 +26,7 @@ haproxy_blazar_api_service:
- 'expect rstatus (200|401)'
haproxy_backend_ssl: "{{ blazar_backend_ssl | default(False) }}"
haproxy_backend_ca: "{{ openstack_haproxy_backend_ca | default(True) }}"
haproxy_accept_both_protocols: "{{ blazar_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['blazar_api'] is defined and groups['blazar_api'] | length > 0 }}"
blazar_haproxy_services:

View File

@ -24,6 +24,7 @@ haproxy_cinder_api_service:
- "httpchk HEAD /healthcheck HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ cinder_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ cinder_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ cinder_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['cinder_api'] is defined and groups['cinder_api'] | length > 0 }}"
cinder_haproxy_services:

View File

@ -25,6 +25,7 @@ haproxy_cloudkitty_api_service:
- "httpchk GET /healthcheck HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ cloudkitty_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ cloudkitty_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ cloudkitty_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['cloudkitty_api'] is defined and groups['cloudkitty_api'] | length > 0 }}"
cloudkitty_haproxy_services:

View File

@ -26,6 +26,7 @@ haproxy_designate_api_service:
- "httplog"
haproxy_backend_ssl: "{{ designate_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ designate_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ designate_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['designate_api'] is defined and groups['designate_api'] | length > 0 }}"
designate_haproxy_services:

View File

@ -25,6 +25,7 @@ haproxy_glance_api_service:
- "httpchk GET /healthcheck HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ (glance_use_uwsgi | default(True)) | ternary((glance_backend_ssl | default(openstack_service_backend_ssl)), False) }}"
haproxy_backend_ca: "{{ glance_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ glance_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['glance_api'] is defined and groups['glance_api'] | length > 0 }}"
glance_haproxy_services:

View File

@ -24,6 +24,7 @@ haproxy_heat_api_service:
- "httpchk HEAD /healthcheck HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ heat_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ heat_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ heat_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['heat_api'] is defined and groups['heat_api'] | length > 0 }}"
haproxy_heat_api_cfn_service:
@ -37,6 +38,7 @@ haproxy_heat_api_cfn_service:
- "httpchk HEAD /healthcheck HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ heat_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ heat_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ heat_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['heat_api_cfn'] is defined and groups['heat_api_cfn'] | length > 0 }}"
heat_haproxy_services:

View File

@ -30,6 +30,7 @@ haproxy_ironic_api_service:
- "http-request deny if { path_beg /v1/heartbeat } !{ src {{ haproxy_ironic_allowlist_networks | join(' } !{ src ') }} }"
haproxy_backend_ssl: "{{ ironic_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ ironic_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ ironic_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['ironic_api'] is defined and groups['ironic_api'] | length > 0 }}"
haproxy_ironic_inspector_service:
@ -45,6 +46,7 @@ haproxy_ironic_inspector_service:
- "http-request deny if { path_beg /v1/continue } !{ src {{ haproxy_ironic_inspector_allowlist_networks | join(' } !{ src ') }} }"
haproxy_backend_ssl: "{{ ironic_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ ironic_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ ironic_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['ironic_inspector'] is defined and groups['ironic_inspector'] | length > 0 }}"
ironic_haproxy_services:

View File

@ -24,6 +24,7 @@ haproxy_keystone_service:
- "httpchk HEAD /healthcheck HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ keystone_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ keystone_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ keystone_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['keystone_all'] is defined and groups['keystone_all'] | length > 0 }}"
keystone_haproxy_services:

View File

@ -24,6 +24,7 @@ haproxy_magnum_service:
- "httpchk GET /healthcheck HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ magnum_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ magnum_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ magnum_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['magnum_all'] is defined and groups['magnum_all'] | length > 0 }}"
magnum_haproxy_services:

View File

@ -24,6 +24,7 @@ haproxy_manila_service:
- "httpchk HEAD /healthcheck HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ manila_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ manila_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ manila_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['manila_api'] is defined and groups['manila_api'] | length > 0 }}"
manila_haproxy_services:

View File

@ -24,6 +24,7 @@ haproxy_masakari_api_service:
- "httpchk GET / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ masakari_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ masakari_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ masakari_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['masakari_api'] is defined and groups['masakari_api'] | length > 0 }}"
masakari_haproxy_services:

View File

@ -24,6 +24,7 @@ haproxy_mistral_service:
- "httpchk GET / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ mistral_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ mistral_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ mistral_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['mistral_all'] is defined and groups['mistral_all'] | length > 0 }}"
mistral_haproxy_services:

View File

@ -26,6 +26,7 @@ haproxy_murano_service:
- "expect status 401"
haproxy_backend_ssl: "{{ murano_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ murano_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ murano_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['murano_all'] is defined and groups['murano_all'] | length > 0 }}"
murano_haproxy_services:

View File

@ -26,6 +26,7 @@ haproxy_neutron_server_service:
- "httpchk GET /healthcheck HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ neutron_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ neutron_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ neutron_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['neutron_server'] is defined and groups['neutron_server'] | length > 0 }}"
haproxy_opendaylight_neutron_service:

View File

@ -33,6 +33,7 @@ haproxy_nova_api_metadata_service:
haproxy_allowlist_networks: "{{ haproxy_nova_metadata_allowlist_networks }}"
haproxy_backend_ssl: "{{ nova_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ nova_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ nova_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['nova_api_metadata'] is defined and groups['nova_api_metadata'] | length > 0 }}"
haproxy_nova_api_compute_service:
@ -46,6 +47,7 @@ haproxy_nova_api_compute_service:
- "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ nova_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ nova_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ nova_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['nova_api_os_compute'] is defined and groups['nova_api_os_compute'] | length > 0 }}"
haproxy_nova_spice_console_service:
@ -62,6 +64,7 @@ haproxy_nova_spice_console_service:
haproxy_backend_httpcheck_options: "{{ haproxy_nova_console_http_mode | ternary(['expect status 200'], []) }}"
haproxy_backend_ssl: "{{ nova_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ nova_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ nova_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['nova_console'] is defined and groups['nova_console'] | length > 0 and nova_console_type == 'spice' }}"
haproxy_nova_serial_console_service:
@ -78,6 +81,7 @@ haproxy_nova_serial_console_service:
haproxy_backend_httpcheck_options: "{{ haproxy_nova_console_http_mode | ternary(['expect status 200'], []) }}"
haproxy_backend_ssl: "{{ nova_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ nova_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ nova_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ (groups['nova_console'] is defined and groups['nova_console'] | length > 0 and nova_console_type == 'serial') or
(groups['ironic_console'] is defined and groups['ironic_console'] | length > 0 and ironic_console_type == 'serial') }}"
@ -95,6 +99,7 @@ haproxy_nova_novnc_console_service:
haproxy_backend_httpcheck_options: "{{ haproxy_nova_console_http_mode | ternary(['expect status 200'], []) }}"
haproxy_backend_ssl: "{{ nova_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ nova_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ nova_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['nova_console'] is defined and groups['nova_console'] | length > 0 and nova_console_type == 'novnc' }}"
# NOTE(jrosser) Clean up legacy console haproxy configs from previous releases

View File

@ -24,6 +24,7 @@ haproxy_octavia_service:
- "httpchk GET /healthcheck HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ octavia_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ octavia_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ octavia_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['octavia_all'] is defined and groups['octavia_all'] | length > 0 }}"
octavia_haproxy_services:

View File

@ -24,6 +24,7 @@ haproxy_placement_service:
- "httpchk GET / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ placement_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ placement_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ placement_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['placement_all'] is defined and groups['placement_all'] | length > 0 }}"
placement_haproxy_services:

View File

@ -44,6 +44,7 @@ haproxy_repo_service:
- "expect status 200"
haproxy_backend_ssl: "{{ repo_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ repo_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ repo_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['repo_all'] is defined and groups['repo_all'] | length > 0 }}"
repo_haproxy_services:

View File

@ -25,6 +25,7 @@ haproxy_sahara_api_service:
- "httpchk GET / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ sahara_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ sahara_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ sahara_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['sahara_api'] is defined and groups['sahara_api'] | length > 0 }}"
sahara_haproxy_services:

View File

@ -24,6 +24,7 @@ haproxy_senlin_api_service:
- "httpchk GET / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ senlin_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ senlin_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ senlin_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['senlin_api'] is defined and groups['senlin_api'] | length > 0 }}"
senlin_haproxy_services:

View File

@ -28,6 +28,7 @@ haproxy_swift_proxy_service:
# https://opendev.org/openstack/swift/src/commit/c78a5962b5f6c9e75f154cac924a226815236e98/etc/proxy-server.conf-sample
haproxy_backend_ssl: "{{ swift_backend_ssl | default(False) }}"
haproxy_backend_ca: "{{ swift_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ swift_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['swift_proxy'] is defined and groups['swift_proxy'] | length > 0 }}"
swift_haproxy_services:

View File

@ -26,6 +26,7 @@ haproxy_tacker_service:
- "httplog"
haproxy_backend_ssl: "{{ tacker_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ tacker_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ tacker_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['tacker_all'] is defined and groups['tacker_all'] | length > 0 }}"
tacker_haproxy_services:

View File

@ -24,6 +24,7 @@ haproxy_trove_service:
- "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck"
haproxy_backend_ssl: "{{ trove_backend_ssl | default(openstack_service_backend_ssl) }}"
haproxy_backend_ca: "{{ trove_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ trove_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['trove_api'] is defined and groups['trove_api'] | length > 0 }}"
trove_haproxy_services:

View File

@ -43,6 +43,7 @@ haproxy_zun_console_service:
# haproxy_backend_ssl disabled due to: https://bugs.launchpad.net/zun/+bug/2016917
haproxy_backend_ssl: False
haproxy_backend_ca: "{{ zun_haproxy_backend_ca | default(openstack_haproxy_backend_ca) }}"
haproxy_accept_both_protocols: "{{ zun_accept_both_protocols | default(openstack_service_accept_both_protocols) }}"
haproxy_service_enabled: "{{ groups['zun_api'] is defined and groups['zun_api'] | length > 0 }}"
zun_haproxy_services:

View File

@ -0,0 +1,6 @@
---
other:
- |
Variable ``openstack_service_accept_both_protocols`` was implemented to
temporarily accept both HTTP and HTTPS traffic on haproxy frontends.
It is useful when changing protocol of service endpoints.