You can support us by downloading this article as PDF from the Link below. Download the guide as PDF

This article is part 4 of a 4 part guide to running Docker containers on AWS ECS. ECS stands for Elastic Container Service. It is a managed container service that runs docker containers. Although AWS also offers container management with Kubernetes, (EKS) it also has its proprietary solution (ECS).

The other parts of the guide already covered in separate articles are:

Part 4 of this guide will cover, “Creating a Pipeline to Update the tasks/containers running on the ECS Cluster,”. The container update happens any time we push a change to the CodeCommit repository.

For this demonstration, we will create a pipeline to update the service and task running on the ECS cluster using CodePipeline. We assume the project source code is on a CodeCommit repository. However, CodePipeline can pick code from various version control tools including:

  • GitHub.
  • GitHub Enterprise Edition.
  • Bitbucket.

Requirements/Prerequisites

  • An AWS Account.
  • Created a User on the account with Permissions to provision resources on the account.
  • Created a CodeCommit Repository and uploaded your source code there.
  • Already created the ECS cluster and have services and tasks running there.
  • Provisioned an ECR registry and uploaded a docker image to the registry.
  • A CloudWatch log group or S3 bucket to store your build project logs.

Create a Build Project

Using CodeBuild we are going to create a Build Project that will build a docker image from a docker file pushed to our code commit repository. It will then push the docker image to the ECR Registry.

On the CodeBuild console, click create build project.

Create Build Project 1
Create, Build Project

ECS CodeBuild Project Configurations:

Next on project configurations, enter your project name and description. Also, you can add tags for your build project.

Code Build Project Configurations
Project Configurations

For source, choose CodeCommit. Assuming you have your project code pushed to a Codecommit Repository.

CodeBuild Project Source
CodeBuild Project Source

Next under Environment Configurations, choose the environment you would want your build project to be executed. Since our image is a Linux image, we chose a Linux environment.

CodeBuild Environment Configurations
CodeBuild Environment Configurations

For the role, select new service role. N/B: Ensure that the role has the AmazonEC2ContainerRegistryFullAccess policy attached to it. Otherwise, CodeBuild will not work.

CodeBuild Service Role
Configure CodeBuild Service Role

ECS CodeBuild BuildSpec.yml:

Under BuildSpec, click Switch to Editor and paste the following code on your buildspec.yml. Ensure that for the docker tag and docker push commands, you replace this with your ECR registry push commands. Also, the docker build image name should be replaced with your respective docker image name.

version: 0.2
phases:
  install:
    runtime-versions:
       docker: 19
    commands:
      - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
      - unzip awscliv2.zip
      - ./aws/install
  pre_build:
    commands:
      - echo logging to ecr
      - $(aws ecr get-login --no-include-email --region eu-central-1)
  build:
    commands:
      - echo starting build on 'date'
      - cd ./
      - docker build -t hello-world .
      - docker tag hello-world:latest 429758582529.dkr.ecr.eu-central-1.amazonaws.com/hello-world:latest
  post_build:
    commands:
      - echo build completed on 'date'
      - echo pushing to repo
      - docker push 429758582529.dkr.ecr.eu-central-1.amazonaws.com/hello-world:latest
      - echo Writing definitions file...
      - printf '[{"name":"Hello_World","imageUri":"%s"}]' 429758582529.dkr.ecr.eu-central-1.amazonaws.com/hello-world:latest > HelloWorldtaskdefinition.json
artifacts:
  files: HelloWorldtaskdefinition.json

Since we are pushing a docker image to an ECR registry, there is no need to have artifacts. Hence under artifacts select none. For logs, we will have them pushed to a CloudWatch log group that you had created earlier.

Artifacts and Logs
Configure Build Project Artifacts and Logs

Finally, click create build project.

Create a Pipeline to Deploy to ECS Cluster

After creating a CodeBuild project, Next we will create a pipeline to deploy the docker image to update ECS cluster service and tasks.

On the CodePipeline Console, click create pipeline.

CodePipeline Create Pipeline
CodePipeline Create Pipeline

Then, under pipeline settings enter your pipeline name. For Service Role choose New Service Role. Under Advanced Settings choose Default Location for artifact store and default AWS managed key for the encryption key. Then click next.

CodePipeline Pipeline Settings 1
Pipeline Settings

ECS CodePipeline Add Source Stage:

On the add source stage, select CodeCommit as your source. Then choose your repository and repository branch for your code. Under Change detection options choose CloudWatch Events. This way CloudWatch will actively monitor changes on the repository and anytime it detects a change it auto-starts the pipeline. Click next.

CodePipeline Add Source Stage
CodePipeline Add Source Stage

ECS CodePipeline Add Build Stage:

For Add a Build Stage, select your build provider as CodeBuild. Then select a region where you created the Build Project and select the build project name. Use the Build project we created in the “Create a Build Project” section of this article. For Build Type, select single build then click next.

CodePipeline Add a Build Stage
CodePipeline Add a Build Stage

ECS CodePipeline Add Deploy Stage:

Next, we have to add a deploy stage to our pipeline. On the Add Deploy Stage, choose our deploy provider to be Amazon ECS. For the region, select the region where you created your ECS cluster. Then under cluster name, select the name of your ECS cluster. Choose the service name of the ECS service you would like to update on the ECS cluster.

When we created our build project on our buildspec.yml we had created an image definitions file. For this case, it was HelloWorldtaskdefinition.json. Paste the name of that file under the image definitions file section of the deploy stage. Finally, for the deployment timeout, enter the time in minutes that we should wait for the deployment before it times out.

CodePipeline Add Deploy Stage
CodePipeline Add Deploy Stage

On the review section, review your pipeline settings and if ok with all configurations click create pipeline.

Pipeline Execution
Pipeline Execution

You now have a pipeline that updates an ECS Service and Tasks anytime a change is pushed to the CodeCommit repository. By default, the update is a rolling update. i.e. ECS will deploy a new Task running alongside the older Task. When the new task reaches a steady-state, then a switch is made to the new Task and the old Task is terminated.

Other AWS Guides:

Happy Building!!!

You can support us by downloading this article as PDF from the Link below. Download the guide as PDF