This reusable GitHub Actions workflow is invoked by the Detect Changed main.tf Files workflow. It processes one main.tf file at a time, performing:
- Terraform environment setup and validation
- Security scanning and cost estimation  
- Conditional plan,applyordestroyactions based on CI mode
- Slack notifications for deployment status
This modular design ensures targeted, environment-specific deployments to Azure.
Purpose
- Isolate processing for each changed main.tffile
- Automate complete Terraform lifecycle (format, validate, plan, apply/destroy)
- Integrate security and cost checks into the deployment pipeline
- Support multiple environments with isolated state management
- Provide deployment notifications via Slack integration
Workflow Jobs
(1) Trigger Conditions
| Aspect | Description | 
| WHAT | Reusable workflow triggered via workflow_callfrom the detect workflow | 
| HOW | Receives tfvars_fileinput parameter and inherits secrets from calling repository | 
| WHY | Enables modular, isolated processing of individual infrastructure files | 
| RESULT | Complete Terraform validation and deployment pipeline for a single file | 
(2) Azure Login with OIDC
| Aspect | Description | 
| WHAT | Authenticates to Azure using OpenID Connect without storing static credentials | 
| HOW | Uses azure/login@v1with client-id, tenant-id, and subscription-id from secrets | 
| WHY | Provides secure, credential-less authentication to Azure services | 
| RESULT | Authenticated session for Azure operations throughout the workflow | 
(3) Checkout Repository
| Aspect | Description | 
| WHAT | Downloads repository code with complete git history | 
| HOW | Uses actions/checkout@v4withfetch-depth: 0andref: ${{ github.ref }} | 
| WHY | Provides access to Terraform files and modules for processing | 
| RESULT | Full repository context available for Terraform operations | 
(4) Calculate Working File and Directory
| Aspect | Description | 
| WHAT | Determines file paths and working directory for the target main.tffile | 
| HOW | Uses custom action calculate-filewithtfvars_fileinput parameter | 
| WHY | Establishes context for subsequent Terraform operations | 
| RESULT | Outputs file_name,file_path, anddirfor use in following steps | 
(5) Read CI Mode
| Aspect | Description | 
| WHAT | Determines deployment mode (plan, apply, destroy) from configuration | 
| HOW | Uses custom action read-ci-modeto parse mode from directory context | 
| WHY | Enables conditional execution of apply/destroy steps based on intended operation | 
| RESULT | Sets ci_modeoutput for controlling downstream deployment actions | 
Each main.tf has a ci_mode block that is read by the workflow and used later to execute different actions based on plan, apply, ordestroy.
# Uncomment for CI/CD pipeline control
# ci_mode = "apply"
# --------------------------------
| Aspect | Description | 
| WHAT | Configures Git authentication for accessing private Terraform modules | 
| HOW | Uses custom action with AZURE_DEPLOY_TO_MODULE_ROtoken for GitHub access | 
| WHY | Enables Terraform to download private modules during initialization | 
| RESULT | Git configured for secure access to private module repositories | 
| Aspect | Description | 
| WHAT | Caches Terraform provider binaries to improve execution speed | 
| HOW | Uses custom action cache-terraform-providersto store/retrieve provider downloads | 
| WHY | Reduces workflow execution time by avoiding repeated provider downloads | 
| RESULT | Faster Terraform initialization and reduced network usage | 
| Aspect | Description | 
| WHAT | Installs Terraform CLI in the workflow environment | 
| HOW | Uses HashiCorp's official setup-terraform@v3action | 
| WHY | Provides Terraform binary required for all subsequent operations | 
| RESULT | Terraform CLI available for format, validate, plan, apply operations | 
(9) Ensure TF Lockfile Exists
| Aspect | Description | 
| WHAT | Ensures Terraform lockfile exists for provider version consistency | 
| HOW | Uses custom action ensure-tf-lockfile-existswith target directory | 
| WHY | Guarantees consistent provider versions across all workflow runs | 
| RESULT | Provider versions locked for reproducible infrastructure deployments | 
| Aspect | Description | 
| WHAT | Extracts key configuration values from the target Terraform file | 
| HOW | Uses custom action extract-tfvarsto parseapp_name,env,locationvariables | 
| WHY | Provides configuration context for backend setup and resource naming | 
| RESULT | Configuration variables available for subsequent workflow steps | 
| Aspect | Description | 
| WHAT | Generates Terraform backend configuration for remote state storage | 
| HOW | Uses custom action with Azure Blob Storage settings and extracted variables | 
| WHY | Ensures isolated state management per environment/application | 
| RESULT | Backend configuration enabling shared state storage in Azure | 
| Aspect | Description | 
| WHAT | Enforces consistent Terraform code formatting standards | 
| HOW | Uses custom action terraform-fmtto runterraform fmton target directory | 
| WHY | Maintains code quality and consistency across infrastructure definitions | 
| RESULT | Formatted Terraform code meeting established style guidelines | 
(13) Run TFLint
| Aspect | Description | 
| WHAT | Performs static analysis and linting of Terraform code | 
| HOW | Uses custom action tflintto analyze code for best practices and errors | 
| WHY | Identifies potential issues and enforces Terraform best practices | 
| RESULT | Code quality validation with early detection of configuration problems | 
| Aspect | Description | 
| WHAT | Validates Terraform configuration syntax and internal consistency | 
| HOW | Uses custom action terraform-validatewith GitHub token for module access | 
| WHY | Ensures configuration is syntactically correct and logically consistent | 
| RESULT | Verified Terraform configuration ready for planning | 
| Aspect | Description | 
| WHAT | Generates execution plan showing proposed infrastructure changes | 
| HOW | Uses custom action terraform-planto create detailed change preview | 
| WHY | Provides visibility into proposed changes before applying them | 
| RESULT | Execution plan available for review and subsequent apply operations | 
(16) Run Checkov Security Scan
| Aspect | Description | 
| WHAT | Performs security analysis to detect misconfigurations and vulnerabilities | 
| HOW | Uses custom action checkov-security-scanto scan infrastructure code | 
| WHY | Identifies security risks before infrastructure deployment | 
| RESULT | Security validation ensuring compliance with best practices | 
| Aspect | Description | 
| WHAT | Estimates monthly costs of planned infrastructure changes | 
| HOW | Uses custom action terraform-cost-estimatewith Infracost API integration | 
| WHY | Provides cost visibility before deploying infrastructure changes | 
| RESULT | Cost analysis helping with budget planning and cost optimization | 
| Aspect | Description | 
| WHAT | Applies Terraform changes to Azure infrastructure when CI mode is 'apply' | 
| HOW | Uses custom action terraform-applyconditionally based onci_modeoutput | 
| WHY | Enables controlled deployment of infrastructure changes | 
| RESULT | Infrastructure deployed to Azure according to Terraform configuration | 
| Aspect | Description | 
| WHAT | Destroys Terraform-managed infrastructure when CI mode is 'destroy' | 
| HOW | Uses custom action terraform-destroyconditionally based onci_modeoutput | 
| WHY | Enables controlled teardown of infrastructure for cleanup or testing | 
| RESULT | Infrastructure removed from Azure as specified by Terraform state | 
(20) Slack Notifications
| Aspect | Description | 
| WHAT | Sends deployment status notifications to Slack channels | 
| HOW | Uses custom action slack-notifyfor success, failure, and cancelled states | 
| WHY | Provides real-time visibility into deployment status for team awareness | 
| RESULT | Team notifications with deployment context and status information | 
Concurrency Control
| Aspect | Description | 
| WHAT | Concurrency managed by calling workflow, not at reusable workflow level | 
| HOW | Each matrix job processes different files, avoiding conflicts between parallel executions | 
| WHY | Prevents deadlocks between parent (caller) and child (reusable) workflow concurrency groups | 
| RESULT | Safe parallel processing with concurrency control handled upstream | 
Security Considerations
- OIDC Authentication: Secure, credential-less authentication to Azure using OpenID Connect
- Scoped Secrets: Only required secrets passed from calling repository via secrets: inherit
- Private Module Access: AZURE_DEPLOY_TO_MODULE_ROtoken scoped for module repository access
- State Isolation: Backend configuration ensures environment-specific state separation
- Cross-Repository Actions: All actions referenced from centralized .githubrepository with full paths
Key Components
| Component | Description | 
| calculate-file | Determines file paths and working directory context | 
| read-ci-mode | Parses deployment mode (plan/apply/destroy) from configuration | 
| configure-git-private-modules | Configures Git authentication for private Terraform modules | 
| cache-terraform-providers | Caches Terraform provider binaries for performance | 
| ensure-tf-lockfile-exists | Ensures provider lockfile exists for version consistency | 
| extract-tfvars | Extracts configuration variables from Terraform files | 
| create-terraform-backend-config-file | Generates backend config for Azure Blob Storage state | 
| terraform-fmt | Enforces Terraform code formatting standards | 
| tflint | Performs static analysis and linting | 
| terraform-validate | Validates Terraform syntax and configuration | 
| terraform-plan | Generates execution plan for infrastructure changes | 
| checkov-security-scan | Runs security analysis using Checkov | 
| terraform-cost-estimate | Estimates costs using Infracost integration | 
| terraform-apply | Applies infrastructure changes to Azure | 
| terraform-destroy | Destroys Terraform-managed infrastructure | 
| slack-notify | Sends deployment notifications to Slack channels |