amazon-ecsaws-code-deployaws-codepipeline

Why does CodePipeline require an `imagedefinitions.json` when ECS task definitions already have this?


OK, so I have a CodePipeline which does a very vanilla

CodeCommit -> Build Docker images -> CodeDeploy to ECS

In the buildspec.yml file, AWS requires outputting imagedefinitions.json as an artifact that CodePipeline can use for mapping the container name to the ECR image URL.

Here's the oft-cited example for how to do this in your buildspec.yml:

printf '[{"name":"MyService","imageUri":"%s"}]' $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/myservice/app:latest > imagedefinitions.json

But this seems totally redundant to me. In an ECS task definition, we can have the following under our containerDefinitions:

"containerDefinitions": [
    {
      "name": "MyService",
      "image": "123456789.dkr.ecr.us-east-1.amazonaws.com/myservice/app:latest"
     }, 
     ...
]

Why, in order to use CodePipeline to CodeDeploy an ECS task, do we have to provide information already specified in the ECS task definition? It would be so much cleaner to remove the need for an artifact (and the S3 bucket to store said artifact) here!

Perhaps there are some fundamentals of CodeDeploy/ECS I do not understand.


Solution

  • You have a good point, however using ":latest" in production systems to identify/retrieve images is usually not a good idea mainly because the tag is not deterministic and can result in surprises. There are many articles on the internet that discuss this anti-pattern, e.g. [1].

    To answer your question, the idea for the "imagedefinitions.json" is to identify the updated image for a container in the task definition. It was not intended to be using ':latest' tag all the time.

    [1] https://vsupalov.com/docker-latest-tag/