-
Notifications
You must be signed in to change notification settings - Fork 95
CI CD Pipeline
Chris Panagiotidis edited this page Jun 13, 2026
·
3 revisions
The repository uses GitHub Actions as the Terraform delivery pipeline.
Workflow source:
Custom action source:
The workflow runs on:
| Trigger | Scope |
|---|---|
Push to main
|
Terraform, tfvars, modules, landing zones, environment files |
Pull request to main
|
Terraform and tfvars files |
| Manual workflow dispatch | Select environment and action |
Manual inputs:
| Input | Values |
|---|---|
environment |
cheap-lab, dev, lab, prod
|
action |
plan, apply, destroy
|
destroy_confirm |
Must be DESTROY for destroy |
Workflow permissions include:
permissions:
contents: write
pull-requests: write
security-events: write
id-token: writeid-token: write is required for Azure OIDC login.
| Secret | Purpose |
|---|---|
AZURE_CLIENT_ID |
Federated Entra application client ID |
AZURE_TENANT_ID |
Entra tenant ID |
AZURE_SUBSCRIPTION_ID |
Target Azure subscription ID |
TF_STATE_RG |
Resource group containing Terraform state storage account |
TF_STATE_SA |
Terraform state storage account name |
INFRACOST_API_KEY |
Optional Infracost key |
Do not configure AZURE_CREDENTIALS for this pipeline.
| Stage | Job | Purpose | Blocking |
|---|---|---|---|
| 1 | format |
terraform fmt -check -recursive -diff |
Yes |
| 2 | validate |
terraform init -backend=false and terraform validate
|
Yes |
| 3 | security-tfsec |
tfsec Terraform scan | Yes |
| 3 | security-checkov |
Checkov Terraform scan | Yes |
| 3 | secret-scan |
Gitleaks secret scan | Yes |
| 4 | tflint |
Terraform lint | Advisory in current workflow |
| 4 | policy-check |
OPA policy evaluation | Yes |
| 4 | terraform-docs |
Documentation generation/check | Depends on action behavior |
| 5 | graph |
Terraform graph visualization | Yes for later analysis |
| 5 | module-versions |
Module and provider version analysis | Yes for plan |
| 6 | cost-estimate |
Infracost estimate | Advisory |
| 7 | plan |
Terraform plan with remote state | Yes |
| 8 | apply |
Manual apply from dispatch | Protected by GitHub environment |
| 9 | destroy |
Manual destroy from dispatch | Requires DESTROY and environment protection |
| 10 | metrics |
Post-apply metrics | Runs after apply |
| Workflow area | What it proves | Evidence to keep |
|---|---|---|
| Format | Terraform files follow a consistent style | Job output with no diff |
| Validate | Terraform graph is syntactically valid |
terraform validate success output |
| Security scans | Known risky IaC patterns are caught | tfsec and Checkov job results |
| Secret scan | Repository does not contain obvious secrets | Gitleaks job result |
| OPA policy | Project-specific guardrails are enforced | Policy-check output |
| Plan | Backend, profile, variables, and Azure auth work | Plan summary and artifact |
| Apply | Approved plan can be applied | Apply job and state backup result |
| Destroy | Teardown requires explicit confirmation | Destroy job approval and result |
The workflow separates hard gates from advisory checks:
- Hard gates: format, validate, tfsec, Checkov, secret scan, OPA policy, plan.
- Advisory gates: TFLint in the current workflow, cost estimate when Infracost is not configured.
- Protected operations: apply and destroy through GitHub environments.
This keeps the lab safe while still allowing cost and lint output to guide improvements.
The Azure login step should prove:
| Proof | Expected value |
|---|---|
| Authentication method | Federated token through GitHub OIDC |
| Client secret JSON | Not required |
id-token: write |
Present in workflow permissions |
| Azure identity | Entra app registration with federated credential |
| Subject | Matches repo branch, PR, or environment pattern |
Failure signs:
- Azure login asks for
AZURE_CREDENTIALS. - Workflow lacks
id-token: write. - Federated credential subject does not match the workflow context.
- Apply works locally but fails in Actions because the CI identity lacks RBAC.
| Action | Source | Purpose |
|---|---|---|
plan |
.github/actions/plan | Azure login, backend init, Terraform plan, outputs plan metadata |
apply |
.github/actions/apply | Applies saved plan artifact |
destroy |
.github/actions/destroy | Controlled destroy |
state-backup |
.github/actions/state-backup | Copies state to backup container before apply/destroy |
secret-scan |
.github/actions/secret-scan | Runs Gitleaks |
policy-check |
.github/actions/policy-check | Runs OPA/Conftest style checks |
cost-estimate |
.github/actions/cost-estimate | Runs cost analysis |
graph |
.github/actions/graph | Generates Terraform graph artifact |
module-version |
.github/actions/module-version | Reviews module and provider versions |
terraform-docs |
.github/actions/terraform-docs | Documentation automation |
resource-inventory |
.github/actions/resource-inventory | Captures deployed resource inventory |
changelog |
.github/actions/changelog | Writes environment changelog |
metrics |
.github/actions/metrics | Writes deployment metrics |
terratest |
.github/actions/terratest | Optional Go/Terratest action |
validate |
.github/actions/validate | Reusable validation action |
security |
.github/actions/security | Reusable security action |
The plan job:
- Uses OIDC authentication.
- Initializes backend using
TF_STATE_RGandTF_STATE_SA. - Uses state key
<environment>.terraform.tfstate. - Uses profile file
environments/<environment>.tfvars. - Publishes plan artifact for apply.
- Exposes plan counts: add, change, destroy.
The apply job:
- Runs only for manual dispatch with
action = apply. - Requires the plan job to succeed.
- Uses the selected GitHub environment.
- Backs up state before applying.
- Applies the saved plan artifact.
- Generates resource inventory and changelog afterward.
The destroy job:
- Runs only for manual dispatch with
action = destroy. - Requires
destroy_confirm = DESTROY. - Uses GitHub environment
<environment>-destroy. - Backs up state before destroying.
- Passes the selected tfvars file.
Configure GitHub environments:
| Environment | Protection |
|---|---|
cheap-lab |
Optional approval |
lab |
Required approval |
dev |
Required approval if shared subscription |
prod |
Required approval |
cheap-lab-destroy |
Required approval |
lab-destroy |
Required approval |
dev-destroy |
Required approval |
prod-destroy |
Required approval from owner |
- OIDC login succeeds without client secret.
-
format,validate,tfsec,checkov,secret-scan, andpolicy-checkfail PRs when findings exist. - Cost estimate is visible but does not block when Infracost is not configured.
- Plan artifact is created and consumed by apply.
- State backup container is created before state copy.
- Destroy requires both text confirmation and environment approval.
| Failure | Likely cause | Fix path |
|---|---|---|
terraform fmt fails |
Terraform files are not formatted | Run terraform fmt -recursive locally and commit the formatting |
terraform validate fails |
Missing variable, invalid type, provider graph issue | Fix Terraform before planning |
| tfsec or Checkov fails | Resource violates security baseline | Harden resource or document justified suppression |
| Gitleaks fails | Secret-like value was committed | Remove value, rotate if real, recommit clean history as needed |
| OPA fails | Project guardrail denied the plan | Fix variables/resources or update policy with review |
| Azure login fails | OIDC subject, audience, client ID, tenant ID, or RBAC is wrong | Review federated credential and role assignments |
| Plan fails on backend | State storage secret or permissions are wrong | Review TF_STATE_RG, TF_STATE_SA, and storage RBAC |
For important changes, attach or record:
- Workflow run URL.
- Commit SHA.
- Selected environment.
- Plan add/change/destroy counts.
- Security scan pass/fail summary.
- OPA pass/fail summary.
- Cost estimate or manual cost review.
- Apply or destroy approval record.
Next page: Testing and Validation
- Architecture Overview
- Full Environment Inventory
- Network Topology
- Shared Services
- Workloads
- Module Reference
- Security Model
- Security Operations
- Identity and Access
- Governance and Policy
- Production Readiness Review
- Monitoring and Diagnostics
- Operations Runbooks
- Azure Portal Validation Evidence
- Cost Management
- Disaster Recovery and Resilience