Deploy to AWS ECS with Github actions 🚀

Consistency and automations are key to every project. In this article we will be looking on how we can automate deployments to AWS ECS.
Cover image for Deploy to AWS ECS with Github actions
Photo by SpaceX on Unsplash

It is a very simple solution which requires almost zero coding. Yet, it’s quite powerful as it allows you to deploy automatically every time there is a change in your code.

We will be using Github actions to achieve that. In particular, we will cover the following steps:

  1. Build and deploy a new docker image to ECR
  2. Retrieve and update the task definition with the new image tag
  3. Update the corresponding services and force redeployment

Get started

First, you will need to register your AWS credentials as Secrets in your Github project. Assuming that you create two new Secrets AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, you should be able to configure AWS in your Github action as per below:

1- name: Configure AWS credentials
2 uses: aws-actions/configure-aws-credentials@v1
3 with:
4 aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
5 aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
6 aws-region: us-east-2

The above registers AWS credentials so that they are available for the next action.

Deploy docker image to ECR

Next we need to build and deploy our image. Most likely, this will be a time consuming action, especially if you have a large number of third party dependencies.

1- name: Login to Amazon ECR
2 id: login-ecr
3 uses: aws-actions/amazon-ecr-login@v1
4- name: Build, tag, and push image to Amazon ECR
5 env:
6 ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
7 ECR_REPOSITORY: your-ecr-repot
8 IMAGE_TAG: ${{ github.sha }}
9 run: |
10 docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
11 docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
12 echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"

There a couple of things that you will need to adjust here. First you will need to provide the repository to deploy to for env ECR_REPOSITORY.

Then you might need to change how the IMAGE_TAG should look like. By default it will include only the commit SHA. Personally, I prefer to include also the date the image was build.

Update ECS task definition and Deploy!

Once the image is build and pushed to ECR, it is time to update the task definition and specify the new image tag. Depending on your setup you may have one or more tasks for the same image tag. In that case, you will need to repeat these steps.

Ideally, you should have the the task definition as part of your code base. In the following examples, we are assuming that the file is called task-definition.json

In case you don’t, you can retrieve the task definition dynamically as per below. However, you might need to remove some parts of the definition, before pushing back to AWS – in that case jq is quite helpful.

1- name: Download task definition
2 run: |
3 aws ecs describe-task-definition --task-definition my-task-definition-family --query taskDefinition > task-definition.json

The following actions specify the new image tag in our task definition and force a deployment to our service. The last option wait-for-service-stability is important since it ensures that the service will reach a stable stage before proceeding further.

1- name: Fill in the new image ID in the Amazon ECS task definition
2 id: task-def
3 uses: aws-actions/amazon-ecs-render-task-definition@v1
4 with:
5 task-definition: task-definition.json
6 container-name: my-container
7 image: ${{ steps.build-image.outputs.image }}
8 
9- name: Deploy Amazon ECS task definition
10 uses: aws-actions/amazon-ecs-deploy-task-definition@v1
11 with:
12 task-definition: ${{ steps.task-def.outputs.task-definition }}
13 service: my-service
14 cluster: my-cluster
15 wait-for-service-stability: true

Similar to the previous actions there a few things that you will need to adjust here. Replace my-containermy-service and my-cluster with your setup details.

Conclusion

Having automated deployments to ECS is quite easy with Github actions. Yet, it’s quite powerful as it allows you to deploy automatically every time there is a change in your code.

You can also use the same approach to deploy from any branch or even deploy manually, if needed.

Make sure to follow me on dev.toMedium or Twitter to read more about PHP, Docker and other dev topics.

Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post
Cover image for Automatic authorization in Postman

Automatic authorization in Postman 🔒

Next Post
Cover image for Improve collaboration across teams with VSCode

Improve collaboration across teams with VSCode