DEV Community

Cover image for Building a Secure Blue/Green Deployment Pipeline on Amazon ECS with Jenkins
Nishath J P
Nishath J P

Posted on

Building a Secure Blue/Green Deployment Pipeline on Amazon ECS with Jenkins

Deploying a container is easy.

Deploying it safely, repeatedly, with security checks and a rollback path is a different challenge.

While learning more about container deployment patterns on AWS, I wanted to build something beyond a basic:

Docker Build → Push Image → Deploy
Enter fullscreen mode Exit fullscreen mode

So, I build a project called DeployGuard, which is a hands-on CI/CD project which combines tools like jenkins, Docker, Trivy and multiple AWS services to implement automated Blue/Green deployment on Amazon ECS.

My goal was not to simply run a application. I wanted to understand what happens when a developer pushes a code and how production traffic reaches to a new container.

Github repo: https://github.com/Nishath06/DeployGuard?utm_source=chatgpt.com

What I Wanted to Build

My target workflow was:

Developer
    │
    ▼
 GitHub
    │
    ▼
 Jenkins
    │
    ├── Run Tests
    │
    ├── Build Docker Image
    │
    └── Scan Image with Trivy
    │
    ▼
 Amazon ECR
    │
    ▼
 Amazon ECS
    │
    ▼
Blue/Green Deployment
    │
    ▼
Application Load Balancer
    │
    ▼
   Users
Enter fullscreen mode Exit fullscreen mode

For monitoring purpose I also wanted the application logs available through AWS CloudWatch thus the deployment success is not only indicated by the application health.

AWS Architecture

The AWS side of DeployGuard uses:

Amazon ECR: to Store container image.
Amazon ECS with Fargate: for running the container.
AWS Application load balancer: for routing traffic.
Target Groups: for blue/green deployments.
Jenkins: for CI/CD workflow.
Trivy: for container vulnerability scanning.

Automating the Workflow with Jenkins

Jenkins was responsible moving application through different stages of the delivery process.

Stages:

Checkout
   ↓
Prepare Build Info
   ↓
Test
   ↓
Docker Build
   ↓
Trivy Scan
   ↓
ECR Login
   ↓
Push ECR
   ↓
Verify ECR Image
   ↓
Deploy to ECS
Enter fullscreen mode Exit fullscreen mode

One thing I wanted was traceability between source code and container images.

During the pipeline, Jenkins retrieves the short Git commit SHA:

git rev-parse --short HEAD

Enter fullscreen mode Exit fullscreen mode

That value can then be used as the Docker image tag.

For example:

deployguard:84015e5

Enter fullscreen mode Exit fullscreen mode

This was much more useful than having every build represented only as latest, because I can identify which source revision produced an image.

Adding Container Security Scanning

Before pushing the application container to deployment workflow, I added Trivy to jenkins.

The pipeline scans the built image for HIGH and CRITICAL vulnerabilities:

trivy image \
    --severity HIGH,CRITICAL \
    --exit-code 0 \
    ${IMAGE}:${GIT_SHA}
Enter fullscreen mode Exit fullscreen mode

For this project, I used --exit-code 0, which meaning vulnerabilities are reported but don't automatically stop the pipeline.

For stricter production pipeline, we could turn the scan into a security quality gate so that unacceptable vulnerabilities prevent the image from reaching production.

For example:

Docker Build
     │
     ▼
Trivy Scan
     │
     ├── Pass ─────► Push to ECR
     │
     └── Fail ─────► Stop Pipeline
Enter fullscreen mode Exit fullscreen mode

This is one of the improvements I plan to make as I continue developing DeployGuard.

Storing Images in Amazon ECR

After testing and scanning, Jenkins authenticates with Amazon ECR and pushes the Docker image.

Now ECS can pull the image from the ECR using roles when creating a new task.

One issue I encountered here taught me an important lesson about container tagging.

During an earlier deployment, ECS reported:

CannotPullContainerError

The service was attempting to retrieve an image tag that wasn't available in the ECR repository.

Fixing the tagging strategy and ensuring the required image existed in ECR resolved the problem.

That experience made the relationship between Jenkins → ECR → ECS task definition much clearer to me.

Why Blue/Green Deployment?

Normal replacement deployment can introduce risk in production

For example

Imagine version 1 is currently running:

Users → Version 1

Version 2 is released, but it contains a problem.

If version 1 has already been replaced, recovering may require another deployment.

Blue/green deployment takes a different approach.

Two environments are available:

BLUE → Existing deployment
GREEN → New deployment

The new version can start in the alternate environment before it becomes the production target.

For DeployGuard, I created two target groups:

deployguard-blue
deployguard-green

An important concept I learned is that blue doesn't permanently mean production and green doesn't permanently mean staging.

They are deployment slots.

After deployments, their roles can alternate.

Routing Traffic with an Application Load Balancer

The Application Load Balancer provides the public entry point to DeployGuard.

The ALB works together with ECS and the target groups to route application traffic.

Conceptually:
`
Users


Application Load Balancer

Production Traffic

┌───────┴───────┐
▼ ▼
BLUE TG GREEN TG
│ │
▼ ▼
ECS Tasks ECS Tasks

`

Watching ECS Perform the Deployment

After all the configurations issues, I could finally see the successful deployments from the ECS console.

The screenshot also shows something I intentionally think is worth sharing: my earlier deployments failed.

In this process I also encountered failed rollbacks.

Some of the issues I had to troubleshoot included:

  • CannotPullContainerError
  • incorrect/missing ECR image tags
  • target group configuration
  • ALB returning 503 Service Temporarily Unavailable
  • ECS tasks failing to become available
  • deployment circuit breaker rollbacks

Eventually the same deployment history started showing:
❌ Rollback failed
❌ Rollback failed
✅ Success
✅ Success

The failures forced me to understand what ECS was actually doing rather than simply following configuration steps until something worked.

Observability with Amazon CloudWatch

A deployment showing "Success" doesn't necessarily tell me everything about the application.

I therefore configured the ECS task to send container logs to Amazon CloudWatch Logs.

The Final Application

After connecting the pipeline and AWS infrastructure, DeployGuard was accessible through the Application Load Balancer.

I designed the UI around the deployment concepts being demonstrated by the project.

It visualizes information such as:

Environment
Application Version
Deployment Slot
Application Health
Git Commit
Build Number
Blue/Green State

The dashboard itself is only the visualization layer.

The actual deployment, task management, target registration and traffic routing happen through the AWS infrastructure behind it.

What Happens After a Code Change?

Putting everything together helped me understand the complete deployment lifecycle:

Developer pushes code

GitHub

Jenkins triggered

Application tests

Docker image built

Trivy vulnerability scan

Image pushed to Amazon ECR

ECS deployment triggered

New ECS/Fargate task starts

Task joins alternate target group

Health validation

Blue/Green deployment proceeds

Application serves traffic

Logs → Amazon CloudWatch

That's considerably more interesting than the docker build and docker run workflow I started with.

Three Things This Project Taught Me

**1. A successful CI pipeline doesn't mean a successful deployment

  1. Health checks are critical to safe deployments
  2. Debugging AWS integrations teaches more than isolated services**

Final Thoughts

DeployGuard started as an experiment to understand blue/green deployments.

It ended up teaching me much more about how CI/CD systems interact with AWS infrastructure.

Instead of learning Amazon ECS, Amazon ECR, ALB, CloudWatch, Docker, Jenkins and container security independently, I had to make them work together as one system.

And when they didn't work together, debugging those failures became part of the learning process.

If you're learning AWS or DevOps, I'd recommend building something where multiple AWS services have to interact rather than stopping after deploying a single container.

You learn a lot when the architecture breaks. 🙂

The complete source code and Jenkins pipeline are available here:

DeployGuard Demo App

DeployGuard Logo Python Version FastAPI Docker

Purpose

DeployGuard Demo App is a lightweight, production-ready demonstration application engineered specifically for DevOps pipelines incorporating Docker, Jenkins CI/CD, Amazon ECR, and AWS ECS Fargate with Blue/Green deployments.

It demonstrates core SRE & DevOps patterns:

  • Zero-downtime Blue/Green deployments (traffic routing between BLUE and GREEN slots).
  • Version visibility and tracking (prominent UI indicators for LinkedIn / portfolio demos).
  • Automated health check validation (AWS ECS ALB integration).
  • Rollback simulation via intentional health endpoint degradation.

Architecture

Architecture Diagram


Features

  • Lightweight & High-Performance: Built using FastAPI and Uvicorn.
  • 🎨 DevOps SRE Dashboard Aesthetic: Dark theme with slot indicators and completed pipeline stages.
  • 🔄 Live Status Polling: Dynamic UI updates without page reloads.
  • 🐳 Single Docker Container: Packaged in a minimal python:3.12-slim container with native Python Docker HEALTHCHECK.
  • 🧪 100% Test Coverage: Complete unit test suite using pytest.

Environment Variables

The application…

I'm continuing to improve DeployGuard as I learn more about AWS deployment patterns, security and observability.

If you have suggestions for improving the architecture, I'd be happy to hear them!

Top comments (0)