63001263ad
Do not inject public certificates in pacemaker bundles by means
of "podman cp", as this pauses the container for a short amount
of time and can make pacemaker operation fail during that time
window and impact cluster for no reason.
Keep "podman cp" for non-HA containers, as the freeze is short
and doesn't seem to impact podman monitoring anyway.
The new certificate injection only works for podman 1.9+, lower
version won't overwrite the existing certificate.
(cherry-picked from 93e53b7429
)
(squashed with Ic6e4264c5ad46bd2589cc907c365af2d42fde63d)
(removed a part that should stay in puppet-tripleo before wallaby)
Closes-Bug: #1917868
Change-Id: Id7308f028f33716be5e3df6699c3f2c12e33e344
189 lines
7.0 KiB
YAML
189 lines
7.0 KiB
YAML
heat_template_version: rocky
|
|
|
|
description: >
|
|
HAProxy deployment with TLS enabled, with an injected certificate
|
|
|
|
parameters:
|
|
ServiceData:
|
|
default: {}
|
|
description: Dictionary packing service data
|
|
type: json
|
|
ServiceNetMap:
|
|
default: {}
|
|
description: Mapping of service_name -> network name. Typically set
|
|
via parameter_defaults in the resource registry. This
|
|
mapping overrides those in ServiceNetMapDefaults.
|
|
type: json
|
|
DefaultPasswords:
|
|
default: {}
|
|
type: json
|
|
RoleName:
|
|
default: ''
|
|
description: Role name on which the service is applied
|
|
type: string
|
|
RoleParameters:
|
|
default: {}
|
|
description: Parameters specific to the role
|
|
type: json
|
|
EndpointMap:
|
|
default: {}
|
|
description: Mapping of service endpoint -> protocol. Typically set
|
|
via parameter_defaults in the resource registry.
|
|
type: json
|
|
# Can be overridden via parameter_defaults in the environment
|
|
SSLCertificate:
|
|
default: ''
|
|
description: >
|
|
The content of the SSL certificate (without Key) in PEM format.
|
|
type: string
|
|
SSLIntermediateCertificate:
|
|
default: ''
|
|
description: >
|
|
The content of an SSL intermediate CA certificate in PEM format.
|
|
type: string
|
|
# NOTE(jaosorior): Adding this default is only while we enable TLS by default
|
|
# for the overcloud. It'll be removed in a subsequent patch.
|
|
SSLKey:
|
|
default: ''
|
|
description: >
|
|
The content of the SSL Key in PEM format.
|
|
type: string
|
|
hidden: true
|
|
DeployedSSLCertificatePath:
|
|
default: '/etc/pki/tls/private/overcloud_endpoint.pem'
|
|
description: >
|
|
The filepath of the certificate as it will be stored in the controller.
|
|
type: string
|
|
|
|
outputs:
|
|
role_data:
|
|
description: Role data for the HAProxy public TLS injection.
|
|
value:
|
|
service_name: haproxy_public_tls_inject
|
|
config_settings: {}
|
|
certificates_specs: {}
|
|
metadata_settings: null
|
|
host_prep_tasks:
|
|
- name: get parameters
|
|
set_fact:
|
|
cert_path: {get_param: DeployedSSLCertificatePath}
|
|
cert_content: {get_param: SSLCertificate}
|
|
chain_content: {get_param: SSLIntermediateCertificate}
|
|
key_content: {get_param: SSLKey}
|
|
no_log: "{{ hide_sensitive_logs | bool }}"
|
|
|
|
# We want to ensure we run all this block IFF we have
|
|
# a certificate content.
|
|
- name: manage certificate
|
|
when:
|
|
- cert_content is defined
|
|
- cert_content != ''
|
|
block:
|
|
- name: get DeployedSSLCertificatePath attributes
|
|
register: attr_cert_path
|
|
stat:
|
|
path: "{{cert_path}}"
|
|
|
|
- name: set is_haproxy_bootstrap_node fact
|
|
set_fact: is_haproxy_bootstrap_node={{haproxy_short_bootstrap_node_name | lower == ansible_facts['hostname'] | lower}}
|
|
when:
|
|
- haproxy_short_bootstrap_node_name|default(false)
|
|
|
|
- name: get haproxy status
|
|
register: haproxy_state
|
|
systemd:
|
|
name: haproxy
|
|
|
|
- name: get pacemaker status
|
|
register: pacemaker_state
|
|
systemd:
|
|
name: pacemaker
|
|
|
|
- name: get docker status
|
|
register: docker_state
|
|
systemd:
|
|
name: docker
|
|
|
|
- name: get container_id
|
|
when:
|
|
- docker_state.status.ActiveState == 'active' or container_cli == 'podman'
|
|
- attr_cert_path.stat.exists
|
|
- attr_cert_path.stat.isdir == False
|
|
command: "{{ container_cli }} ps -q -f name=haproxy"
|
|
register: container_id
|
|
|
|
- name: get pcs resource name for haproxy container
|
|
when:
|
|
- bootstrap_node is defined
|
|
- is_haproxy_bootstrap_node
|
|
- pacemaker_state.status.ActiveState == 'active'
|
|
- attr_cert_path.stat.exists
|
|
- attr_cert_path.stat.isdir
|
|
shell: |
|
|
pcs status resources | sed -n 's/^.*container.*: \(haproxy.*\) .*/\1/p'
|
|
register: pacemaker_resource
|
|
|
|
# It might happen docker has started priori the file creation - it will then create a
|
|
# directory. We have to drop that directory in order to push our file.
|
|
- name: remove DeployedSSLCertificatePath if is dir
|
|
when: attr_cert_path.stat.isdir is defined and attr_cert_path.stat.isdir
|
|
file:
|
|
path: "{{cert_path}}"
|
|
state: absent
|
|
|
|
# In containerized env, haproxy group does not exist.
|
|
# We hence need to do this file creation in two distinct steps
|
|
# and ignore failure on the ownership change.
|
|
- name: push certificate content
|
|
no_log: "{{ hide_sensitive_logs | bool }}"
|
|
copy:
|
|
dest: "{{cert_path}}"
|
|
mode: 0440
|
|
owner: root
|
|
content: |
|
|
{{cert_content}}
|
|
{{chain_content}}
|
|
{{key_content}}
|
|
|
|
# Set certificate group IFF we're not in container context
|
|
# Also, restart HAProxy service without more concern
|
|
- name: BM haproxy non-pacemaker context
|
|
when: haproxy_state.status.ActiveState == 'active'
|
|
block:
|
|
- name: set certificate ownership
|
|
file:
|
|
path: "{{cert_path}}"
|
|
group: haproxy
|
|
|
|
- name: reload haproxy if enabled
|
|
service:
|
|
name: haproxy
|
|
state: reloaded
|
|
|
|
- name: restart pacemaker resource for haproxy
|
|
when:
|
|
- pacemaker_resource is defined
|
|
- pacemaker_resource.stdout is defined
|
|
- pacemaker_resource.stdout != ''
|
|
command: pcs resource restart "{{pacemaker_resource.stdout}}"
|
|
|
|
# We can't use kolla for certificate updates, so we have to
|
|
# set its rights and restart the service.
|
|
- name: dedicated part for containers
|
|
when:
|
|
- container_id is defined
|
|
- container_id.stdout is defined
|
|
- container_id.stdout != ''
|
|
block:
|
|
- name: copy certificate, chgrp, restart haproxy
|
|
shell: |
|
|
set -e
|
|
if {{ container_cli }} ps -f "id={{ item }}" --format "{{ '{{' }}.Names{{ '}}' }}" | grep -q "^haproxy-bundle"; then
|
|
tar -c {{ cert_path }} | {{container_cli}} exec -i {{ item }} tar -C / -xv
|
|
else
|
|
{{ container_cli }} cp {{ cert_path }} {{ item }}:{{ cert_path }}
|
|
fi
|
|
{{ container_cli }} exec --user root {{ item }} chgrp haproxy {{ cert_path }}
|
|
{{ container_cli }} kill --signal=HUP {{ item }}
|
|
with_items: "{{ container_id.stdout.split('\n') }}"
|