Table of Contents
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:
- Build and deploy a new docker image to ECR
- Retrieve and update the task definition with the new image tag
- 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 credentials2 uses: aws-actions/configure-aws-credentials@v13 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_TAG12 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 definition2 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 definition10 uses: aws-actions/amazon-ecs-deploy-task-definition@v111 with:12 task-definition: ${{ steps.task-def.outputs.task-definition }}13 service: my-service14 cluster: my-cluster15 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, Medium or Twitter to read more about PHP, Docker and other dev topics.