Skip to main content

Command Palette

Search for a command to run...

AWS Terraform Blue-Green Deployment Using Elastic Beanstalk

Published
4 min read

Architectural Diagram

Blue - Green Deployment Strategy

Blue-green deployment is a release technique that keeps two identical production environments - nicknamed “blue” and “green.”

At any moment, only ONE of them is live and serving real users. Say the “blue“.

To deploy a new version, you:

  • Push the new build to the idle environment (say green).

  • Run whatever tests you need against green.

  • Once green is healthy, switch the router / load-balancer / Elastic-Beanstalk URL so that all incoming traffic instantly goes to green instead of blue.

  • If something breaks, you “flip back” to blue in seconds.

  • If everything looks good, leave green as the new live environment and recycle blue for the next release.

For this project, we will use two applications and deploy them to production. Then, after that, we will swap the production from blue to green.

Blue Environment Setup

We set up the Blue environment with version 1.0 in AWS Elastic Beanstalk.

1. Uploads the app code to S3

resource "aws_s3_object" "app_v1" {
  bucket = aws_s3_bucket.app_versions.id
  key    = "app-v1.zip"
  source = "${path.module}/app-v1/app-v1.zip"
  etag   = filemd5("${path.module}/app-v1/app-v1.zip")

  tags = var.tags
}
  • Takes app-v1.zip from your local folder

  • Uploads it to an S3 bucket (named app_versions)

  • Calculates MD5 hash to detect changes

2. Creates an Elastic Beanstalk app version

resource "aws_elastic_beanstalk_application_version" "v1" {
  name        = "${var.app_name}-v1"
  application = aws_elastic_beanstalk_application.app.name
  description = "Application Version 1.0 - Initial Release"
  bucket      = aws_s3_bucket.app_versions.id
  key         = aws_s3_object.app_v1.id

  tags = var.tags
}
  • Registers app-v1.zip as version your-app-name-v1

  • Links it to your main EB application

  • Stores it in S3 with the version label

3. Launches the production environment (Blue)

resource "aws_elastic_beanstalk_environment" "blue" {
  name                = "${var.app_name}-blue"
  application         = aws_elastic_beanstalk_application.app.name
  solution_stack_name = var.solution_stack_name
  tier                = "WebServer"
  version_label       = aws_elastic_beanstalk_application_version.v1.name

  # IAM Settings
  setting {
    ....
}
  • Creates an environment called your-app-name-blue

  • Deploys version 1.0 to it

  • Uses your specified platform (solution_stack_name)

  • Sets it as a WebServer tier (production-ready)

In simple terms: It bundles the app → uploads to S3 → registers as EB version 1.0 → deploys to production (blue environment).

Green Environment Setup

The same sequence of measures for the green environment as well.

# Application Version 2.0 (Green Environment - Staging)
resource "aws_s3_object" "app_v2" {
  bucket = aws_s3_bucket.app_versions.id
  key    = "app-v2.zip"
  source = "${path.module}/app-v2/app-v2.zip"
  etag   = filemd5("${path.module}/app-v2/app-v2.zip")

  tags = var.tags
}

resource "aws_elastic_beanstalk_application_version" "v2" {
  name        = "${var.app_name}-v2"
  application = aws_elastic_beanstalk_application.app.name
  description = "Application Version 2.0 - New Feature Release"
  bucket      = aws_s3_bucket.app_versions.id
  key         = aws_s3_object.app_v2.id

  tags = var.tags
}

# Green Environment (Staging/Pre-production)
resource "aws_elastic_beanstalk_environment" "green" {
  name                = "${var.app_name}-green"
  application         = aws_elastic_beanstalk_application.app.name
  solution_stack_name = var.solution_stack_name
  tier                = "WebServer"
  version_label       = aws_elastic_beanstalk_application_version.v2.name

  # IAM Settings
  ...
}

Main Terraform Configuration

We set up security and IAM permissions.

1. EC2 Instance Role (for your app servers)

# IAM Role for Elastic Beanstalk EC2 instances
resource "aws_iam_role" "eb_ec2_role" {
  name = "${var.app_name}-eb-ec2-role"

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

  tags = var.tags
}
  • Creates an IAM role ${your-app}-eb-ec2-role

  • Allows EC2 instances to "assume" this role

  • Gives your running app permissions to access AWS services (databases, S3, etc.)

2. Elastic Beanstalk Service Role (for AWS control plane)

# IAM Role for Elastic Beanstalk Service
resource "aws_iam_role" "eb_service_role" {
  name = "${var.app_name}-eb-service-role"

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

  tags = var.tags
}
  • Creates an IAM role ${your-app}-eb-service-role

  • Allows the Elastic Beanstalk service itself to manage your environments

  • AWS needs this to deploy, scale, and monitor your app

3. Locks down S3 bucket security

# Block public access to S3 bucket
resource "aws_s3_bucket_public_access_block" "app_versions" {
  bucket = aws_s3_bucket.app_versions.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}
  • Blocks all public access to your app_versions S3 bucket

  • Prevents accidental public exposure of app-v1.zip

  • All 4 public access settings = maximum security

Running

   17-Blue-Green-Deployment   git:(main)  sudo chmod 755 package-apps.sh
[sudo] password for kutt:     
   17-Blue-Green-Deployment   git:(main)  
   17-Blue-Green-Deployment   git:(main)  ./package-apps.sh 
=====================================
Packaging Applications for Deployment
=====================================

Packaging Application v1.0 (Blue)...
[SUCCESS] Created app-v1/app-v1.zip

Packaging Application v2.0 (Green)...
[SUCCESS] Created app-v2/app-v2.zip

=====================================
[SUCCESS] All applications packaged successfully!
=====================================

Next steps:
1. Run: terraform init
2. Run: terraform plan
3. Run: terraform apply

After applying the Terraform Apply:

Blue is in production with version 1.0

Green in the staging environment with version 2.0

Here, we test the environment, making sure the edge cases are solved and make it ready for production.

Now, we swap:

(Due to the cache, the application weern’t updating very well. Open in a new browser, and we can see the swap is done.)


Repo link: Here

Video Reference:


Arigato!

More from this blog

Code Companions

32 posts