ECS Blue/Green Deployment with AWS CodePipeline

Overview

ECS Blue/Green Deployment with AWS CodePipeline

This repository contains a set of configuration to setup a CI/CD pipeline for an AWS ECS Cluster. All configuration powered by AWS Cloud Development Kit. Hope you have fun ^^ Let's get started

Table of Contents

  1. About this Repo
  2. Cdk Setup
  3. Network Setup
  4. ECS Cluster Setup
  5. CodePipeline Setup
  6. License

About this Repo

In this repo, I give a step-by-step guide for deploying applications to ECS Fargate use AWS CodePipeline with AWS CDK. Hope you have fun ^^ Let's get started. The image below gives an overview of what we are going to create using CDK.

ECS CI/CD Architecture

Cdk Setup

Install or update the [AWS CDK CLI] from npm (requires Node.js ≥ 14.15.0). We recommend using a version in Active LTS

npm i -g aws-cdk

Bootstrap Cdk assets if you run Cdk the first time:

cdk bootstrap

Deploy this to your account:

cdk deploy

Network Setup

To be able to connect to the ECS cluster you need to create an Application Load Balancer in front of the ECS service.

Create a new vpc with 2 public subnets:

const vpc = new ec2.Vpc(this, "ecs-devops-sandbox-vpc", {
  vpcName: "ecs-devops-sandbox-vpc",
  maxAzs: 2,
  cidr: "10.0.0.0/16",
  subnetConfiguration: [
    {
      name: "ecs-devops-sandbox-subnet-public",
      subnetType: ec2.SubnetType.PUBLIC,
      cidrMask: 24,
    },
    {
      name: "ecs-devops-sandbox-subnet-private",
      subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
      cidrMask: 24,
    },
  ],
});

Create a new Application Load Balancer:

const elb = new elbv2.ApplicationLoadBalancer(
  this,
  "ecs-devops-sandbox-elb",
  {
    vpc: vpc,
    vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC },
    internetFacing: true,
  }
);

Create new target group with health check config for containers to be deployed to:

const targetGroupBlue = new elbv2.ApplicationTargetGroup(this, "target-group", {
  targetType: elbv2.TargetType.IP,
  protocol: elbv2.ApplicationProtocol.HTTP,
  port: 8080,
  vpc: vpc,
  healthCheck: {
    // My custom health check
    path: "/api/v1/health",
  },
});

Create a new HTTP listener for HTTP requests around the world on port 80:

const listener = elb.addListener("ecs-devops-sandbox-listener", {
  port: 80,
  open: true,
});

listener.addTargetGroups("ecs-devops-sandbox-target-group", {
  targetGroups: [targetGroupBlue],
});

Create a new Security Group and attach it to Application Load Balancer:

const elbSG = new ec2.SecurityGroup(this, "ecs-devops-sandbox-elb-sg", {
  vpc: vpc,
  allowAllOutbound: true,
});

// Allow access from around the world
elbSG.addIngressRule(
  ec2.Peer.anyIpv4(),
  ec2.Port.tcp(80),
  "Allow HTTP traffic from the world"
);

// Attach the ELB to the Security Group
elb.addSecurityGroup(elbSG);

ECS Cluster Setup

This section helps to create all the resources in ECS and connects them to the application load balancer. It creates the following resources:

Create a new ECS cluster:

const cluster = new ecs.Cluster(this, "ecs-devops-sandbox-cluster", {
  clusterName: "ecs-devops-sandbox-cluster",
  vpc: vpc,
});

Create a new ECS execution role help your cluster has permission for pulling image from AWS ECR and pushing logs to AWS Cloudwatch:

const executionRole = new iam.Role(
  this,
  "ecs-devops-sandbox-execution-role",
  {
    assumedBy: new iam.ServicePrincipal("ecs-tasks.amazonaws.com"),
    roleName: "ecs-devops-sandbox-execution-role",
  }
);

executionRole.addToPolicy(
  new iam.PolicyStatement({
    effect: iam.Effect.ALLOW,
    resources: ["*"],
    actions: [
      "ecr:GetAuthorizationToken",
      "ecr:BatchCheckLayerAvailability",
      "ecr:GetDownloadUrlForLayer",
      "ecr:BatchGetImage",
      "logs:CreateLogStream",
      "logs:PutLogEvents",
    ],
  })
);

You also need to create a task role that help the task and its containers can access AWS Resources through IAM Role:

const taskRole = new iam.Role(this, "ecs-devops-sandbox-task-role", {
  assumedBy: new iam.ServicePrincipal("ecs-tasks.amazonaws.com"),
  roleName: "ecs-devops-sandbox-task-role",
  description: "ECS Task Role",
});

// Allow sendEmail
taskRole.addToPolicy(
  new iam.PolicyStatement({
    effect: iam.Effect.ALLOW,
    resources: ["*"],
    actions: ["ses:SendEmail"],
  })
);

Create a new ECS task definition:

const taskDefinition = new ecs.FargateTaskDefinition(
  this,
  "ecs-devops-sandbox-task-definition",
  {
    cpu: 256,
    memoryLimitMiB: 512,
    executionRole: executionRole,
    family: "ecs-devops-sandbox-task-definition",
    taskRole: taskRole,
  }
);

Create a new docker container including the image to use:

const container = taskDefinition.addContainer(
  "ecs-devops-sandbox-container",
  {
    image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
    memoryReservationMiB: 512,
    environment: {
      SANDBOX_ELB_DNS: elb.loadBalancerDnsName,
    },
    // Store the logs in cloudwatch
    logging: new ecs.AwsLogDriver({ streamPrefix: "ecs-devops-sandbox" }),
  }
);

Mapping port for containers:

container.addPortMappings({ containerPort: 80 });

Create a new Security groups to allow connections from the application load balancer to the fargate containers:

const serviceSG = new ec2.SecurityGroup(
  this,
  "ecs-devops-sandbox-service-sg",
  {
    vpc: vpc,
    allowAllOutbound: true,
  }
);

serviceSG.connections.allowFrom(
  elbSG,
  ec2.Port.allTcp(),
  "Allow traffic from the ELB"
);

Create a new ECS Fargate Service user for deploying tasks:

const service = new ecs.FargateService(this, "ecs-devops-sandbox-service", {
  cluster: cluster,
  taskDefinition: taskDefinition,
  securityGroups: [serviceSG],
  assignPublicIp: true,
  desiredCount: 1,
  serviceName: "ecs-devops-sandbox-service",
});

Attach ECS Fargate Service to Target Group that we've created before:

service.attachToApplicationTargetGroup(targetGroupBlue);

Create a new Scalable Target for tasks based on CPU and Memory Utilization:

const scalableTarget = service.autoScaleTaskCount({
  maxCapacity: 3,
  minCapacity: 1,
});

scalableTarget.scaleOnCpuUtilization("ecs-devops-sandbox-cpu-scaling", {
  targetUtilizationPercent: 50,
});

scalableTarget.scaleOnMemoryUtilization(
  "ecs-devops-sandbox-memory-scaling",
  {
    targetUtilizationPercent: 50,
  }
);

CodePipeline Setup

To perform blue/green deployment with ECS and CodePipeline, you need to create some extra resources:

Create a new Target Group for Green Environment that be used by CodePipeline:

const targetGroupGreen = new elbv2.ApplicationTargetGroup(
  this,
  "target-group-green",
  {
    targetType: elbv2.TargetType.IP,
    protocol: elbv2.ApplicationProtocol.HTTP,
    port: 8080,
    vpc: vpc,
    healthCheck: {
      // My custom health check
      path: "/api/v1/health",
    },
  }
);

You also need a service role that can be used by AWS CodeDeploy to perform actions in your ECS Cluster (for information, please read this documenation: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/codedeploy_IAM_role.html):

const ecsCodeDeployRole = new iam.Role(this, "ecs-codedeploy-role", {
  assumedBy: new iam.ServicePrincipal("codedeploy.amazonaws.com"),
  roleName: "ecs-codedeploy-role",
  description: "ECS CodeDeploy Role",
});

ecsCodeDeployRole.addManagedPolicy(
  iam.ManagedPolicy.fromAwsManagedPolicyName("AWSCodeDeployRoleForECS")
);

ecsCodeDeployRole.addToPolicy(
  new iam.PolicyStatement({
    effect: iam.Effect.ALLOW,
    resources: [taskRole.roleArn, executionRole.roleArn],
    actions: ["iam:PassRole"],
  })
);

License

License: MIT

You might also like...

A pleasing darker theme made mostly with complementary purple and blue colors, occasionally with a touch of pink or red.

A pleasing darker theme made mostly with complementary purple and blue colors, occasionally with a touch of pink or red.

Nebula Float away in space with a beautiful blurple oriented color theme. DISCLAIMER: ⚠️ This theme is not as high contrast as other themes. A pleasin

Nov 23, 2022

RedEye is a visual analytic tool supporting Red & Blue Team operations

RedEye is a visual analytic tool supporting Red & Blue Team operations

RedEye Red Team C2 Log Visualization RedEye is an open-source analytic tool developed by CISA and DOE’s Pacific Northwest National Laboratory to assis

Jan 3, 2023

A serverless AWS expense tracker API. AWS Lambda functions, API gateway, and Dynamodb are among the ingredients.

AWS-Serverless-API A serverless AWS expense tracker API. AWS Lambda functions API gateway Dynamodb Endpoints Create a new expense: Method: POST Body f

Jul 16, 2022

Everynode allows you to run any version of Node.js in AWS Lambda, in any commercial AWS region

Everynode allows you to run any version of Node.js in AWS Lambda, in any commercial AWS region

Run Any Node.js Version in AWS Lambda Everynode allows you to run any version of Node.js in AWS Lambda, in any commercial AWS region. We add support f

Dec 15, 2022

Deploy an Architect project from GitHub Actions with keys gathered from aws-actions/configure-aws-credentials

Deploy an Architect project from GitHub Actions with keys gathered from a specific AWS IAM Role federated by an IAM OIDCProvider. CloudFormation to cr

Apr 6, 2022

A monorepo that uses the AWS Cloud Development Kit to deploy and configure nanomdm on AWS lambda.

NanoMDM on AWS This repo builds and configures a nanomdm server to run on AWS lambda. It uses the Cloud Development Kit and tries to follow best pract

May 26, 2022

a stack-separated way to bringing together common AWS services useful in a fullstack application that uses AWS Amplify libraries

Fullstack CDK Helpers This project helps developers create common AWS services that are useful in creating fullstack applications. Backend services ar

Nov 26, 2022

Lumos is an AWS Lambda visualizer and open source alternative to AWS CloudWatch.

Lumos is an AWS Lambda visualizer and open source alternative to AWS CloudWatch.

Lumos Lambda Metrics Visualizer Table of Contents About Lumos Techologies Used Getting Started Key Lambda Metrics How to Contribute License Contributo

Nov 5, 2022

An Amazon Kendra REST API CDK example with an API Gateway, including authentication with AWS Cognito and AWS X-Ray Tracing

An Amazon Kendra REST API CDK example with an API Gateway, including authentication with AWS Cognito and AWS X-Ray Tracing

Amazon Kendra Web Service CDK Sample Amazon Kendra has a robust JSON API for use with the AWS SDK (software development kit), but does not expose endp

Nov 28, 2022
Owner
Phạm Khắc Quyền
Software Engineer at Spring Knowledge Global
Phạm Khắc Quyền
A sample CICD Deployment Pipeline for your Alexa Skills, using AWS CDK, CodeBuild and CodePipeline

Alexa Skils - CI/CD CDK Pipeline This repository will help you setting up a CI/CD pipeline for your Alexa Skills. This pipeline is powered by AWS Clou

null 5 Nov 23, 2022
Under the Sea is an official AWS workshop delivered by AWS SAs and AWS Partners to help customers and partners to learn about AIOps with serverless architectures on AWS.

Under the Sea - AIOps with Serverless Workshop Under the Sea is an exciting MMORPG developed by the famous entrepreneur behind Wild Rydes, the most po

AWS Samples 4 Nov 16, 2022
A 👩‍💻 developer-friendly entity management system for 🕹 games and similarly demanding applications, based on 🛠 ECS architecture.

Miniplex Ecosystem miniplex miniplex-react Introduction Miniplex is an entity management system for games and similarly demanding applications. Instea

Hendrik Mans 253 Dec 31, 2022
Learn Web 2.0 and Web 3.0 Development using Next.js, Typescript, AWS CDK, AWS Serverless, Ethereum and AWS Aurora Serverless

Learn Web 2.0 Cloud and Web 3.0 Development in Baby Steps In this course repo we will learn Web 2.0 cloud development using the latest state of the ar

Panacloud Multi-Cloud Internet-Scale Modern Global Apps 89 Jan 3, 2023
MerLoc is a live AWS Lambda function development and debugging tool. MerLoc allows you to run AWS Lambda functions on your local while they are still part of a flow in the AWS cloud remote.

MerLoc MerLoc is a live AWS Lambda function development and debugging tool. MerLoc allows you to run AWS Lambda functions on your local while they are

Thundra 165 Dec 21, 2022
AWS Lambda & Serverless - Developer Guide with Hands-on Labs. Develop thousands line of aws lambda functions interact to aws serverless services with real-world hands-on labs

AWS Lambda & Serverless - Developer Guide with Hands-on Labs UDEMY COURSE WITH DISCOUNTED - Step by Step Development of this Repository -> https://www

awsrun 35 Dec 17, 2022
Green Lattice Overlay for r/place

Green Lattice Overlay for r/place Step 1 Install one of the following extensions for your browser. Chrome (TamperMonkey) Firefox (ViolentMonkey) (note

siah 4 Apr 25, 2022
A server setup to take screenshots against the green screen in-game.

alt:V Clothing Green Screener Support on Patreon. Seriously. Ever want screenshots of every single clothing item in GTA:V? Well this is your repositor

null 13 Dec 26, 2022
Primeiro projeto do Módulo 1 da Blue ed Tech - Web Fullstack

Projeto1-Modulo1-BlueFullstack Módulo 1 - Blue ed Tech - Web Fullstack Projeto 1 - A Jornada do Herói A premissa é a seguinte: O nosso herói chegou ao

Vinhas93 2 Mar 9, 2022