0
0
Terraformcloud~10 mins

Blue-green infrastructure pattern in Terraform - Commands & Configuration

Choose your learning style9 modes available
Introduction
Switching live applications between two identical environments helps avoid downtime and reduces risk during updates. The blue-green pattern keeps one environment live while preparing the other for changes, then switches traffic smoothly.
When you want to update your app without making users wait or see errors.
When you need a quick way to roll back to the previous version if something breaks.
When you want to test a new version of your app in a real environment before making it live.
When you want to reduce downtime during deployments to nearly zero.
When you want to separate environments for staging and production but switch traffic easily.
Config File - main.tf
main.tf
provider "aws" {
  region = "us-east-1"
}

resource "aws_lb" "app_lb" {
  name               = "app-load-balancer"
  internal           = false
  load_balancer_type = "application"
  security_groups    = ["sg-0123456789abcdef0"]
  subnets            = ["subnet-0123456789abcdef0", "subnet-0fedcba9876543210"]
}

resource "aws_lb_target_group" "blue" {
  name     = "blue-target-group"
  port     = 80
  protocol = "HTTP"
  vpc_id   = "vpc-0123456789abcdef0"
}

resource "aws_lb_target_group" "green" {
  name     = "green-target-group"
  port     = 80
  protocol = "HTTP"
  vpc_id   = "vpc-0123456789abcdef0"
}

resource "aws_lb_listener" "http_listener" {
  load_balancer_arn = aws_lb.app_lb.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.blue.arn
  }
}

resource "aws_autoscaling_group" "blue_asg" {
  name                      = "blue-asg"
  max_size                  = 2
  min_size                  = 1
  desired_capacity          = 1
  vpc_zone_identifier       = ["subnet-0123456789abcdef0", "subnet-0fedcba9876543210"]
  launch_configuration      = aws_launch_configuration.blue_lc.name
  target_group_arns         = [aws_lb_target_group.blue.arn]
  health_check_type         = "ELB"
  health_check_grace_period = 300
}

resource "aws_autoscaling_group" "green_asg" {
  name                      = "green-asg"
  max_size                  = 2
  min_size                  = 1
  desired_capacity          = 0
  vpc_zone_identifier       = ["subnet-0123456789abcdef0", "subnet-0fedcba9876543210"]
  launch_configuration      = aws_launch_configuration.green_lc.name
  target_group_arns         = [aws_lb_target_group.green.arn]
  health_check_type         = "ELB"
  health_check_grace_period = 300
}

resource "aws_launch_configuration" "blue_lc" {
  name_prefix   = "blue-lc-"
  image_id      = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  security_groups = ["sg-0123456789abcdef0"]
  user_data = <<-EOF
              #!/bin/bash
              echo 'Blue version running' > /var/www/html/index.html
              EOF
}

resource "aws_launch_configuration" "green_lc" {
  name_prefix   = "green-lc-"
  image_id      = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  security_groups = ["sg-0123456789abcdef0"]
  user_data = <<-EOF
              #!/bin/bash
              echo 'Green version running' > /var/www/html/index.html
              EOF
}

This Terraform file creates two identical environments named blue and green.

The aws_lb resource creates a load balancer that directs traffic.

The aws_lb_target_group resources define groups of servers for blue and green.

The aws_lb_listener listens on port 80 and initially forwards traffic to the blue target group.

The aws_autoscaling_group resources manage the servers for blue and green environments, with blue active and green inactive at start.

The aws_launch_configuration resources define how to launch servers for each environment, with simple user data to show which version is running.

Commands
This command sets up Terraform in the current folder by downloading necessary plugins and preparing the environment.
Terminal
terraform init
Expected OutputExpected
Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/aws... - Installing hashicorp/aws v4.0.0... - Installed hashicorp/aws v4.0.0 (signed by HashiCorp) Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure.
This command creates the blue and green environments and the load balancer, applying the infrastructure described in the config file.
Terminal
terraform apply -auto-approve
Expected OutputExpected
aws_lb.app_lb: Creating... aws_lb_target_group.blue: Creating... aws_lb_target_group.green: Creating... aws_launch_configuration.blue_lc: Creating... aws_launch_configuration.green_lc: Creating... aws_autoscaling_group.blue_asg: Creating... aws_autoscaling_group.green_asg: Creating... aws_lb_listener.http_listener: Creating... ... Apply complete! Resources: 9 added, 0 changed, 0 destroyed.
-auto-approve - Skip manual approval to apply changes immediately
This command checks the current listener configuration to verify which target group (blue or green) is receiving traffic.
Terminal
aws elbv2 describe-listeners --load-balancer-arn $(terraform output -raw app_lb_arn)
Expected OutputExpected
{ "Listeners": [ { "ListenerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/app-load-balancer/50dc6c495c0c9188/6d0ecf831eec9f09", "Port": 80, "Protocol": "HTTP", "DefaultActions": [ { "Type": "forward", "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/blue-target-group/6d0ecf831eec9f09" } ] } ] }
This command switches the live traffic from the blue environment to the green environment by changing the load balancer's target group.
Terminal
aws elbv2 modify-listener --listener-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/app-load-balancer/50dc6c495c0c9188/6d0ecf831eec9f09 --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/green-target-group/6d0ecf831eec9f09
Expected OutputExpected
{}
This command scales up the green environment to start serving traffic after the switch.
Terminal
terraform apply -auto-approve -target=aws_autoscaling_group.green_asg -var='desired_capacity=1'
Expected OutputExpected
aws_autoscaling_group.green_asg: Modifying... [id=green-asg] aws_autoscaling_group.green_asg: Modifications complete after 10s [id=green-asg] Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
-target - Apply changes only to the green autoscaling group
Key Concept

If you remember nothing else from this pattern, remember: keep two identical environments and switch traffic between them to update without downtime.

Common Mistakes
Changing the load balancer target group without scaling up the new environment.
Traffic switches to an environment with no active servers, causing downtime.
Always start or scale up the new environment before switching the load balancer.
Applying Terraform changes without initializing the workspace first.
Terraform commands fail because plugins and providers are not set up.
Run 'terraform init' before any other Terraform commands.
Not verifying the load balancer listener after switching target groups.
You might think traffic switched but it still goes to the old environment.
Use AWS CLI or Terraform outputs to confirm the listener points to the correct target group.
Summary
Initialize Terraform to prepare the environment with 'terraform init'.
Apply the infrastructure to create blue and green environments and load balancer with 'terraform apply'.
Check which environment receives traffic by inspecting the load balancer listener.
Switch live traffic by modifying the load balancer listener to point to the other environment.
Scale the new environment to handle traffic after switching.