tripleo-heat-templates/deployment/haproxy/haproxy-internal-tls-certmonger.j2.yaml
Harald Jensås 273b41a5da Use ServiceNetMap to filter PublicNetwork in haproxy-tls
Replace the filtering using the hard-coded "external"
network name with a yaql filter using the PublicNetwork in
ServiceNetMap instead.

This should allow fully custom network name/name_lower to be
used as long as service_net_map_replace is also used or the
ServiceNetMap is provided with appropriate overrides.

Also removes jinj2 filtering on 'tenant' network, this network
does not have a VIP by default so it is alreayd filtered by the
'and network.vip' in the jinj2 for loop. In the case 'tenant'
network does have VIP it would make sense to create a certificate
for it as well.

Related-Bug: #1946239
Change-Id: I7fa8e9931f27dbe3352b06c830441eac5bc3733e
2021-10-27 12:32:16 +02:00

174 lines
7.2 KiB
YAML

heat_template_version: wallaby
description: >
HAProxy deployment with TLS enabled, powered by certmonger
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. Use
parameter_merge_strategies to merge it with the defaults.
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
HAProxyInternalTLSCertsDirectory:
default: '/etc/pki/tls/certs/haproxy'
type: string
HAProxyInternalTLSKeysDirectory:
default: '/etc/pki/tls/private/haproxy'
type: string
CertificateKeySize:
type: string
default: '2048'
description: Specifies the private key size used when creating the
certificate.
HAProxyCertificateKeySize:
type: string
default: ''
description: Override the private key size used when creating the
certificate for this service
conditions:
key_size_override_set:
not: {equals: [{get_param: HAProxyCertificateKeySize}, '']}
resources:
HAProxyNetworks:
type: OS::Heat::Value
properties:
value:
# NOTE(jaosorior|hjensas) Get unique network names to create
# certificates for those.
# * The 'ctlplane' network is always included.
# * The tenant network is skipped in jinja2 filter since it
# does not have a VIP. We don't need a certificate for the
# tenant nework.
# * The "external" (PublicNetwork) network will be handled in
# another template, it is skipped by a yaql filter on the
# PublicNetwork defined in ServiceNetMap.
yaql:
expression: let(public_network => $.data.public_network) -> $.data.networks.where($ != $public_network or $ = 'ctlplane')
data:
public_network: {get_param: [ServiceNetMap, PublicNetwork]}
networks:
- ctlplane
{%- for network in networks if network.enabled|default(true) and network.vip|default(false) %}
- {{network.name_lower}}
{%- endfor %}
{% raw -%}
outputs:
role_data:
description: Role data for the HAProxy internal TLS via certmonger role.
value:
service_name: haproxy_internal_tls_certmonger
config_settings:
tripleo::haproxy::use_internal_certificates: true
certificates_specs:
map_merge:
repeat:
template:
haproxy-NETWORK:
service_pem:
list_join:
- ''
- - {get_param: HAProxyInternalTLSCertsDirectory}
- '/overcloud-haproxy-NETWORK.pem'
for_each:
NETWORK: {get_attr: [HAProxyNetworks, value]}
metadata_settings:
repeat:
template:
- service: haproxy
network: $NETWORK
type: vip
- service: haproxy
network: $NETWORK
type: node
for_each:
$NETWORK: {get_attr: [HAProxyNetworks, value]}
deploy_steps_tasks:
- name: Certificate generation
when: step|int == 1
block:
- name: Create dirs for certificates and keys
file:
path: "{{ item }}"
state: directory
serole: object_r
setype: cert_t
seuser: system_u
with_items:
- {get_param: HAProxyInternalTLSCertsDirectory}
- {get_param: HAProxyInternalTLSKeysDirectory}
- include_role:
name: linux-system-roles.certificate
vars:
certificate_requests:
repeat:
template:
name: haproxy-NETWORK-cert
dns:
- "{{fqdn_NETWORK}}"
- "{{cloud_names.cloud_name_NETWORK}}"
principal: "haproxy/{{fqdn_NETWORK}}@{{idm_realm}}"
run_after:
str_replace:
template: |
# Copy crt and key for backward compatibility
cp "/etc/pki/tls/certs/haproxy-NETWORK-cert.crt" "CERTSDIR/overcloud-haproxy-NETWORK.crt"
cp "/etc/pki/tls/private/haproxy-NETWORK-cert.key" "KEYSDIR/overcloud-haproxy-NETWORK.key"
ca_path="/etc/ipa/ca.crt"
service_crt="CERTSDIR/overcloud-haproxy-NETWORK.crt"
service_key="KEYSDIR/overcloud-haproxy-NETWORK.key"
service_pem="CERTSDIR/overcloud-haproxy-NETWORK.pem"
cat "$service_crt" "$ca_path" "$service_key" > "$service_pem"
container_name=$({{container_cli}} ps --format=\{\{.Names\}\} | grep -w -E 'haproxy(-bundle-.*-[0-9]+)?')
# Inject the new pem into the running container
if echo "$container_name" | grep -q "^haproxy-bundle"; then
# lp#1917868: Do not use podman cp with HA containers as they get
# frozen temporarily and that can make pacemaker operation fail.
tar -c "$service_pem" | {{container_cli}} exec -i "$container_name" tar -C / -xv
# no need to update the mount point, because pacemaker
# recreates the container when it's restarted
else
# Refresh the pem at the mount-point
{{container_cli}} cp $service_pem "$container_name:/var/lib/kolla/config_files/src-tls/$service_pem"
# Copy the new pem from the mount-point to the real path
{{container_cli}} exec "$container_name" cp "/var/lib/kolla/config_files/src-tls$service_pem" "$service_pem"
fi
# Set appropriate permissions
{{container_cli}} exec "$container_name" chown haproxy:haproxy "$service_pem"
# Trigger a reload for HAProxy to read the new certificates
{{container_cli}} kill --signal HUP "$container_name"
params:
CERTSDIR: {get_param: HAProxyInternalTLSCertsDirectory}
KEYSDIR: {get_param: HAProxyInternalTLSKeysDirectory}
key_size:
if:
- key_size_override_set
- {get_param: HAProxyCertificateKeySize}
- {get_param: CertificateKeySize}
ca: ipa
for_each:
NETWORK: {get_attr: [HAProxyNetworks, value]}
{%- endraw %}