Terraform Unified Workflow
Auto-generated by
scripts/generate_docs.py— edit the workflow YAML, not this file.
File: .github/workflows/terraform-unified.yml
Description
Workflow: terraform-unified.yml — Main Infrastructure Orchestration
The single entry point for all Terraform operations across tenants and
customers. Supports plan / apply / destroy for any module or MODULE=ALL.
Input relationship:
TENANT_NAME + CLIENT_NAME + DEVOPS_ENV → configs///.json
MODULE → which submodule directory to target
TARGET_RAAS_ENV → env-raas sub-env (prod/nonprod/all)
MODULE=ALL behaviour:
Reads module list from the customer's JSON config (NOT from .gitmodules).
base-account and base-connectivity are excluded from ALL runs because they
are phase-1 modules managed separately.
For destroy, the module order is reversed so resources are torn down in the
correct dependency order.
env-raas special case:
env-raas contains both prod and nonprod sub-environments. When
TARGET_RAAS_ENV=all, the matrix fans out into two entries so both
sub-environments are processed in the same workflow run.
Security scan integration:
Optional Trivy scan runs before any Terraform operations when
SECURITY_SCAN=true. The terraform job is skipped if the scan fails or if
APPLY_FIXES=true (fixes must be applied in a separate run).
Triggers
Trigger types: workflow_dispatch
Manual Dispatch Inputs (workflow_dispatch)
| Input | Type | Required | Default | Description |
|---|---|---|---|---|
ACTION |
choice |
yes | — |
The Terraform action to perform. Options: plan, apply, destroy |
TENANT_NAME |
string |
yes | raas |
The customer tenant in which we are deploying to |
CLIENT_NAME |
string |
yes | rhapsody |
The customer in which we are deploying to |
DEVOPS_ENV |
choice |
yes | staging1 |
IaC environment (e.g., staging1, staging2, or prod). Options: staging1, staging2, staging3, prod |
MODULE |
choice |
yes | base-counter |
Specific Terraform module to target, or ALL/NONE. Options: NONE, base-account-phase1, base-connectivity-phase1, base-counter, base-core, base-diagnostics, env-raas, env-snapshots, base-cifs, base-sftp, base-expressroute, base-peering, base-routes, base-vpn, base-monitoring, env-upwind, env-raas-lb, env-raas-api, env-directcifs, env-filetransfer, base-fwrules, ALL |
TARGET_RAAS_ENV |
choice |
yes | all |
Target RaaS environment (prod/nonprod/all) for env-raas module state file. Options: prod, nonprod, all |
SECURITY_SCAN |
choice |
yes | false |
Execute infrastructure security scan (Trivy): 'true' or 'false' Options: true, false |
AI_PROVIDER |
choice |
no | copilot-cli |
AI provider for security scan remediation Options: copilot-cli, gemini, openai |
APPLY_FIXES |
choice |
no | false |
Apply AI-suggested security fixes (requires manual approval) Options: true, false |
SAFETY_ENFORCE |
choice |
no | true |
Block apply on an outage-class plan classification (the plan-safety gate). 'true' enforces; 'false' is the emergency kill-switch (gate becomes report-only). Options: true, false |
Permissions
id-token:writecontents:read
Jobs
setup — Setup Deployment Matrix
| Property | Value |
|---|---|
| Runs on | ubuntu-latest |
Outputs:
matrix— ${{ steps.set-matrix.outputs.matrix }}env_tier— ${{ steps.resolve-runner-env.outputs.env_tier }}region— ${{ steps.fetch-region.outputs.region }}
Steps:
| Step | Action / Detail
---|---|---
1 | Checkout repository | actions/checkout@v4
2 | Fetch customer region from CosmosDB | Inline script: python3 -m venv /tmp/region-venv
3 | Resolve Runner Environment Tier | Inline script: env_tier="${{ github.event.inputs.DEVOPS_ENV }}"
4 | Setup Python for CosmosDB Query (conditional) | actions/setup-python@v5
5 | Determine Target Environments and Modules | Inline script: action="${INPUT_ACTION}"
security_scan — Security Scan
| Property | Value |
|---|---|
| Uses (reusable) | ./.github/workflows/callable-security-scan.yml |
Condition: github.event.inputs.SECURITY_SCAN == 'true'
Inputs passed (with):
MODULE:${{ inputs.MODULE }}TENANT_NAME:${{ inputs.TENANT_NAME }}CLIENT_NAME:${{ inputs.CLIENT_NAME }}DEVOPS_ENV:${{ inputs.DEVOPS_ENV }}AI_PROVIDER:${{ inputs.AI_PROVIDER || 'copilot-cli' }}APPLY_FIXES:${{ inputs.APPLY_FIXES == 'true' }}
Secrets passed:
GEMINI_API_KEYOPENAI_API_KEYCOPILOT_PAT_KEYAPP_PRIVATE_KEY
terraform — ${{ inputs.ACTION }} | ${{ matrix.module }} | ${{ matrix.environment }}${{ matrix.peering_name && format(' | {0}', matrix.peering_name) || '' }}
| Property | Value |
|---|---|
| Runs on | self-hosted, terraform, ${{needs.setup.outputs.env_tier}}, ${{needs.setup.outputs.region}}, ${{inputs.TENANT_NAME}} |
| Depends on | setup, security_scan |
| Environment | ${{ inputs.TENANT_NAME }} |
Condition: always() && (needs.security_scan.result == 'success' || needs.security_scan.result == 'skipped') && inputs.APPLY_FIXES != 'true'
Strategy:
fail-fast:Truemax-parallel:1include: 43 entries
Steps:
| Step | Action / Detail
---|---|---
1 | Cleanup Step (conditional) | Inline script: rm -rf "${WORKSPACE_DIR}"/*
2 | Checkout Code | actions/checkout@v4
3 | Checkout with submodules | ./.github/actions/checkout-with-submodules
4 | Checkout Submodules | ./.github/actions/checkout-repos
5 | Fetch Azure Credentials | ./.github/actions/fetch-azure-credentials
6 | Setup Terraform Environment | ./.github/actions/setup-terraform-vars
7 | Initialize Terraform | ./.github/actions/terraform-init
8 | Plan Terraform (conditional) | ./.github/actions/terraform-plan
9 | Apply Terraform (conditional) | ./.github/actions/terraform-apply
10 | Destroy Terraform (conditional) | ./.github/actions/terraform-destroy
11 | 📊 AI Triage Summary (conditional) | Inline script: if [[ "$ACTION" == "plan" ]]; then
12 | Fail job if Terraform failed (conditional) | Inline script: echo "::error::Terraform ${INPUT_ACTION} failed for module ${MODULE_NAME}. See A…
Secrets Referenced
ACTIVATION_KEYAPP_PRIVATE_KEYAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYCOPILOT_PAT_KEYCORALOGIX_API_KEYCOSMOSDB_CREDS_KEY_SECRETGEMINI_API_KEYOPENAI_API_KEYRHN_ORG_IDS1_API_KEYS1_TOKENSSH_PUB_KEYUPWIND_CLIENT_SECRET
Composite Actions Used
checkout-reposcheckout-with-submodulesfetch-azure-credentialssetup-terraform-varsterraform-applyterraform-destroyterraform-initterraform-plan
_📋Auto-Generated Documentation | Team: Azure Infrastructure | Generated by: AI Documentation Engine | Date: 2026-08-14 22:10 UTC _