Blue-Green Deployment with AWS ECS + Route 53 + Terraform

Architecture Overview

  • ECS Fargate: Two separate ECS services for Blue and Green environments.
  • Application Load Balancer (ALB): Targets either Blue or Green ECS service.
  • Route 53: Points to ALB DNS. Traffic is switched from Blue to Green using ALB target group registration.
  • Terraform: Manages ECS, ALB, Route53, and automates the switch.

Real-Time Use Case

Fintech Company Problem:
Every deployment caused 2–3 minutes of downtime → resulting in failed payment transactions and angry users.
Solution: Blue-Green deployments ensured 0 downtime, real-time testing on the green environment before switching traffic with no user impact.

.
├── main.tf
├── variables.tf
├── outputs.tf
├── ecs-blue.tf
├── ecs-green.tf
├── alb.tf
├── route53.tf

variables.tf

variable "app_name" {
  default = "fintech-app"
}

variable "vpc_id" {}
variable "subnets" {
  type = list(string)
}

variable "domain_name" {}
alb.tf
resource "aws_lb" "ecs_alb" {
  name               = "${var.app_name}-alb"
  internal           = false
  load_balancer_type = "application"
  subnets            = var.subnets
  security_groups    = [aws_security_group.alb_sg.id]
}

resource "aws_lb_target_group" "blue" {
  name     = "${var.app_name}-blue-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id
}

resource "aws_lb_target_group" "green" {
  name     = "${var.app_name}-green-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id
}

resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.ecs_alb.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.blue.arn # Switch manually during cutover
  }
}

resource "aws_security_group" "alb_sg" {
  name        = "${var.app_name}-alb-sg"
  description = "Allow HTTP inbound"
  vpc_id      = var.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"]
  }
}

ecs-blue.tf and ecs-green.tf (Repeat for Green)

resource "aws_ecs_task_definition" "blue" {
  family                = "${var.app_name}-blue"
  network_mode          = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                   = "256"
  memory                = "512"

  container_definitions = jsonencode([
    {
      name  = "blue-container"
      image = "nginx" # Replace with your app image
      portMappings = [
        {
          containerPort = 80
          protocol      = "tcp"
        }
      ]
    }
  ])
}

resource "aws_ecs_service" "blue" {
  name            = "${var.app_name}-blue-svc"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.blue.arn
  desired_count   = 1
  launch_type     = "FARGATE"

  network_configuration {
    subnets         = var.subnets
    security_groups = [aws_security_group.ecs_sg.id]
    assign_public_ip = true
  }

  load_balancer {
    target_group_arn = aws_lb_target_group.blue.arn
    container_name   = "blue-container"
    container_port   = 80
  }
}

resource "aws_security_group" "ecs_sg" {
  name   = "${var.app_name}-ecs-sg"
  vpc_id = var.vpc_id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    security_groups = [aws_security_group.alb_sg.id]
  }

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

route53.tf

resource "aws_route53_record" "app_dns" {
  zone_id = data.aws_route53_zone.primary.zone_id
  name    = var.domain_name
  type    = "A"

  alias {
    name                   = aws_lb.ecs_alb.dns_name
    zone_id                = aws_lb.ecs_alb.zone_id
    evaluate_target_health = true
  }
}

data "aws_route53_zone" "primary" {
  name = var.domain_name
}
output "alb_dns" {
  value = aws_lb.ecs_alb.dns_name
}

output "route53_record" {
  value = aws_route53_record.app_dns.fqdn
}

Real-time Benefits

  • Zero-downtime deployments
  • Canary-style testing before routing production traffic
  • Fast rollback: Just flip the target group
  • Saved ~₹20L/month in failed transaction losses for fintech firms

Business Use Case: Fintech Downtime Disaster

A fast-growing fintech startup was facing severe downtime during app updates.
Even 2–3 minutes of outage during deployments led to:

  • Failed UPI & card transactions
  • Customer drop-offs mid-payment
  • Revenue loss > ₹15–20 lakhs/month

When Should You Go for Blue-Green Deployment?

Use Blue-Green Deployment if you:

  • Run mission-critical workloads (Fintech, Banking, Healthcare)
  • Cannot afford even seconds of downtime
  • Need quick rollback without re-deployment
  • Want to test in prod-like environment before cutover
  • Need safer deployments in high-risk or high-frequency update environments

AWS #Terraform #DevOps #BlueGreenDeployment #ECS #Route53 #ZeroDowntime #Fintech #CloudArchitecture #InfrastructureAsCode #CICD #AWSSolutionsArchitect #StartupTech #CloudNative

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *