Meet the New GitHub AT-AT: Automate the Automation with Terraform, GitHub Edition
Welcome to the GitHub AT-AT (Automate the Automation with Terraform), an innovative Terraform module library that combines the power of GitHub Actions, Azure, and Terraform to streamline the process of building and managing cloud-based application environments. The GitHub AT-AT simplifies the creation of end-to-end infrastructure-as-code (IaC) pipelines, enabling you to automate the automation and establish a fully operational CI/CD pipeline tailored to your application workloads.
The GitHub AT-AT module library isn’t just a single module — it’s a composition of several independent Terraform modules, each addressing a specific aspect of infrastructure automation. Together, these modules provide a seamless solution to orchestrate the interactions between Entra ID, Azure, and GitHub, creating a highly integrated and secure deployment environment. Let’s dive into the architecture and step-by-step workings of this system.
The Architecture of the GitHub AT-AT
GitHub AT-AT Architecture
At the heart of the GitHub AT-AT lies its modular architecture, which combines smaller, purpose-built modules to create a cohesive system. These modules operate independently, meaning you can use specific components as needed or deploy the entire system to fully automate your Azure application environments.
The core module, terraform-github-atat-application-environment, is composed of submodules that collectively handle the setup of your application workload. These include:
- terraform-github-azure-credential: Adds Azure authentication context to GitHub environments.
- terraform-github-azure-backend: Configures Azure backend storage for Terraform state.
- terraform-github-codebase-terraform-azure-application: Sets up the codebase that provisions a placeholder Azure Resource Group during the initial run.
These modules integrate with others that configure GitHub Actions workflows. For example, the terraform-github-action-azure-login-test module validates Azure OpenID Connect (OIDC) authentication, while terraform-github-action-azure-application deploys workflows for Terraform Plan, Apply, and Destroy operations, offering manual and automated triggers tied to your GitFlow branching strategy.
GitHub AT-AT Module Structure
Here is the hierarchy of the GitHub AT-AT Module Library. Each of these modules can be used independently which allows you to use part or all of the GitHub AT-AT for your own creations.
- atat
- terraform-backend (Azure)
- github-credential (Entra ID)
- application-environment (GitHub)
- Repository
- codebase-terraform-azure-application
- Environment
- azure-credential
- azure-backend
- Actions
- azure-login-test
- azure-application
Step 1: Creating Azure Backends for Terraform State
The first step is to establish Azure Storage Accounts to serve as the Terraform state backend for each environment. Each storage account is isolated by Azure RBAC, ensuring that environments like DEV and PROD remain securely separated. For instance, a terraform-github-azure-backend module creates containers for both Terraform state files and temporary Terraform Plan files. This design facilitates a manual approver workflow, allowing plans to be reviewed before being applied.
In the Terraform configuration, a separate backend module is instantiated for each environment. For example, the DEV environment might use:
module "backend_dev" {
providers = {
azurerm = azurerm.dev
}
source = "Azure-Terraformer/terraform-backend/azurerm"
version = "1.0.2"
location = "westus3"
}
This approach not only promotes security but also aligns with best practices for environment isolation.
We create two containers. One for storing Terraform State and another that is used by the GitHub Actions Workflows to save temporary Terraform Plan files. This will facilitate a manual approvers workflow.
Step 2: Provisioning Entra ID Identities and Federating with GitHub
Each environment requires a dedicated Service Principal, which manages deployments using a least-privilege model. These Service Principals are tied to Azure subscriptions through role assignments, granting appropriate permissions such as Contributor or custom roles.
The terraform-github-azure-credential module provisions the Application, Service Principal, associating them with their respective Azure environments. Additionally, the module sets up Federated Identity Credentials, enabling GitHub Actions to authenticate seamlessly using OIDC tokens.
For instance, the configuration for federating an Entra ID application looks like this:
module "github_identity" {
source = "Azure-Terraformer/github-credential/azuread"
version = "1.0.8"
for_each = var.environments
github_organization = var.github_organization
repository_name = var.repository_name
entity_type = "environment"
environment_name = each.key
owners = [data.azuread_client_config.current.object_id]
}
By setting up federation for each environment, you ensure that DEV and PROD workloads remain isolated and independently manageable.
That permission could be Contributor or Owner or a custom Role Definition. This is an area that I’d like to improve and make more customizable in the future.
Step 3: Establishing the Codebase and Workflows
The terraform-github-codebase-terraform-azure-application module is pivotal to the GitHub AT-AT. It serves as the foundation for your automated deployment pipeline by initializing your application codebase and deploying a series of robust GitHub Actions workflows that drive Terraform operations across multiple environments. These workflows are designed to align with your branching strategy and enforce best practices in infrastructure-as-code (IaC) automation.
The Three GitHub Actions Workflow Categories
The GitHub AT-AT module deploys three distinct types of workflows, each serving a critical role in the automation process:
- Manually Triggered Workflows for Terraform Core Operations
These workflows provide manual control over the three core Terraform operations: Plan, Apply, and Destroy. By manually triggering these workflows, you can precisely dictate when infrastructure changes are planned, applied, or torn down. For example, you might want to trigger a Terraform Plan to preview changes before a major update, or a Terraform Destroy to clean up resources after a testing phase. This manual flexibility ensures that your team retains control over critical operations, enabling you to make changes with confidence.
- Pull Request Workflows for Change Previews
Pull Request workflows are designed to run a Terraform Plan for each environment whenever your team submits a pull request. This feature offers a preview of the proposed changes, allowing your team to understand the impact of their code modifications on the environment. For example, when a developer submits a PR to the DEV branch, the associated workflow runs a Terraform Plan specifically for the DEV environment. The results of the plan are displayed directly within the GitHub interface, providing visibility into what changes will be made if the PR is approved and merged.
- Push (or Merge) Workflows for Automated Deployments
Push workflows are triggered whenever code is pushed to or merged into specific branches, typically aligned with your environments. For example, the DEV environment may be associated with the develop branch, while the PROD environment may correspond to the main branch. These workflows automate Terraform operations such as Apply and Destroy, streamlining deployments and reducing manual intervention.
A Deeper Look at the Push Workflow: Multi-Stage Deployment with Approvals
The push workflow is a standout feature due to its multi-stage design, leveraging Azure Blob Storage to securely manage Terraform plans between stages. Here’s how it works:
- Stage 1: Terraform Plan
When a push event occurs (e.g., merging a PR into the main branch for the PROD environment), the workflow generates a Terraform Plan. This plan is saved as a .tfplan file in an Azure Blob Storage container. The plan file is uniquely named using the GitHub Run ID, ensuring traceability and preventing conflicts between workflow runs.
- Stage 2: Approval and Review
Once the plan is stored, it can be reviewed by a designated approver. This stage introduces a manual checkpoint, allowing a human with the necessary authority to examine the proposed changes before they are applied. This process enhances security and governance, ensuring that only approved changes make it into the environment.
- Stage 3: Terraform Apply
After approval, the workflow proceeds to the Terraform Apply stage. It retrieves the stored .tfplan file from Azure Blob Storage and applies the changes to the target environment. By correlating the plan file with the GitHub Run ID, the system ensures consistency between the reviewed plan and the applied changes.
This multi-stage approach not only promotes best practices for deployment governance but also provides flexibility in managing workflows across environments.
Configuring Environments and Branches
The GitHub AT-AT workflows are tightly integrated with your branching strategy. Each environment is associated with a specific branch, creating a clear separation between development and production workflows. For example: The DEV environment is linked to the develop branch, enabling continuous integration for development changes. The PROD environment is linked to the main branch, ensuring stability and governance for production deployments. By aligning workflows with GitFlow or similar branching strategies, the GitHub AT-AT module simplifies the management of infrastructure changes across multiple environments.
Demonstrating the Workflow in Action
When a developer submits a pull request to the develop branch, the Pull Request workflow runs a Terraform Plan for the DEV environment. The team can review the changes in GitHub before merging the PR. After approval, merging the PR triggers the push workflow, which executes the Terraform Apply and updates the DEV environment.
Similarly, changes to the main branch trigger the PROD workflow. Before applying changes, the system saves the plan to Azure Blob Storage, allowing a production approver to review it. Once approved, the workflow retrieves the plan and applies the changes, ensuring a controlled and predictable update to the production environment.
Step 4: Running the Automation
Once all modules are instantiated, the GitHub AT-AT module is configured to tie everything together. For example:
module "application_environment" {
source = "Azure-Terraformer/atat-application-environment/github"
version = "1.0.1"
providers = {
azurerm.dev = azurerm.dev
azurerm.prod = azurerm.prod
}
github_organization = var.github_organization
repository_name = "atat-demo"
commit_user = {
name = "YOU"
email = "you@me.com"
}
environments = {
dev = {
subscription_id = "00000000-0000-0000-0000-000000000000"
branch_name = "develop"
}
prod = {
subscription_id = "00000000-0000-0000-0000-000000000000"
branch_name = "main"
}
}
}
When executed, the module provisions all necessary infrastructure and workflows. From initializing Terraform state backends to configuring OIDC authentication, the GitHub AT-AT automates every aspect of your CI/CD pipeline.
Step 5: Applying GitFlow and Managing Environments
The GitHub AT-AT module integrates seamlessly with the GitFlow branching strategy, enabling you to manage infrastructure changes across environments such as DEV and PROD with precision and control. By associating specific branches with environments — such as mapping the DEV environment to the develop branch and the PROD environment to the main branch—the module ensures that development and production workloads remain isolated yet interconnected through a streamlined CI/CD pipeline.
- Developer Creates a Pull Request The workflow begins when a developer submits a pull request (PR) to the develop branch. This action triggers the Pull Request workflow for the DEV environment. The workflow runs a Terraform Plan, generating a detailed preview of the changes that the proposed code modifications will make to the infrastructure.
At this stage, the developer can review the results of the Terraform Plan directly in the GitHub interface. The plan output provides critical insights, such as which resources will be added, modified, or destroyed. This step ensures transparency and enables the developer to verify that their code changes align with expectations before proceeding further.
- Developer Reviews and Approves the Pull Request
Once the Terraform Plan output is reviewed and validated, the developer — or an authorized reviewer — approves the pull request. Approval signals that the proposed changes are ready to be merged into the main branch for the PROD environment.
After approval, the PR is merged into the main branch. This merge not only updates the codebase but also triggers the Push/Merge workflow for the PROD environment. This automated process ensures that changes are continuously integrated and tested in the development stage.
- Push/Merge Workflow Executes Multi-Stage Apply Upon merging the pull request, the Push/Merge workflow begins executing. This workflow is designed as a multi-stage process to ensure secure, predictable, and governed infrastructure updates.
Here’s a breakdown of the stages:
- Stage 1: Terraform Plan
The workflow generates a new Terraform Plan based on the merged changes. This plan is saved as a .tfplan file in Azure Blob Storage, uniquely identified by the GitHub Run ID. Saving the plan in a centralized storage location ensures that it can be reviewed and retrieved for subsequent stages.
terraform plan -out=$.tfplan
- Stage 2: Manual Approval (Optional)
If the workflow is configured with a manual approval step, an authorized individual — such as a team lead or environment owner — can review the stored plan. This step introduces a governance checkpoint, ensuring that only vetted changes proceed to the apply stage.
- Stage 3: Terraform Apply
After approval, the workflow retrieves the .tfplan file from Azure Blob Storage and executes the Terraform Apply operation. This action applies the changes to the target environment, provisioning, modifying, or destroying resources as specified in the plan. By correlating the plan with the GitHub Run ID, the workflow ensures that the exact reviewed plan is applied, eliminating any discrepancies.
terraform apply $.tfplan
Conclusion
The GitHub AT-AT module library represents a powerful approach to automating cloud application environments with Terraform. By combining modular components for Azure, Entra ID, and GitHub, it provides a secure, scalable, and flexible solution for managing CI/CD pipelines. Whether you’re provisioning infrastructure for DEV or PROD, this system ensures that your workflows adhere to best practices and enable robust governance.
With the GitHub AT-AT, you no longer need to spend hours configuring each piece of your automation. Instead, you can focus on building and scaling your application workloads, confident that your infrastructure is automated, efficient, and secure.