16

I know that there are already countless questions in this direction, but unfortunately I was not able to find the right answer yet. If a post already exists, please just share the link here.

I have several gitlab CI / CD pipelines. The first pipeline uses Terraform to build the complete infrastructure for an ECS cluster based on Fargate. The second / third pipeline creates nightly builds of the frontend and the backend and pushes the Docker Image with the tag "latest" into the ECR of the (staging) AWS account.

What I now want to achieve is that the corresponding ECS tasks are redeloyed so that the latest Docker images are used. I actually thought that there is a way to do this via CloudWatch Events or whatsoever, but I don't find a really good starting point here. A workaround would be to install the AWS CLI in the CI / CD pipeline and then do a service update with "force new deployment". But that doesn't seem very elegant to me. Is there any better way here?

Conditions:

  • The solution must be fully automated (either in AWS or in gitlab CI / CD)
  • Switching to AWS CodePipeline is out of discussion
  • Ideally as close as possible to AWS standards. I would like to avoid extensive lambda functions that perform numerous actions due to their maintainability.

Thanks a lot!

Stefan
  • 1,253
  • 2
  • 12
  • 36

5 Answers5

27

Ok, for everybody who is interested in an answer. I solved it that way: I execute the following AWS CLI command in the CICD pipeline

aws ecs update-service --cluster <<cluster-name>> --service <<service-name>> --force-new-deployment --region <<region>>

Not the solution I was looking for but it works.

Stefan
  • 1,253
  • 2
  • 12
  • 36
  • `--force-new-deployment` won't pull newer image if they have the same tag – XPX-Gloom Aug 15 '20 at 16:57
  • 11
    Nice downvote. It is working now. So, what should I say? [AWS CLI documentation](https://docs.aws.amazon.com/cli/latest/reference/ecs/update-service.html) says: If your updated Docker image uses the same tag as what is in the existing task definition for your service (for example, my_image:latest ), you do not need to create a new revision of your task definition. You can update the service using the forceNewDeployment option. The new tasks launched by the deployment pull the current image/tag combination from your repository when they start. – Stefan Aug 31 '20 at 17:45
  • 1
    It works, however it's important to note that using the latest tag for deploying images is an anti-pattern. E.g.: if the new image is faulty the rollback is not possible because the tag is the same ('latest') – Lau Apr 22 '21 at 10:49
  • 2
    Yes, you are right. That is the reason why it is not supported out of the box. But sometimes you need it anyway. :) – Stefan Apr 23 '21 at 14:39
  • Also looking for a solution for this. Pretty weird AWS does not provide an easy trigger for this. "Restart fargate task X when new image in ECR" . Would be far more secure if we didn't need to provide credentials to CircleCI. – Joeri Jan 17 '23 at 08:34
2

As a general comment it is not recommended to always push the same container tag because then rolling back to a previous version in case of failure becomes really difficult.

One suitable option would be to use git tags. Let's say you are deploying version v0.0.1 You can create a file app-version.tf which will contain the variable backend-version = v0.0.1 that you can reference on the task definition of the ecs service. Same thing can be done for the container creation using git describe.

So, you get a new task definition for every git tag and the possibility of rolling back just by changing a value in the terraform configuration.

jackops
  • 776
  • 5
  • 15
  • 1
    Yes, I am aware of this. The idea is, that all dev-branches can be deployed with an image tag `dev-123`. This branches can be in any state. But as soon as it is merged into the master, its a shippable increment and passed all test cases etc. The master can but dont have to be the next version. Therefore it will get the latest tag for the staging system. Only if the current master is tagged with an version tag, e. g. v.0.2.4 it will be tagged with a specific version and will automatically be deployed to prod (instead) of stage. I dont want to manage a version for each nightly. – Stefan Feb 21 '20 at 14:24
  • @jackops Although you are not wrong, you are not providing an answer to the question. The question is: How do I get the latest image online when pushing an image into ECR. And why doesn't AWS have a simple automated solution for this, remove the sysops. – Joeri Jan 17 '23 at 08:33
1

It is beneficial to refer to images using either digests or unique immutable tags. After the pipeline pushes the image, it could:

  1. Grab the image's digest/unique tag
  2. Create a new revision of the task definition
  3. Trigger an ECS deployment with the new task definition.

As sgramo93 mentions, the big benefit is that rolling back your application can be done by deploying an older revision of the task definition.

Richard Nguyen
  • 1,203
  • 8
  • 18
0

You could force a redeployment using the "Force new deployment" option while updating the ECS service: enter image description here

0

The popular vote was close. update-service includes a --task-definition option. Running the command with this option and the name of the revision, including the colon notation "...01:2" will launch a new service with the changes and decommission the old service.

aws ecs update-service --region <> --cluster <> --service <> --task-definition <> --force-new-deployment