Skip to content

Terraform-to-Azure CI/CD Architecture

This CI/CD system is built around two modular GitHub Actions workflows:

  1. Detect Changed .tfvars Files

    • Watches for .tfvars changes in PRs or pushes to main.
    • Identifies changed files and triggers targeted processing.
  2. Process Changed .tfvars Files

    • Runs for each changed file.
    • Handles validation, linting, security scanning, cost estimation, and conditional apply/destroy to Azure.

The design ensures fast, targeted, and secure deployments without affecting unrelated environments.


Workflow Responsibilities

Workflow Responsibility Key Outputs
Detect Changed .tfvars Files Identify changed .tfvars files and trigger processing. JSON array of changed file paths.
Process Changed .tfvars Files Fully process one .tfvars file: validate, scan, plan, cost, and deploy/destroy. Updated Azure infrastructure or destroyed resources.

Security Model

  • OIDC Authentication – No static Azure credentials.
  • Scoped Secrets – Only required secrets passed to jobs.
  • Concurrency Control – Prevents overlapping runs for the same file.
  • State Isolation – Backend config ensures environment separation.

Benefits

  • Targeted Deployments – Only changed environments are processed.
  • Parallel Execution – Multiple .tfvars changes run simultaneously.
  • Modular & Maintainable – Easy to extend or modify.
  • Security-First – OIDC, least privilege, secret minimization.
  • Cost Awareness – Infracost integrated before apply.

Swimlane Diagram

flowchart TB

    %% Developer lane
    subgraph Dev[Developer]
        A[Commit changes to repo]
        B[Push to main or open PR]
        A --> B
    end

    %% Workflow 1 lane
    subgraph W1[Workflow 1 Detect Changed tfvars]
        C[Trigger on tfvars change]
        D[Checkout and sync repo]
        E[Detect changed tfvars files]
        F[Exit workflow]
        G[Matrix job one per file]
        C --> D --> E
        E -->|No changes| F
        E -->|Changes found| G
    end

    %% Workflow 2 lane
    subgraph W2[Workflow 2 Process Changed tfvars]
        H[Azure login OIDC]
        I[Checkout repo]
        J[Show file and read CI mode]
        K[Configure git for private modules]
        L[Cache providers and setup terraform]
        M[Ensure lockfile exists]
        N[Extract variables from tfvars]
        O[Create backend config]
        P[Terraform format lint validate]
        Q[Terraform plan pre apply]
        R[Security scan checkov]
        S[Cost estimation infracost]
        U{CI mode}
        W[Terraform plan only]
        X[Terraform apply]
        Y[Terraform destroy]
        Z[Azure infra updated]
        H --> I --> J --> K --> L --> M --> N --> O --> P --> Q --> R --> S --> U
        U -->|plan| W --> Z
        U -->|apply| X --> Z
        U -->|destroy| Y --> Z
    end

    %% Cross‑lane connections
    B --> C
    G --> H

    %% Colour definitions
    classDef dev fill:#d0e6ff,stroke:#003366,stroke-width:1px;
    classDef w1 fill:#d5f5e3,stroke:#145a32,stroke-width:1px;
    classDef w2 fill:#fdebd0,stroke:#7d6608,stroke-width:1px;
    classDef decision fill:#fff3cd,stroke:#7d6608,stroke-width:1px;

    %% Assign colours
    class A,B dev;
    class C,D,E,F,G w1;
    class H,I,J,K,L,M,N,O,P,Q,R,S,W,X,Y,Z w2;
    class U decision;