Distribution overview
How modules work — Execute, DryRun, Validate, HealthCheck. Fan-out concurrency, batch sizing, post-distribution validation, and how distribution failures interact with renewal.
The module system
Distribution is implemented as modules. CertAutoPilot ships seventeen built-in modules — SSH, Kubernetes, IIS, WinRM, F5 BIG-IP, Citrix NetScaler, HashiCorp Vault, Huawei Cloud, Cloudflare, cPanel/WHM, MerlinCDN, AWS ACM, Azure Key Vault, Palo Alto PAN-OS, Webhook, Email/SMTP, Microsoft Exchange. Each module implements four operations:
| Operation | What it does |
|---|---|
Execute | Push the certificate + key + chain to the target. |
DryRun | Show exactly what Execute would do, without doing it. Used by approvals. |
Validate | Interface method, currently unused. Post-deploy verification runs through the target's validation endpoints, not this method. |
HealthCheck | Probe reachability and credentials without deploying anything. See Health checks. |
Rollback is not a module operation — there is no Rollback method on the interface. A rollback re-runs Execute with a previous retained certificate version. See Rollback.
Distribution targets
A target is a (module, credential, location) tuple. Examples:
- SSH module + ssh-key credential +
nginx-prod-01:/etc/nginx/ssl/site.pem - Kubernetes module + kubeconfig +
cluster=prod / ns=apps / secret=tls-www - F5 module + iControl creds +
partition=Common / profile=clientssl-www
Targets are reusable — many certificates can attach the same target.
Fan-out execution
When a certificate has many targets — say, 80 SSH hosts — distribution can run fan-out: split into batches, run each batch concurrently. Fan-out is disabled by default (distribution_fanout_threshold: 0); set a positive threshold in Settings → General to enable it. Batch size defaults to 50 (distribution_fanout_batch_size), and SSH concurrency uses the module default of 10 unless overridden (distribution_ssh_max_concurrency).
Failures within a batch don't stop other batches. Each target gets its own result status — success, failed, partial or skipped — plus a fan-out state of pending_retry while a retry child is outstanding.
DryRun & approvals
If approval is required, the operator's Submit produces a request with the DryRun output for every attached target. Approvers see exactly what files will land where, what services will reload, what API calls will fire — before they approve.
A dry run resolves the same per-certificate overrides the real run would (target overrides, PathSet/ActionSet selection, auto-generated object names), so the plan describes the run that would actually happen — not the target's defaults.
Findings come back in two lists. Warnings are things to act on: something that will change, or a setting that will not work. Notes are what the preview could not determine — a remote system that will not report a fact is a limit of the preview, not a problem with the deployment, and mixing the two only teaches operators to skim the warnings. What each module reports:
| Module | The preview says |
|---|---|
| IIS | Every binding it would touch: replace (with the certificate on it today), already current, Central Certificate Store skipped, excluded by host header — plus the site's bindings and application pools |
| F5 BIG-IP | The object name and partition, one row per client-ssl profile (update, or skipped because the profile is missing), the chain it would install, and a warning when a profile already serves another CertAutoPilot certificate of the same key type |
| NetScaler | The certkey name, the file uploads, and whether it creates or updates in place — including how many vservers keep their bindings |
| Kubernetes | Every Secret it would create or update, and the ones already current, plus each workload it would restart |
| AWS ACM | Whether it creates or re-imports, what the ARN covers today (domain, status, expiry, how many resources use it) — and it refuses up front an ARN that ACM issued itself, which can never be imported over |
| Cloudflare | Create or update, the hosts the certificate being replaced serves, and a warning when the zone's plan cannot hold a custom certificate at all |
| Azure Key Vault | Create or new version (with the reason), and a warning when the name belongs to another certificate |
| PAN-OS | Create or update of the named object, including material already sitting uncommitted in the candidate configuration |
| Huawei Cloud | Create or update of the ELB/WAF certificate object, resolved the same way the deploy resolves it; for CDN, whether the domain exists at all |
| Exchange | The servers it would reach, the import and enable steps, the certificate OWA/ECP/EWS currently serves, and a warning when the certificate's key type — or a wildcard subject with POP/IMAP selected — cannot work |
| cPanel / WHM | Per domain, the install — and on cPanel what certificate is on that domain today |
| SSH / WinRM | Per file: create, or leave unchanged, compared against the file already on the host |
| SMTP / Webhook | The recipients or endpoint it would send to, proven by an actual probe |
A preview never writes. When a lookup it needs is unavailable, it says so in a warning and keeps the rest of the plan rather than guessing.
Two org-wide toggles decide whether an operator's distribution work needs approval (admins and owners always bypass):
- Distribution approval (
require_approval_for_distribution, OFF by default) gates operator distribution link / update / unlink / execute / rollback. Only the manual operator action is gated — the scheduler's automatic post-renewal distribution sweep is not gated, so renewals keep flowing to their targets. Shell-mode distributions still require the Admin role to execute regardless of this toggle. - Config-change approval (ON by default) gates operator edits to targets, target-groups, PathSets/ActionSets, and project-variables.
See Approval workflow and Auth & RBAC.
Post-distribution validation
After Execute, the worker runs every validation endpoint configured on the resolved targets: it opens a TLS connection and compares the served leaf certificate's SHA-256 fingerprint against the one just deployed.
Per-endpoint dial timeout defaults to 5 seconds with 3 attempts / 2-second delay; all configurable per endpoint. Validation is opt-in for every module: a target with no endpoints configured is not verified, and the worker caps a single target's whole validation phase at 5 minutes.
Rollback
A rollback re-deploys a previous retained certificate version — from the certificate's per-renewal artifact history — through the module's normal deploy path. One uniform mechanism, no per-module snapshots: all seventeen modules support manual rollback (the two push modules, Webhook and SMTP, re-send the previous version), while auto-rollback covers the fifteen stateful modules only. Trigger it from the version picker on the Distribution tab or via the API; a per-distribution auto_rollback_on_failure toggle rolls back automatically when a run finishes failed/partial and at least one target changed. After a successful rollback the distribution's status is rolled_back and stays that way until the next renewal rolls forward. Details, eligibility rules, and the capability matrix: Rollback.
Distribution & renewal
Renewal and distribution are decoupled: a renewal is successful the moment the new certificate is stored — distribution is then triggered automatically for every enabled distribution of the certificate. If a distribution fails, the renewal is NOT re-run; instead the failed distribution is retried by the distribution sweep (bounded automatic retries per certificate version), failure notifications fire, and the targets keep serving the previous certificate until a re-push succeeds or an operator re-runs the distribution manually.
API
POST /api/v1/projects/{project}/targets
GET /api/v1/projects/{project}/certificates/{id}/distributions
POST /api/v1/projects/{project}/certificates/{id}/distributions/{distId}/execute
POST /api/v1/projects/{project}/certificates/{id}/distributions/{distId}/dry-run
See also
- Distribution primitives — Path Sets, Action Sets, Credentials, Variables, Validation, Fan-out
- External secret stores — read a credential from Vault/OpenBao or PAM360 instead of storing it
- Targets & groups
- SSH · Kubernetes · IIS · WinRM
- F5 BIG-IP · NetScaler · Vault · Huawei · AWS ACM · Azure Key Vault · Cloudflare · cPanel · MerlinCDN · Exchange · PAN-OS · Webhook · SMTP
- Approval workflow (gating Execute)
- Renewal & rotation
partial run is not retried automaticallyOnly a wholly failed distribution is re-armed by the renewal sweep. partial is excluded on purpose: some targets already have the certificate, and re-running would deploy to them again — re-executing ActionSets and service restarts that already succeeded. Re-run a partial distribution manually from the certificate's Distributions tab.