Back to Blog
December 202315 min read

Infrastructure as Code with Terraform

TerraformIaCCloud

Introduction

Infrastructure as Code (IaC) with Terraform has become the standard for managing cloud infrastructure. This guide covers essential concepts, best practices, and real-world examples for managing your infrastructure effectively.

Project Structure

1. Directory Organization

project/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── terraform.tfvars
│   └── prod/
│       ├── main.tf
│       ├── variables.tf
│       └── terraform.tfvars
├── modules/
│   ├── vpc/
│   ├── ec2/
│   └── rds/
└── shared/
    └── provider.tf

Module Development

1. VPC Module Example

# modules/vpc/main.tf
module "vpc" {
  source = "terraform-aws-modules/vpc/aws"
  
  name = var.vpc_name
  cidr = var.vpc_cidr
  
  azs             = var.availability_zones
  private_subnets = var.private_subnet_cidrs
  public_subnets  = var.public_subnet_cidrs
  
  enable_nat_gateway = true
  single_nat_gateway = var.environment != "prod"
  
  tags = {
    Environment = var.environment
    Terraform   = "true"
  }
}

2. Variables Structure

# modules/vpc/variables.tf
variable "vpc_name" {
  description = "Name of the VPC"
  type        = string
}

variable "vpc_cidr" {
  description = "CIDR block for VPC"
  type        = string
  default     = "10.0.0.0/16"
}

variable "environment" {
  description = "Environment name"
  type        = string
}

State Management

1. Remote State Configuration

terraform {
  backend "s3" {
    bucket         = "terraform-state-bucket"
    key            = "environment/terraform.tfstate"
    region         = "us-west-2"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

2. State Locking

resource "aws_dynamodb_table" "terraform_locks" {
  name         = "terraform-locks"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}

Resource Management

1. EC2 Instance with Auto Scaling

module "asg" {
  source = "terraform-aws-modules/autoscaling/aws"

  name = "web-asg"

  min_size                  = 2
  max_size                  = 4
  desired_capacity          = 2
  health_check_type        = "EC2"
  health_check_grace_period = 300

  vpc_zone_identifier = module.vpc.private_subnets
  target_group_arns   = [aws_lb_target_group.web.arn]
  
  launch_template_name        = "web-lt"
  launch_template_description = "Web server launch template"
  update_default_version      = true

  image_id          = data.aws_ami.amazon_linux_2.id
  instance_type     = "t3.micro"
  ebs_optimized     = true
  enable_monitoring = true
}

Security Best Practices

1. IAM Policies

resource "aws_iam_role" "ec2_role" {
  name = "ec2_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      }
    ]
  })
}

2. Security Groups

resource "aws_security_group" "web" {
  name        = "web-sg"
  description = "Security group for web servers"
  vpc_id      = module.vpc.vpc_id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Automation and CI/CD

1. GitHub Actions Workflow

name: Terraform CI/CD

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    
    - name: Setup Terraform
      uses: hashicorp/setup-terraform@v1
    
    - name: Terraform Init
      run: terraform init
    
    - name: Terraform Plan
      run: terraform plan
    
    - name: Terraform Apply
      if: github.ref == 'refs/heads/main'
      run: terraform apply -auto-approve

Best Practices Checklist

  • Use consistent naming conventions
  • Implement proper state management
  • Version control your Terraform code
  • Use data sources when possible
  • Implement proper tagging strategy
  • Use workspaces for environment isolation

Conclusion

Implementing Infrastructure as Code with Terraform provides a robust and maintainable way to manage cloud resources. Following these best practices ensures scalable and reliable infrastructure deployment across your organization.

Author

Sandeep Choudhary

DevOps Engineer with expertise in AWS, Kubernetes, and cloud infrastructure.