Automate Terraform Deployments: (1/2) Detect¶
This workflow is part of the Terraform-to-Azure deployment automation pipeline.
Its primary role is to detect changes toterraform.tfvars
files in pull requests or direct pushes to themain
branch, and then trigger targeted downstream processing for each changed file.
Purpose¶
- Change Detection: Identify modifications to any
terraform.tfvars
file. - Targeted Execution: For each changed file, trigger a reusable downstream workflow to process, test, and deploy changes.
- Efficiency: Avoid running unnecessary jobs when no
.tfvars
changes are detected. - Modularity: Enable environment-specific or file-specific CI/CD runs.
Trigger Conditions¶
The workflow runs when:
- A push is made to the main
branch and a .tfvars
file changes.
- A pull request is opened or updated and a .tfvars
file changes.
on:
push:
branches: [main]
paths: ["**/terraform.tfvars"]
pull_request:
paths: ["**/terraform.tfvars"]
Workflow Logic¶
Step 1 – Detect Changes¶
- Uses a custom action (
.github/actions/detect-changed-tfvars-files
) to determine which.tfvars
files have changed. - Handles both PR and
main
branch contexts. - Outputs a JSON array of changed file paths.
Step 2 – Early Exit¶
- If no
.tfvars
files have changed, the workflow stops immediately to save resources.
Step 3 – Process Changes¶
- If changes are detected:
- A matrix job is created, with one job per changed
.tfvars
file. - Each job calls the reusable workflow
.github/workflows/process-changed-tfvars-files.yaml
. - Secrets are passed securely to the downstream workflow.
Concurrency Control¶
- Ensures only one run per branch/ref is active at a time. - Prevents overlapping runs that could cause deployment conflicts.Security Considerations¶
- Principle of Least Privilege: Only required secrets are passed to the downstream workflow.
- Scoped Permissions:
- Secrets include:
GRINNTEC_TERRAFORM_DEPLOYMENTS_AZURE_PAT
AZURE_SUBSCRIPTION_ID
AZURE_TENANT_ID
AZURE_CLIENT_ID
INFRACOST_API_KEY
Key Components¶
Component | Description |
---|---|
.github/actions/detect-changed-tfvars-files |
Custom action to detect changed .tfvars files. |
.github/workflows/process-changed-tfvars-files.yaml |
Reusable workflow to process each changed file. |
Matrix Strategy | Runs jobs in parallel for each changed file. |
Concurrency Group | Prevents overlapping runs for the same branch. |
Example Flow¶
- Developer updates
environments/prod/terraform.tfvars
in a PR. - Workflow detects the change.
- Matrix job triggers
process-changed-tfvars-files.yaml
with: - Downstream workflow runs Terraform plan/apply for that environment.
Maintenance Notes¶
- Update detection logic in
.github/actions/detect-changed-tfvars-files
if file structure changes. - Ensure
.github/workflows/process-changed-tfvars-files.yaml
supports all environments. - Review and rotate secrets regularly.
Full Workflow YAML¶
(Included for reference — matches the implemented configuration)
name: Detect Changed terraform.tfvars Files
permissions:
contents: write
checks: write
id-token: write
on:
push:
branches: [main]
paths: ["**/terraform.tfvars"]
pull_request:
paths: ["**/terraform.tfvars"]
concurrency:
group: terraform-checks-${{ github.ref }}
cancel-in-progress: false
jobs:
detect-changed-tfvars-files:
name: Detect Changed terraform.tfvars Files
runs-on: ubuntu-latest
outputs:
changed_files: ${{ steps.detect-changed-tfvars-files.outputs.changed_tfvars }}
steps:
- name: Checking out repository
run: echo "::notice::Checking out the repository with full history for change detection"
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.ref }}
- name: Sync to latest
run: |
git fetch origin main
git checkout main
git reset --hard origin/main
- name: Detect Changed terraform.tfvars Files
id: detect-changed-tfvars-files
uses: ./.github/actions/detect-changed-tfvars-files/
- name: Early Exit
if: ${{ steps.detect-changed-tfvars-files.outputs.changed_tfvars == '' }}
run: |
echo "::notice::No changes detected in .tfvars files. Skipping further steps."
exit 0
process-tfvars-files:
name: Process Changed terraform.tfvars File
needs: detect-changed-tfvars-files
if: ${{ needs.detect-changed-tfvars-files.outputs.changed_files != '' }}
strategy:
fail-fast: false
matrix:
tfvars_file: ${{ fromJson(needs.detect-changed-tfvars-files.outputs.changed_files) }}
uses: ./.github/workflows/process-changed-tfvars-files.yaml
with:
tfvars_file: ${{ matrix.tfvars_file }}
secrets:
GRINNTEC_TERRAFORM_DEPLOYMENTS_AZURE_PAT: ${{ secrets.GRINNTEC_TERRAFORM_DEPLOYMENTS_AZURE_PAT }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
INFRACOST_API_KEY: ${{ secrets.INFRACOST_API_KEY }}