← Back to AWS Mastery
Advanced15 min read

Infrastructure as Code

Manage AWS infrastructure declaratively with CloudFormation, Terraform, and AWS CDK — version control, reproducibility, and automated provisioning.

Infrastructure as Code Principles

IaC defines infrastructure in code files rather than manual console clicks. Benefits: version control, reproducibility, peer review, automated testing, and disaster recovery. The same templates deploy identical environments.

Treat infrastructure code like application code: code review, CI/CD pipelines, testing, and documentation.

  • Never modify production infrastructure manually
  • Store IaC in git alongside application code
  • Use separate state/stacks per environment
# IaC workflow
# 1. Write infrastructure definition (YAML/HCL/TypeScript)
# 2. Code review via pull request
# 3. CI validates template (lint, security scan)
# 4. Deploy to staging automatically
# 5. Manual approval for production
# 6. Deploy to production
# 7. Drift detection monitors changes

AWS CloudFormation

CloudFormation is AWS native IaC service. Define resources in YAML or JSON templates. Stacks are deployed instances of templates. CloudFormation handles dependency ordering, rollback on failure, and drift detection.

Use nested stacks for modular templates. StackSets deploy across accounts and regions. Change sets preview modifications before applying.

AWSTemplateFormatVersion: '2010-09-09'
Description: Web application stack

Resources:
  WebBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub '${AWS::StackName}-assets'
      VersioningConfiguration:
        Status: Enabled

Outputs:
  BucketUrl:
    Value: !GetAtt WebBucket.WebsiteURL
    Export:
      Name: !Sub '${AWS::StackName}-BucketUrl'

Terraform

Terraform by HashiCorp is cloud-agnostic IaC using HCL syntax. The AWS provider covers all AWS services. State files track deployed resources. Plan/apply workflow previews and executes changes.

Terraform excels at multi-cloud deployments and has a larger module ecosystem. Use remote state (S3 + DynamoDB locking) for team collaboration.

resource "aws_s3_bucket" "assets" {
  bucket = "${var.project}-assets"
}

resource "aws_s3_bucket_versioning" "assets" {
  bucket = aws_s3_bucket.assets.id
  versioning_configuration {
    status = "Enabled"
  }
}

output "bucket_url" {
  value = aws_s3_bucket.assets.bucket_regional_domain_name
}

AWS CDK

Cloud Development Kit (CDK) defines infrastructure in programming languages — TypeScript, Python, Java, C#, Go. CDK synthesizes to CloudFormation templates. Higher-level constructs simplify common patterns.

CDK appeals to developers who prefer code over YAML. L3 constructs (patterns) deploy entire architectures — a Lambda API with one construct call.

import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'MyStack');

new s3.Bucket(stack, 'AssetsBucket', {
  versioned: true,
  encryption: s3.BucketEncryption.S3_MANAGED,
  blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
});

app.synth();

Comparing IaC Tools

CloudFormation: AWS-native, no additional tooling, deep AWS integration. Terraform: multi-cloud, large community, HCL syntax. CDK: programming languages, high-level abstractions, generates CloudFormation.

Many teams use CDK or Terraform for daily work and CloudFormation indirectly. Choose based on team skills and multi-cloud requirements.

  • CDK synthesizes to CloudFormation — use cdk deploy
  • Terraform state is critical — back up and lock remote state
  • Use cfn-lint and tflint for template validation in CI
# Tool selection guide
# CloudFormation: AWS-only, YAML/JSON, no extra tools
# Terraform: multi-cloud, HCL, largest module registry
# CDK: TypeScript/Python, developer-friendly, AWS-focused
# SAM: serverless-focused, extends CloudFormation
# Pulumi: general-purpose languages, multi-cloud

IaC Best Practices

Modularize templates by service or feature. Parameterize environment differences. Use consistent tagging strategies. Implement policy as code with cfn-guard or Sentinel. Test templates with taskcat or terratest.

Enable drift detection to catch manual console changes. Import existing resources into IaC management rather than recreating them.

# CI pipeline for IaC
# 1. cfn-lint template.yaml (CloudFormation)
# 2. tflint (Terraform)
# 3. cdk synth && diff against deployed stack
# 4. cfn-guard / checkov security scan
# 5. Deploy to staging on merge
# 6. Manual approval → deploy production

Get In Touch


Ready to discuss your next project? Drop me a message.