Cloudformation - ECS service. How to manage pipeline-deployed image updates without stack conflicts

200 views Asked by At

I'm attempting to write a CloudFormation template to fully to define all resources required for an ECS service, including...

  • CodeCommit repository for the nodejs code
  • CodePipeline to manage builds
  • ECR Repository
  • ECS Task Definition
  • ECS Service
  • ALB Target Group
  • ALB Listener Rule

I've managed to get all of this working. The stack builds fine. However I'm not sure how to correctly handle updates.

The Container in the Task Defition in the template required an image to be defined. However the actual application image won't exist until after the code is first built by the pipeline.

I had an idea that I might be able to work around this issue, by defining some kind of placeholder image "amazon/amazon-ecs-sample" for example, just to allow the stack to build. This image would be replaced by CodeBuild when the pipeline first runs.

This part also works fine.

The issues occur when I attempt to update the task definition, for example adding environment variables, in the CloudFormation template. When I re-run the stack, it replaces my application image in the container definition, with the original placeholder image from the template.

This is logical enough, as CloudFormation obviously assumes the image in the template is the correct one to use.

I'm just trying to figure out the best way to handle this.

Essentially I'd like to find some way to tell CloudFormation to just use whatever image is defined in the most recent revision of the task definition when creating new revisions, rather than replacing it with the original template property.

Is what I'm trying to do actually possible with pure CloudFormation, or will I need to use a custom resource or something similar?

Ideally I'd like to keep extra stack dependencies to a minimum.

One possibility I had thought of, would be to use a fixed tag for the container definition image, which won't actually exist when the cloudformation stack first builds, but which will exist after the first code-pipeline build.

For example

image: [my_ecr_base_uri]/[my_app_name]:latest

I can then have my pipeline push a new revision with this tag. However, I prefer to define task defition revisions with specific verion tags, like so ...

image: [my_ecr_base_uri]/[my_app_name]:v1.0.1-[git-sha]

... as this makes it very easy to see exactly what version of the application is currently running, and to revert revisions easily if needed.

1

There are 1 answers

0
Jim Mulvey On BEST ANSWER

Your problem is that you're putting too many things into this CloudFormation template. Your template could include the CodeCommit repository and the CodePipeline. But the other things should be outputs from your pipeline. Remember: Your pipeline will have a build and a deploy stage. The build stage can "build" another cloudformation template that is executed in the deploy stage. During this deploy stage, your pipeline will construct the ECS services, tasks, ALB etc...