Skip to content

Automate Terraform Deployments: (2/2) Process

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, apply or destroy actions 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.tf file
  • 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_call from the detect workflow
HOW Receives tfvars_file input 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@v1 with 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@v4 with fetch-depth: 0 and ref: ${{ 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.tf file
HOW Uses custom action calculate-file with tfvars_file input parameter
WHY Establishes context for subsequent Terraform operations
RESULT Outputs file_name, file_path, and dir for 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-mode to parse mode from directory context
WHY Enables conditional execution of apply/destroy steps based on intended operation
RESULT Sets ci_mode output 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"
# --------------------------------

(6) Configure Git for Private Modules

Aspect Description
WHAT Configures Git authentication for accessing private Terraform modules
HOW Uses custom action with AZURE_DEPLOY_TO_MODULE_RO token for GitHub access
WHY Enables Terraform to download private modules during initialization
RESULT Git configured for secure access to private module repositories

(7) Cache Terraform Providers

Aspect Description
WHAT Caches Terraform provider binaries to improve execution speed
HOW Uses custom action cache-terraform-providers to store/retrieve provider downloads
WHY Reduces workflow execution time by avoiding repeated provider downloads
RESULT Faster Terraform initialization and reduced network usage

(8) Set Up Terraform

Aspect Description
WHAT Installs Terraform CLI in the workflow environment
HOW Uses HashiCorp's official setup-terraform@v3 action
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-exists with target directory
WHY Guarantees consistent provider versions across all workflow runs
RESULT Provider versions locked for reproducible infrastructure deployments

(10) Extract tfvars Values

Aspect Description
WHAT Extracts key configuration values from the target Terraform file
HOW Uses custom action extract-tfvars to parse app_name, env, location variables
WHY Provides configuration context for backend setup and resource naming
RESULT Configuration variables available for subsequent workflow steps

(11) Create Terraform Backend Config File

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

(12) Terraform Format

Aspect Description
WHAT Enforces consistent Terraform code formatting standards
HOW Uses custom action terraform-fmt to run terraform fmt on 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 tflint to 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

(14) Terraform Validate

Aspect Description
WHAT Validates Terraform configuration syntax and internal consistency
HOW Uses custom action terraform-validate with GitHub token for module access
WHY Ensures configuration is syntactically correct and logically consistent
RESULT Verified Terraform configuration ready for planning

(15) Terraform Plan

Aspect Description
WHAT Generates execution plan showing proposed infrastructure changes
HOW Uses custom action terraform-plan to 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-scan to scan infrastructure code
WHY Identifies security risks before infrastructure deployment
RESULT Security validation ensuring compliance with best practices

(17) Terraform Cost Estimate (Infracost)

Aspect Description
WHAT Estimates monthly costs of planned infrastructure changes
HOW Uses custom action terraform-cost-estimate with Infracost API integration
WHY Provides cost visibility before deploying infrastructure changes
RESULT Cost analysis helping with budget planning and cost optimization

(18) Terraform Apply (Conditional)

Aspect Description
WHAT Applies Terraform changes to Azure infrastructure when CI mode is 'apply'
HOW Uses custom action terraform-apply conditionally based on ci_mode output
WHY Enables controlled deployment of infrastructure changes
RESULT Infrastructure deployed to Azure according to Terraform configuration

(19) Terraform Destroy (Conditional)

Aspect Description
WHAT Destroys Terraform-managed infrastructure when CI mode is 'destroy'
HOW Uses custom action terraform-destroy conditionally based on ci_mode output
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-notify for 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_RO token scoped for module repository access
  • State Isolation: Backend configuration ensures environment-specific state separation
  • Cross-Repository Actions: All actions referenced from centralized .github repository 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