heat_template_version: rocky description: > This is a template which will build the TLS Certificates necessary for the load balancer using the given parameters. parameters: # 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 # Can be overridden by parameter_defaults if the user wants to try deploying # this in a distro that doesn't support this path. 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 # Passed in by the controller NodeIndex: default: 0 type: number server: description: ID of the controller node to apply this config to type: string resources: ControllerTLSConfig: type: OS::Heat::SoftwareConfig properties: group: script inputs: - name: cert_path - name: cert_chain_content outputs: - name: chain_md5sum - name: cert_modulus - name: key_modulus config: | #!/bin/sh # If the HAProxy container tried to load this, it'll be a directory and # will make this fail. if [ -d ${cert_path} ]; then rmdir ${cert_path} HAPROXY_TLS_UPDATE_NEEDED=1 else HAPROXY_TLS_UPDATE_NEEDED=0 fi cat > ${cert_path} << EOF ${cert_chain_content} EOF chmod 0440 ${cert_path} chown root:haproxy ${cert_path} md5sum ${cert_path} > ${heat_outputs_path}.chain_md5sum openssl x509 -noout -modulus -in ${cert_path} \ | openssl md5 | cut -c 10- \ > ${heat_outputs_path}.cert_modulus openssl rsa -noout -modulus -in ${cert_path} \ | openssl md5 | cut -c 10- \ > ${heat_outputs_path}.key_modulus # We need to reload haproxy in case the certificate changed because # puppet doesn't know the contents of the cert file. haproxy_status=$(systemctl is-active haproxy) if [ "$haproxy_status" = "active" ]; then systemctl reload haproxy fi pacemaker_status=$(systemctl is-active pacemaker) # If we need an update and pacemaker is being used, we need to restart # the pacemaker resource on the bootstrap node. We don't support the update # in non-pacemaker cases. if [[ $HAPROXY_TLS_UPDATE_NEEDED -eq 1 && "$pacemaker_status" == "active" ]]; then BOOTSTRAPNODE=$(hiera -c /etc/puppet/hiera.yaml bootstrap_nodeid) MY_HOSTNAME=$(hostname) if [[ "$BOOTSTRAPNODE" == "$MY_HOSTNAME" ]]; then # Triggers an update HAPROXY_RESOURCE_NAME=$(pcs status | grep container | grep haproxy | sed 's/^.*container.*: \(.*\) .*/\1/') if [[ -n "$HAPROXY_RESOURCE_NAME" ]]; then pcs resource restart "$HAPROXY_RESOURCE_NAME" fi fi elif [[ $HAPROXY_TLS_UPDATE_NEEDED -eq 0 ]]; then # Handles reloading HAProxy and fetching a new certificate if # necessary HAPROXY_CONTAINER_ID=$(docker ps | grep '[[:space:]]haproxy' | awk '{print $1}') if [[ -n "$HAPROXY_CONTAINER_ID" ]]; then if [[ "$pacemaker_status" == "active" ]]; then # We copy the certificate from the mount point to the desired # path docker exec "$HAPROXY_CONTAINER_ID" cp /var/lib/kolla/config_files/src-tls${cert_path} ${cert_path} fi docker kill --signal=HUP "$HAPROXY_CONTAINER_ID" fi fi ControllerTLSDeployment: type: OS::Heat::SoftwareDeployment properties: name: ControllerTLSDeployment config: {get_resource: ControllerTLSConfig} server: {get_param: server} input_values: cert_path: {get_param: DeployedSSLCertificatePath} cert_chain_content: list_join: - '' - - {get_param: SSLCertificate} - {get_param: SSLIntermediateCertificate} - {get_param: SSLKey} outputs: deploy_stdout: description: Deployment reference value: {get_attr: [ControllerTLSDeployment, chain_md5sum]} deployed_ssl_certificate_path: description: The location that the TLS certificate was deployed to. value: {get_param: DeployedSSLCertificatePath} key_modulus_md5: description: MD5 checksum of the Key SSL Modulus value: {get_attr: [ControllerTLSDeployment, key_modulus]} cert_modulus_md5: description: MD5 checksum of the Certificate SSL Modulus value: {get_attr: [ControllerTLSDeployment, cert_modulus]}