Skip to content

Certificate Sync Role Usage Guide

Azure IRE only, for now

Today this role is deployed only in the Azure IRE, on the perimeter auth proxy, and azure_keyvault is the only implemented certificate_sync_source — so there is nothing to configure in an AWS deployment yet. An AWS customer fork installs the proxy's certificate the ordinary way, per Perimeter Auth.

AWS is a future option, not a closed door: aws_secretsmanager is reserved with the same base64 PKCS#12 contract (IMDSv2 instance-profile credentials and a SigV4 GetSecretValue), so validation, swap and reload stay one code path when someone implements it.

Keeps a TLS certificate file pair synced from a cloud secret store with the machine's own identity — no stored credential. The role installs certificate-sync, a systemd oneshot service plus timer that fetches the certificate's PKCS#12 bundle, and swaps the local PEM pair and reloads the consumer only when a new version appears. Renewing the certificate is then one upload to the secret store — no Ansible run; every host follows on its next timer tick.

The flagship use is the perimeter auth proxy on Azure: one Key Vault certificate backs the Application Gateway listeners (key_vault_secret_id, self-polling roughly every 4 hours) and, through this role, nginx — so both consumers renew from a single import. Azure Key Vault is the only implemented source today; aws_secretsmanager is reserved for a future AWS implementation, with the same PKCS#12 contract.

A fetched certificate is installed only after it proves it matches its private key, is not expired, and covers every name in certificate_sync_expected_names — a bad upload never reaches the host. The reload is verified rather than trusted (optional config test first, error-log scan after), and a failed reload restores the previous files.

Requirements

Requirement Details
python3-cryptography on the target Installed by the role from the OS repositories. Nothing else is needed on the host — no az CLI, curl or jq.
Network access The target host must reach its cloud's metadata service (169.254.169.254, link-local) and the secret store's data-plane endpoint — for Azure Key Vault, https://<vault>.vault.azure.net, which for a private-endpoint-only vault means resolving privatelink.vaultcore.azure.net and reaching the private endpoint on 443.

Prerequisites

  1. A machine identity with read access to the secret — on Azure, a managed identity (system-assigned, or user-assigned pinned via certificate_sync_identity_resource_id) holding Key Vault Secrets User on the vault.
  2. The certificate imported into the store — on Azure, az keyvault certificate import --vault-name <vault> --name <secret-name> --file <cert.pfx>; a Key Vault certificate exposes its PKCS#12 bundle as a secret of the same name, and the role always fetches the latest version.
  3. Run this role before the consumer's deploy — the first sync run, which happens during the converge, is what puts the certificate in place; while the consumer's unit is inactive the files land without a reload.

Usage

The role is single-purpose and declarative — no tags; converging it does everything, ends by running one real sync, and fails with pointed hints when an identity, grant, DNS path, or secret is missing:

ansible-playbook --limit=app_nginx playbooks/deploy-certificate-sync.yml --become

The consuming group's vars supply everything — see Tags and Variables for the reference and group_vars/ire_copier_azure_app_nginx/ for the worked nginx example. On the host, journalctl -u certificate-sync shows what the timer last did, systemctl list-timers 'certificate-sync*' shows when it runs next, and systemctl start certificate-sync runs a sync immediately, identical to a scheduled one.