Approvals and Gates¶
CAPTF can stop a TerraformCluster before it changes infrastructure and wait for a person to say yes. It has two such gates, and they apply to the cluster kind only. This chapter explains what each gate does, what it binds, what is deliberately not gated, and what an operator needs to run them safely. The task-oriented commands are in Plan Approval.
The pages:
- This page: the gates, a decision table and the scaling questions.
- Manual plan approval:
applyPolicy: Manual, the plan Job,status.planand the approved apply. - What the plan hash binds: the
p2:fingerprint. - The destructive-plan guard: the check on every cluster apply under
Automatic. - Operating the gates: commands, conditions, events, retries, upgrades and who can approve.
- Other manual actions: restores, abandoning an object, and the fixes that are not approvals.
- Limits: what an approval does and does not promise.
The two gates¶
| Gate | Set by | What it stops | Annotation that releases it | Binds |
|---|---|---|---|---|
| Manual plan approval | spec.applyPolicy: Manual on a TerraformCluster or its template | Every apply except the first one | captf.io/approve-plan=<plan hash> | The plan: what each change does, and the output changes |
| Destructive-plan guard | Always on, for every TerraformCluster apply | An apply whose plan deletes or replaces a resource | captf.io/approve-destructive-plan=<inputs hash> | The inputs, not the plan |
Under Manual the first gate subsumes the second: approving a plan also approves the deletes and replacements that plan lists, so the second annotation is never needed there.
Both gates are specific to TerraformCluster, with one narrow extension. applyPolicy exists on no other kind, and the Job builder adds the guard to a TerraformCluster’s apply, and to a TerraformMachinePool’s apply only when it renders cluster exports that differ from its last successful apply (see Machine pools). A TerraformMachine’s apply is never gated: its instance is immutable, and Cluster API replaces it rather than its apply changing it. Destroy, restore, refresh and drift Jobs are never gated on any kind.
What is gated¶
An apply decision has one reason; the reason decides whether a gate sees it.
| Situation | Kind | Automatic | Manual |
|---|---|---|---|
| First apply of a new object (no state) | TerraformCluster | Guard runs, nothing to delete | Not gated, applies at once |
| Changed inputs (image, spec, variables) | TerraformCluster | Guard: blocked if the plan deletes or replaces | Plan, then wait for approve-plan |
| Retry after a failed apply | TerraformCluster | Guard | Plan, then wait (an earlier approval is reused if the re-plan matches) |
Drift remediation (drift.action: Remediate) | TerraformCluster | Guard | Plan, then wait |
| State with no inputs hash | TerraformCluster | Guard | Plan, then wait |
| Apply that renders a changed set of cluster exports | TerraformMachinePool | Guard: held if the plan deletes or replaces; the pool keeps applying the last exports | Not applicable: no applyPolicy |
| Any other apply | TerraformMachinePool | Not gated | Not applicable: no applyPolicy |
| Any apply | TerraformMachine | Not gated | Not applicable: no applyPolicy |
| Destroy, restore, refresh, drift check | Any | Not gated | Not gated |
Scaling is not gated¶
Scaling does not go through an approval, so a large change to machine counts does not wait for one:
- Scaling a
MachineDeploymentup createsTerraformMachineobjects. Each one’s first apply creates its machine; there is nothing for a gate to check. - Scaling it down deletes
Machineobjects. After Cluster API drains them, eachTerraformMachineruns a destroy Job, which is never gated. - A fixed-replica
MachinePoolre-applies its pool module whenspec.replicaschanges. Such an apply is not gated, unless it also renders changed cluster exports. - An autoscaled
MachinePoolscales in the cloud, with no Terraform run at all (see Machine Pools).
A 100-machine MachineDeployment therefore scales without an approval. If a change to shared infrastructure must wait for a person, that infrastructure belongs in the cluster module. See Limits for how cluster outputs reach machines and pools.
In this section¶
-
Approve a Plan
The commands to review and approve a destructive plan or a manual plan.
-
Manual Plan Approval
applyPolicy: Manual, the plan Job, status.plan and the approved apply.
-
What the Plan Hash Binds
The p2: fingerprint an approval names, and what it covers.
-
The Destructive-Plan Guard
The check on every cluster apply under Automatic.
-
What Approval Does Not Guarantee
What an approval does and does not promise.
Where the state lives¶
An approval rests on three things that other chapters describe:
- the plan key, a Secret that makes the plan hash a keyed value (see Run inputs and the plan key);
status.plan, written by the controller from what the runner reports;- annotations on the object, which are the approval itself.