Terraform

Advanced

Infrastructure as Code for complete control

šŸ’µ Cost: Terraform itself is FREE and open source. However, the AWS resources it creates will incur charges. Always run terraform plan to review what will be created before terraform apply. Use terraform destroy to remove all resources and stop charges. See our Costs & Cleanup Guide.

What is Terraform?

Terraform is an Infrastructure as Code (IaC) tool that lets you define cloud resources in declarative configuration files. You describe what you want, and Terraform figures out how to create it.

Declarative vs Imperative

Instead of writing scripts that say do this, then do that, you declare I want a VPC with these subnets and Terraform handles the order of operations, dependencies, and updates.

Why Terraform?

  • Version Control: Track infrastructure changes in Git
  • Reproducibility: Create identical environments from same code
  • Multi-Cloud: Same language for AWS, GCP, Azure
  • State Management: Knows what exists, only changes whats needed
  • Plan Before Apply: Preview changes before making them

Installation

Terminal
$brew install terraform
==> terraform 1.7.0 installed

Project Structure

Plain Text
infra/terraform/
ā”œā”€ā”€ main.tf           # Provider configuration
ā”œā”€ā”€ variables.tf      # Input variables
ā”œā”€ā”€ outputs.tf        # Output values
ā”œā”€ā”€ vpc.tf            # VPC and networking
ā”œā”€ā”€ ecs.tf            # ECS cluster and service
ā”œā”€ā”€ alb.tf            # Load balancer
ā”œā”€ā”€ rds.tf            # Database
ā”œā”€ā”€ s3.tf             # S3 buckets
ā”œā”€ā”€ iam.tf            # IAM roles and policies
ā”œā”€ā”€ secrets.tf        # Secrets Manager
└── terraform.tfvars  # Variable values (git-ignored)

Provider Configuration

HCL
# main.tf
terraform {
  required_version = ">= 1.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }

  # Store state in S3 (recommended for teams)
  backend "s3" {
    bucket = "my-terraform-state-bucket"
    key    = "my-app/terraform.tfstate"
    region = "ap-southeast-1"
  }
}

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = {
      Project     = var.project_name
      Environment = var.environment
      ManagedBy   = "terraform"
    }
  }
}

Variables

HCL
# variables.tf
variable "aws_region" {
  description = "AWS region to deploy to"
  type        = string
  default     = "ap-southeast-1"
}

variable "project_name" {
  description = "Name of the project"
  type        = string
}

variable "environment" {
  description = "Environment (staging, production)"
  type        = string

  validation {
    condition     = contains(["staging", "production"], var.environment)
    error_message = "Environment must be staging or production."
  }
}

variable "container_image" {
  description = "Docker image URI"
  type        = string
}

variable "db_password" {
  description = "Database password"
  type        = string
  sensitive   = true
}

Outputs

HCL
# outputs.tf
output "alb_dns_name" {
  description = "DNS name of the load balancer"
  value       = aws_lb.main.dns_name
}

output "ecr_repository_url" {
  description = "URL of the ECR repository"
  value       = aws_ecr_repository.app.repository_url
}

output "rds_endpoint" {
  description = "RDS instance endpoint"
  value       = aws_db_instance.main.endpoint
  sensitive   = true
}

Best Practices

  • Use remote state with locking
  • Never hardcode secrets - use variables with sensitive flag
  • Use modules for reusable components
  • Run terraform fmt before commits
  • Review plans carefully before applying
  • Use workspaces or separate state files per environment
  • Tag all resources for cost tracking

Cost Control with Terraform

Always destroy unused infrastructure to avoid charges:

  • terraform destroy -var-file=staging.tfvars - Destroy staging environment
  • Review the plan output carefully - it shows exactly what will be deleted
  • Type yes only after confirming the resources listed are correct

Warning: Terraform destroy is irreversible. Ensure you have backups of any important data before destroying.

Learning Path

Start with Copilot to understand AWS ECS concepts, then graduate to Terraform when you need more control or multi-cloud deployments.

AWS Deployment Guide — Built with Next.js