Module 5

Infrastructure as Code

Automate everything with CloudFormation templates and Terraform modules. Compare IaC approaches.

CloudFormationTerraformState Management

What You'll Learn

You've deployed everything manually and with CloudFormation. Now let's compare the two major IaC approaches and learn Terraform โ€” the multi-cloud standard.

AzureAWSNotes
ARM TemplatesCloudFormationCloudFormation is the AWS-native IaC
BicepCloudFormationBicep is ARM's friendly syntax; CF uses YAML/JSON
Terraform (azurerm)Terraform (aws)Same tool, different provider

CloudFormation vs Terraform

FeatureCloudFormationTerraform
ProviderAWS onlyMulti-cloud
LanguageYAML / JSONHCL
StateManaged by AWSSelf-managed (S3)
PreviewChange Setsterraform plan
RollbackAutomaticManual
ModulesNested StacksFirst-class modules
๐Ÿ“˜ Key Concept

When to use which? CloudFormation for pure AWS shops needing auto-rollback. Terraform for multi-cloud, better module ecosystem, and team collaboration via Terraform Cloud.


Terraform Basics

Project Structure

text
terraform/
โ”œโ”€โ”€ main.tf          # Root module โ€” wires everything together
โ”œโ”€โ”€ variables.tf     # Input variables
โ”œโ”€โ”€ outputs.tf       # Output values
โ”œโ”€โ”€ providers.tf     # AWS provider config
โ”œโ”€โ”€ backend.tf       # Remote state (S3 + DynamoDB)
โ””โ”€โ”€ modules/
    โ”œโ”€โ”€ vpc/         # Networking module
    โ”œโ”€โ”€ rds/         # Database module
    โ”œโ”€โ”€ alb/         # Load balancer module
    โ”œโ”€โ”€ asg/         # Auto scaling module
    โ””โ”€โ”€ cicd/        # Pipeline module

The Terraform Workflow

  1. terraform init โ€” Download providers and initialize backend
  2. terraform plan โ€” Preview what will change (like a CF Change Set)
  3. terraform apply โ€” Create/update the resources
  4. terraform destroy โ€” Delete everything

Example: VPC Module in Terraform

Compare this to the CloudFormation YAML you've already seen:

hclmodules/vpc/main.tf
resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "${var.project_name}-vpc"
  }
}

resource "aws_subnet" "public" {
  count                   = 2
  vpc_id                  = aws_vpc.main.id
  cidr_block              = cidrsubnet(var.vpc_cidr, 8, count.index + 1)
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  map_public_ip_on_launch = true
}

resource "aws_subnet" "private" {
  count             = 2
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet(var.vpc_cidr, 8, count.index + 10)
  availability_zone = data.aws_availability_zones.available.names[count.index]
}
โ˜๏ธ Azure Parallel

If you've used provider "azurerm" in Terraform, the AWS provider follows the exact same patterns. The main difference is AWS doesn't have a Resource Group concept โ€” you use tags instead.


State Management

CloudFormation manages state automatically. With Terraform, you must manage it:

hclbackend.tf
terraform {
  backend "s3" {
    bucket         = "aws-sandbox-tf-state-ACCOUNT_ID"
    key            = "aws-sandbox/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "aws-sandbox-tf-lock"  # Prevents concurrent modifications
    encrypt        = true
  }
}
โš ๏ธ Warning

Never commit terraform.tfstate to git! It often contains sensitive data (passwords, keys). Always use remote state (S3) for team projects.


๐Ÿงช

Hands-On: Deploy with Terraform

bash
cd terraform

# Initialize
terraform init

# Preview all resources that will be created
terraform plan

# Apply โ€” creates everything in ~15 minutes
terraform apply

# View what was created
terraform state list
terraform output

# Destroy when done
terraform destroy

Key Takeaways

  • CloudFormation = AWS-native, auto-rollback, no state management needed
  • Terraform = multi-cloud, better module system, plan command is superior
  • Terraform state must be stored remotely (S3 + DynamoDB) for team use
  • Both are valid choices โ€” pick based on your organization's needs