Refactor HAProxy configuration and certificate management
- Updated HAProxy configuration template to reflect changes for the Taurus Production Environment, including SSL settings and rate limiting for specific endpoints. - Introduced new playbooks for certificate distribution and validation with OCI Vault, ensuring certificates are correctly managed and renewed. - Added hooks for uploading renewed certificates to OCI Vault and validating their integrity. - Enhanced the HAProxy configuration playbook to ensure proper service management and verification of the HAProxy service. - Updated inventory variables for certificate management and ensured compatibility with the new structure.
This commit is contained in:
115
ansible/certbot/vault-upload-hook.sh.j2
Normal file
115
ansible/certbot/vault-upload-hook.sh.j2
Normal file
@@ -0,0 +1,115 @@
|
||||
#!/bin/bash
|
||||
# Certbot post-renewal hook for OCI Vault upload
|
||||
# Managed by Ansible - DO NOT EDIT MANUALLY
|
||||
#
|
||||
# This script uploads renewed certificates to OCI Vault so that
|
||||
# fornax can distribute them to target hosts via Ansible.
|
||||
#
|
||||
# Uses Instance Principal authentication (no config file needed).
|
||||
# Called by certbot --deploy-hook after each successful renewal.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
CERT_DIR="{{ certbot_directory }}/config/live"
|
||||
LOG_PREFIX="[$(date '+%Y-%m-%d %H:%M:%S')] [vault-upload]"
|
||||
|
||||
echo "${LOG_PREFIX} Starting vault upload hook"
|
||||
|
||||
# RENEWED_LINEAGE is set by certbot to the path of the renewed cert
|
||||
# e.g. /srv/certbot/config/live/bootes.helu.ca
|
||||
if [[ -z "${RENEWED_LINEAGE:-}" ]]; then
|
||||
echo "${LOG_PREFIX} ERROR: RENEWED_LINEAGE not set — not running under certbot?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CERT_NAME=$(basename "${RENEWED_LINEAGE}")
|
||||
FULLCHAIN="${RENEWED_LINEAGE}/fullchain.pem"
|
||||
PRIVKEY="${RENEWED_LINEAGE}/privkey.pem"
|
||||
OCI="{{ certbot_directory }}/.venv/bin/oci"
|
||||
COMPARTMENT_ID="{{ oci_govern_compartment_id }}"
|
||||
VAULT_ID="{{ oci_vault_id }}"
|
||||
|
||||
# Convert dots to hyphens to match Terraform secret naming (e.g. pan.helu.ca → pan-helu-ca)
|
||||
VAULT_PREFIX="${CERT_NAME//./-}"
|
||||
|
||||
echo "${LOG_PREFIX} Processing certificate: ${CERT_NAME} (vault prefix: ${VAULT_PREFIX})"
|
||||
|
||||
if [[ ! -f "${FULLCHAIN}" ]] || [[ ! -f "${PRIVKEY}" ]]; then
|
||||
echo "${LOG_PREFIX} ERROR: Certificate files not found in ${RENEWED_LINEAGE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Look up secret OCIDs by name (Terraform creates secrets named {domain-hyphens}-fullchain/-privkey)
|
||||
lookup_secret_id() {
|
||||
local secret_name="$1"
|
||||
local result
|
||||
if ! result=$(${OCI} vault secret list \
|
||||
--auth instance_principal \
|
||||
--compartment-id "${COMPARTMENT_ID}" \
|
||||
--vault-id "${VAULT_ID}" \
|
||||
--name "${secret_name}" \
|
||||
--lifecycle-state ACTIVE \
|
||||
--all \
|
||||
--query 'data[0].id' \
|
||||
--raw-output 2>&1); then
|
||||
echo "${LOG_PREFIX} ERROR: OCI CLI failed looking up secret '${secret_name}': ${result}" >&2
|
||||
return 1
|
||||
fi
|
||||
echo "${result}"
|
||||
}
|
||||
|
||||
FULLCHAIN_SECRET_ID=$(lookup_secret_id "${VAULT_PREFIX}-fullchain") || true
|
||||
PRIVKEY_SECRET_ID=$(lookup_secret_id "${VAULT_PREFIX}-privkey") || true
|
||||
|
||||
if [[ -z "${FULLCHAIN_SECRET_ID}" ]] || [[ "${FULLCHAIN_SECRET_ID}" == "null" ]] || \
|
||||
[[ -z "${PRIVKEY_SECRET_ID}" ]] || [[ "${PRIVKEY_SECRET_ID}" == "null" ]]; then
|
||||
echo "${LOG_PREFIX} ERROR: Could not find vault secrets for ${VAULT_PREFIX} (fullchain=${FULLCHAIN_SECRET_ID:-missing}, privkey=${PRIVKEY_SECRET_ID:-missing})"
|
||||
echo "${LOG_PREFIX} Ensure 'terraform apply' has been run on bootes_certificates.tf"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "${LOG_PREFIX} Found secret OCIDs for ${VAULT_PREFIX}"
|
||||
|
||||
# Upload fullchain to OCI Vault
|
||||
FULLCHAIN_B64=$(base64 -w 0 < "${FULLCHAIN}")
|
||||
if ! upload_output=$(${OCI} vault secret update-base64 \
|
||||
--auth instance_principal \
|
||||
--secret-id "${FULLCHAIN_SECRET_ID}" \
|
||||
--secret-content-content "${FULLCHAIN_B64}" 2>&1); then
|
||||
echo "${LOG_PREFIX} ERROR: Failed to upload fullchain for ${CERT_NAME}: ${upload_output}"
|
||||
exit 1
|
||||
fi
|
||||
echo "${LOG_PREFIX} Uploaded fullchain for ${CERT_NAME}"
|
||||
|
||||
# Upload private key to OCI Vault
|
||||
PRIVKEY_B64=$(base64 -w 0 < "${PRIVKEY}")
|
||||
if ! upload_output=$(${OCI} vault secret update-base64 \
|
||||
--auth instance_principal \
|
||||
--secret-id "${PRIVKEY_SECRET_ID}" \
|
||||
--secret-content-content "${PRIVKEY_B64}" 2>&1); then
|
||||
echo "${LOG_PREFIX} ERROR: Failed to upload privkey for ${CERT_NAME}: ${upload_output}"
|
||||
exit 1
|
||||
fi
|
||||
echo "${LOG_PREFIX} Uploaded privkey for ${CERT_NAME}"
|
||||
|
||||
{% if certbot_local_cert_name is defined %}
|
||||
# Also combine cert for local HAProxy if this is the local cert
|
||||
if [[ "${CERT_NAME}" == "{{ certbot_local_cert_name }}" ]]; then
|
||||
echo "${LOG_PREFIX} Combining local cert for HAProxy: ${CERT_NAME}"
|
||||
HAPROXY_CERT="{{ haproxy_cert_path }}"
|
||||
cat "${FULLCHAIN}" "${PRIVKEY}" > "${HAPROXY_CERT}.tmp"
|
||||
mv "${HAPROXY_CERT}.tmp" "${HAPROXY_CERT}"
|
||||
chown {{ certbot_user }}:{{ haproxy_group }} "${HAPROXY_CERT}"
|
||||
chmod 640 "${HAPROXY_CERT}"
|
||||
|
||||
if systemctl is-active --quiet haproxy; then
|
||||
echo "${LOG_PREFIX} Reloading HAProxy..."
|
||||
systemctl reload haproxy
|
||||
fi
|
||||
fi
|
||||
{% endif %}
|
||||
|
||||
# Update certificate metrics
|
||||
{{ certbot_directory }}/hooks/cert-metrics.sh
|
||||
|
||||
echo "${LOG_PREFIX} Vault upload hook completed successfully"
|
||||
Reference in New Issue
Block a user