8.4 Third-Party Automation with Terraform & Git Workflows
Key Takeaways
- HashiCorp Terraform provides declarative Infrastructure as Code using HCL across a core operational lifecycle: terraform init (backend and providers), terraform plan (dry run preview), terraform apply (provisioning), and terraform destroy (decommissioning).
- Remote state management stores terraform.tfstate in an Amazon S3 bucket (with versioning, SSE-KMS encryption, and private bucket policies) combined with an Amazon DynamoDB table (LockID partition key) to provide distributed state locking and prevent concurrent state corruption.
- State drift between deployed AWS infrastructure and the state file is identified and reconciled using terraform plan -refresh-only or terraform refresh, while terraform import adopts pre-existing unmanaged AWS resources into Terraform state.
- Infrastructure GitOps workflows utilize automated Pull Request pipelines executing terraform fmt -check, terraform validate, security linters, and speculative terraform plan checks before merging to protected main branches.
- Modern CI/CD pipelines authenticate to AWS using IAM OpenID Connect (OIDC) identity federation (sts:AssumeRoleWithWebIdentity), completely eliminating hardcoded, long-lived AWS IAM access keys and secret keys.
8.4 Third-Party Automation with Terraform & Git Workflows
CloudOps Blueprint Focus: While AWS CloudFormation provides native orchestration, modern enterprise environments heavily utilize third-party Infrastructure as Code (IaC) tools—predominantly HashiCorp Terraform. For the AWS Certified CloudOps Engineer – Associate (SOA-C03) exam, you must understand Terraform architecture on AWS, master remote state management and distributed state locking with Amazon S3 and DynamoDB, manage configuration drift, adopt existing cloud resources, and secure CI/CD deployment pipelines using IAM OpenID Connect (OIDC) federation.
Terraform Fundamentals in AWS CloudOps
HashiCorp Terraform enables cloud engineers to define infrastructure using HashiCorp Configuration Language (HCL)—a declarative language. Rather than executing procedural scripts, declarative IaC defines the target end state; Terraform builds an internal dependency graph and executes the precise AWS API calls required to reconcile live infrastructure against declared configurations.
An AWS Terraform implementation begins with provider configuration:
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
default_tags {
tags = {
Environment = "Production"
ManagedBy = "Terraform"
}
}
}
The default_tags block automatically attaches standardized organizational tags across all provisioned resources, enforcing tagging governance across the estate.
Core Terraform Operational Lifecycle Commands
The standard Terraform lifecycle follows four sequential CLI commands:
| Command | Operational Function | CloudOps Best Practices & Safety Controls |
|---|---|---|
terraform init | Initializes the working directory, sets up the remote backend, and downloads provider plugins into .terraform/. | Must re-run when provider versions or backends change. Use -upgrade to update plugins. |
terraform plan | Performs a dry run. Compares live AWS resources against HCL, outputting proposed additions (+), changes (~), and destructions (-). | In CI/CD pipelines, output plan artifacts using -out=tfplan to ensure reviewed changes match what is applied. |
terraform apply | Executes planned API calls against AWS and records resource metadata into the state file. | Use -auto-approve strictly in unattended CI/CD pipelines post-merge; never in manual sessions. |
terraform destroy | Deletes all infrastructure tracked in the state file. | Guard critical stateful resources (RDS, S3) with lifecycle { prevent_destroy = true }. |
Additional validation tools include terraform fmt -check (verifies canonical syntax and indentation in CI lint stages) and terraform validate (validates syntax and internal references without calling remote APIs).
Remote State Management & Distributed State Locking
Terraform records resource attributes in a state file (terraform.tfstate). In team environments, local state files are prohibited—they expose plain-text secrets and cause state divergence.
Amazon S3 and DynamoDB State Backend Architecture
The enterprise standard pairs Amazon S3 for remote storage with Amazon DynamoDB for distributed locking:
-
Amazon S3 Bucket Requirements:
- Versioning: Retains complete revision history of state files, enabling immediate recovery if corruption occurs.
- Encryption: Enforces SSE-KMS using a Customer Managed Key (CMK) to protect sensitive data stored in state.
- Bucket Policy: Blocks public access, mandates TLS encryption (
aws:SecureTransport), and restricts access to deployment IAM roles.
-
Amazon DynamoDB State Locking:
- Configured with a primary partition key named
LockID(String type). - During
terraform planorterraform apply, Terraform writes a lock item containing the transaction ID. If another runner attempts an execution concurrently, DynamoDB rejects the write, and Terraform halts with anError acquiring the state lockmessage, preventing concurrent state corruption. - Upon completion, Terraform deletes the lock item.
- Configured with a primary partition key named
terraform {
backend "s3" {
bucket = "corp-terraform-state-111122223333"
key = "prod/vpc/terraform.tfstate"
region = "us-east-1"
encrypt = true
kms_key_id = "arn:aws:kms:us-east-1:111122223333:key/abc-123"
dynamodb_table = "corp-terraform-state-locks"
}
}
Managing State Drift & Resource Importation
Reconciling Configuration Drift
State Drift occurs when infrastructure is modified out-of-band directly through the AWS Console or CLI. The modern, safe workflow uses terraform plan -refresh-only (or terraform apply -refresh-only). This queries live AWS APIs, identifies differences against state, and updates the state file to reflect reality without modifying or reverting cloud resources.
Adopting Unmanaged Infrastructure with Terraform Import
When adopting existing AWS resources into Terraform management without recreation, engineers use declarative import blocks:
import {
to = aws_security_group.app_sg
id = "sg-0123456789abcdef0"
}
Running terraform plan -generate-config-out=generated.tf automatically generates HCL configuration for the imported resource, binding it into state.
GitOps CI/CD Pipelines & Validation Workflows
In GitOps architectures, infrastructure repositories are structured by blast radius (e.g., separating networking, databases, and compute into isolated directories and state files). Automated CI/CD pipelines enforce quality gates:
- Pull Request Validation: Runs
terraform fmt -check, static security scanners (tfsec,checkov),terraform validate, andterraform plan -out=tfplan, posting speculative diffs to PR comments for peer review. - Main Branch Merge & Deployment: Merging to the protected
mainbranch triggers automated deployment, executingterraform apply -auto-approveagainst the reviewed plan.
Credential-Less CI/CD Authentication via IAM OIDC Federation
Storing static IAM user access keys in CI/CD secret stores creates credential leakage risks. The AWS standard uses IAM OpenID Connect (OIDC) Identity Federation:
- An IAM OIDC Identity Provider is registered in AWS trusting the CI/CD platform (e.g.,
token.actions.githubusercontent.com). - An IAM role is created with a trust policy allowing
sts:AssumeRoleWithWebIdentity, strictly conditioned on repository claims (token.actions.githubusercontent.com:submatchingrepo:my-org/infra:ref:refs/heads/main).
The CI/CD runner exchanges its short-lived OIDC JSON Web Token (JWT) with AWS STS to obtain temporary security credentials valid only for the pipeline run, eliminating persistent access keys entirely.
A platform engineering team uses HashiCorp Terraform to manage multi-account AWS infrastructure. As the engineering team grew, two engineers ran automated CI/CD deployment pipelines simultaneously, resulting in concurrent terraform apply operations against the same infrastructure environment. This race condition led to severe state file corruption. Which architecture must the CloudOps team implement to ensure distributed state locking, high availability, and durable state protection?
A security compliance officer identifies that an organization's CI/CD pipeline running in GitHub Actions authenticates to AWS using long-lived IAM user access keys and secret access keys stored as repository secrets. To eliminate the credential leakage risks associated with static credentials, the architect mandates that the pipeline must use short-lived, temporary credentials without storing any persistent AWS access keys in GitHub. Which operational architecture should the CloudOps engineer deploy?
An on-call engineer temporarily modified the inbound rules of an Amazon EC2 security group via the AWS Management Console to troubleshoot an urgent network connectivity issue. The CloudOps team needs to detect this configuration drift using Terraform and update the local state file so that it accurately matches the live AWS infrastructure, without modifying or reverting any live cloud resources. Which command should the engineer execute?