Deploy to AWS ECS with Github actions 🚀
Tags: aws, github, actions, devops
Published: 2021-11-11 18:48:33

---
title: Deploy to AWS ECS with Github actions 🚀
published: true
description: Deploy automatically to AWS ECS every time there  is a change in your code
tags: #aws #github #actions #devops
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gsnab4koti9aoiai0ued.jpg
canonical_url: https://softius.net/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.

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:

```
    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        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.

```
    - name: Login to Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v1
    - name: Build, tag, and push image to Amazon ECR
      env:
        ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        ECR_REPOSITORY: your-ecr-repot
        IMAGE_TAG: ${{ github.sha }}
      run: |
        docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
        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.

```
    - name: Download task definition
      run: |
        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.

```
    - name: Fill in the new image ID in the Amazon ECS task definition
      id: task-def
      uses: aws-actions/amazon-ecs-render-task-definition@v1
      with:
        task-definition: task-definition.json
        container-name: my-container
        image: ${{ steps.build-image.outputs.image }}

    - name: Deploy Amazon ECS task definition
      uses: aws-actions/amazon-ecs-deploy-task-definition@v1
      with:
        task-definition: ${{ steps.task-def.outputs.task-definition }}
        service: my-service
        cluster: my-cluster
        wait-for-service-stability: true
```

Similar to the previous actions there a few things that you will need to adjust here. Replace `my-container`, `my-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.to](https://dev.to/iacons), [Medium](https://medium.com/@softius) or [Twitter](https://twitter.com/iacons) to read more about PHP, Docker and other dev topics.  

Photo by [SpaceX](https://unsplash.com/@spacex?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](ttps://unsplash.com/s/photos/rocket?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)