Hey cloud enthusiasts! In my last post, I walked you through the flow of our Jira clone deployment. Today, let's dive deep into the infrastructure and how we're managing it all with Terraform. Grab your coffee โ - we're about to get technical!
Why Terraform? The Infrastructure as Code Journey ๐ค
When I started this project, I had two options: manually click through the AWS console or use Infrastructure as Code (IaC). Here's why I chose Terraform:
- Version Control: Every infrastructure change is tracked
- Repeatability: Same setup every time
- Documentation: The code itself documents our infrastructure
- Collaboration: Team members can understand and contribute easily
Breaking Down Our Infrastructure ๐
First Things First: State Management ๐ฆ
terraform {
backend "s3" {
bucket = "zscrum-terraform-state"
key = "dev/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-lock"
encrypt = true
}
}
Why this setup? Because:
- S3 is reliable and secure for state storage
- DynamoDB prevents concurrent modifications
- Encryption keeps our state file secure
Networking: The Foundation ๐
Remember our "virtual city" from the last post? Here's how we build it:
module "vpc" {
source = "./modules/vpc"
vpc_cidr = "10.0.0.0/16"
availability_zones = ["us-east-1a", "us-east-1b"]
public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
private_subnets = ["10.0.3.0/24", "10.0.4.0/24"]
}
We split our network into:
- Public subnets for load balancers
- Private subnets for our containers
- NAT Gateways for private subnet internet access
Load Balancer: The Traffic Director ๐ฆ
module "alb" {
source = "./modules/alb"
vpc_id = module.vpc.vpc_id
public_subnets = module.vpc.public_subnet_ids
certificate_arn = module.acm.certificate_arn
health_check = {
path = "/api/health"
healthy_threshold = 2
unhealthy_threshold = 10
}
}
Our ALB configuration ensures:
- Health checks detect issues quickly
- SSL termination at the load balancer
- Smart traffic distribution
Container Infrastructure: Building and Deploying ๐ณ
First, let's look at our Dockerfile that packages our application:
# Base image
FROM node:18-alpine
# Set working directory
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy application files
COPY . .
# Build the application
RUN npm run build
# Expose port
EXPOSE 3000
# Start the application
CMD ["npm", "start"]
To automate our container builds and pushes to ECR, I created a handy shell script (let's call it deploy-ecr.sh
):
#!/bin/bash
set -e
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
#for full code refer github
This script handles everything from building to pushing our container image. Simply run it with:
./deploy-ecr.sh -a your-aws-account -r your-region -e your-repo-name
Now, let's look at how we manage our containers with Terraform:
module "ecs" {
source = "./modules/ecs"
cluster_name = "zscrum-cluster"
task_cpu = 256
task_memory = 512
container_port = 3000
desired_count = 1
private_subnet_ids = module.vpc.private_subnet_ids
security_groups = [module.security.ecs_sg_id]
}
Why these choices?
- Fargate for serverless container management
- Right-sized resources for our app
- Auto-scaling ready
Security: Defense in Depth ๐
Security is implemented through multiple modules:
module "security" {
source = "./modules/security"
vpc_id = module.vpc.vpc_id
alb_sg = module.alb.security_group_id
# Parameter Store for sensitive data
parameters = {
database_url = "secure-string"
clerk_key = "secure-string"
}
}
Key security features:
- Tight security group rules
- Encrypted parameters
- IAM roles with minimal permissions
Monitoring: Eyes on Everything ๐
module "monitoring" {
source = "./modules/monitoring"
log_retention_days = 30
alarm_sns_topic = module.sns.topic_arn
containers_to_monitor = {
app = module.ecs.container_name
}
}
This gives us:
- CloudWatch Log Groups
- Performance metrics
- Alert notifications
The Power of Modules ๐ง
Our Terraform structure:
terraform/
โโโ modules/
โ โโโ network/
โ โโโ alb/
โ โโโ ecs/
โ โโโ cdn/
โ
โโโ environments/
โ โโโ dev/
โ โโโ prod/
โโโ variables.tf
Why this structure?
- Reusable components
- Environment isolation
- Easy maintenance
Cost Optimization Strategies ๐ฐ
We're smart about costs:
- Right-sized containers
- Auto-scaling limits
- Reserved NAT Gateway instances
- CloudFront caching optimization
Lessons Learned ๐
- Start Small: Build one module at a time
-
Test Everything: Use
terraform plan
religiously - Use Workspaces: Keep environments separate
- Document As You Go: Your future self will thank you
Want to Try This Yourself? ๐
Head over to my GitHub repo where I've shared the complete Terraform setup. And don't forget to check out Piyush's original Jira Clone that made this all possible!
Questions? Comments? ๐ญ
Drop them below! I'd love to hear about your infrastructure adventures and help where I can.
Remember: Infrastructure as Code is a journey. Start small, learn continuously, and don't be afraid to make mistakes - that's how we all learn! ๐ฑ
Top comments (0)