Intermediate

Infrastructure as Code

Deploy and manage AWS infrastructure using CloudFormation or Terraform

Project Overview

Define your entire infrastructure in code, enabling version control, reproducibility, and automated deployments. A critical skill for any cloud architect.

Difficulty: Intermediate
AWS Services: CloudFormation, CDK, S3, IAM
Cost: Free (CloudFormation is free, you pay for resources)

Prerequisites

  • Familiarity with AWS services (VPC, EC2, etc.)
  • YAML or JSON knowledge
  • AWS CLI installed and configured
  • Basic programming knowledge for CDK (optional)

Choose Your Tool

📜
CloudFormation
AWS Native
🌏
Terraform
Multi-Cloud
💻
CDK
Code-First
📝
Template
YAML/HCL
Deploy
Stack/Apply
AWS Resources
VPC, EC2, RDS...

Version control your infrastructure like application code

Step-by-Step Instructions

1

Start with a Simple Template

  • Create a template that deploys a single S3 bucket
  • Define the AWSTemplateFormatVersion and Description
  • Add a Resources section with your S3 bucket
  • Deploy using AWS Console or CLI
  • Verify the resource was created
2

Add Parameters and Outputs

  • Add Parameters section for customizable values
  • Use parameter types (String, Number, AWS::SSM::Parameter::Value)
  • Define Outputs to expose resource IDs and ARNs
  • Export outputs for cross-stack references
3

Build a VPC Template

  • Define VPC with CIDR block
  • Create public and private subnets
  • Add Internet Gateway and NAT Gateway
  • Configure route tables
  • Use intrinsic functions: !Ref, !Sub, !GetAtt
4

Add Compute and Database Resources

  • Add EC2 instances or Lambda functions
  • Define security groups with proper ingress/egress
  • Add RDS or DynamoDB resources
  • Use DependsOn for resource ordering
  • Add Conditions for environment-specific resources
5

Implement Nested Stacks or Modules

  • Break large templates into nested stacks
  • Store child templates in S3
  • Pass parameters between stacks
  • Import outputs from other stacks
  • Create reusable modules for common patterns
6

Set Up CI/CD for Infrastructure

  • Store templates in Git repository
  • Use CloudFormation change sets for previewing changes
  • Create a CodePipeline for automated deployments
  • Add testing and validation stages
  • Implement drift detection

Tips

  • Use nested stacks/modules for reusability - Create reusable components for common patterns
  • Store state remotely (Terraform) - Use S3 + DynamoDB for team collaboration
  • Always use change sets - Preview changes before applying to avoid surprises
  • Enable termination protection - Prevent accidental deletion of production stacks

Code Examples

CloudFormation VPC Template

vpc-template.yaml YAML
AWSTemplateFormatVersion: '2010-09-09'
Description: VPC with public and private subnets

Parameters:
  VpcCidr:
    Type: String
    Default: 10.0.0.0/16

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-vpc

  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Select [0, !Cidr [!Ref VpcCidr, 4, 8]]
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true

  PrivateSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Select [1, !Cidr [!Ref VpcCidr, 4, 8]]
      AvailabilityZone: !Select [0, !GetAZs '']

  InternetGateway:
    Type: AWS::EC2::InternetGateway

  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

Outputs:
  VpcId:
    Value: !Ref VPC
    Export:
      Name: !Sub ${AWS::StackName}-VpcId

Terraform AWS Configuration

main.tf HCL
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "vpc/terraform.tfstate"
    region = "us-east-1"
  }
}

provider "aws" {
  region = var.aws_region
}

resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true

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

resource "aws_subnet" "public" {
  count             = length(var.availability_zones)
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet(var.vpc_cidr, 4, count.index)
  availability_zone = var.availability_zones[count.index]

  tags = {
    Name = "${var.project_name}-public-${count.index + 1}"
  }
}

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

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

AWS CDK (TypeScript)

lib/vpc-stack.ts TYPESCRIPT
import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

export class VpcStack extends cdk.Stack {
  public readonly vpc: ec2.Vpc;

  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    this.vpc = new ec2.Vpc(this, 'MainVpc', {
      maxAzs: 2,
      subnetConfiguration: [
        {
          name: 'Public',
          subnetType: ec2.SubnetType.PUBLIC,
          cidrMask: 24,
        },
        {
          name: 'Private',
          subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
          cidrMask: 24,
        },
      ],
    });

    new cdk.CfnOutput(this, 'VpcId', {
      value: this.vpc.vpcId,
    });
  }
}

CLI Commands

Terminal Commands BASH
# CloudFormation
aws cloudformation deploy \
    --template-file vpc-template.yaml \
    --stack-name my-vpc-stack \
    --parameter-overrides VpcCidr=10.0.0.0/16

# View change set before applying
aws cloudformation create-change-set \
    --stack-name my-vpc-stack \
    --change-set-name my-changes \
    --template-body file://vpc-template.yaml

# Terraform
terraform init
terraform plan -out=tfplan
terraform apply tfplan

# CDK
cdk bootstrap
cdk diff
cdk deploy

What You'll Learn

  • Infrastructure as Code principles and benefits
  • CloudFormation template authoring and best practices
  • Stack management, updates, and rollbacks
  • Cross-stack references and nested stacks
  • Drift detection and remediation