4
votes

I use codebuild & codepipeline successfully for continuous deployment onto ECS for several projects but have came up with a problem. In this project I need to deploy the same build to four different ECS containers.

The default way I use codebuild and codepipeline CD is as shown in aws docs - I create imagedefinitions.json file at the end of the build process. As far as I can see this file can contain the definition of only one ECS container.

You have to provide the name of the container:

post_build:
commands:
  - echo Build completed on `date`
  - echo Pushing the Docker images...
  - docker push $REPOSITORY_URI:latest
  - docker push $REPOSITORY_URI:$IMAGE_TAG
  - echo Writing image definitions file...
  - printf '[{"name":"hello-world","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json

For this task defintion:

{
"taskDefinition": {
"family": "hello-world",
"containerDefinitions": [
  {
    "name": "hello-world",
    "image": "012345678910.dkr.ecr.us-west-2.amazonaws.com/hello-world:6a57b99",
    "cpu": 100,
    "portMappings": [
      {
        "protocol": "tcp",
        "containerPort": 80,
        "hostPort": 80
      }
    ],
    "memory": 128,
    "essential": true
  }
]

It could work if I change the names of all four containers in the different services to the same name. for example that specific image name. But I can't tell if this is a good idea.

Now I wonder if I can use codepipeline to ECS in this project at all or should I deploy in a different way.

2
why dont you use single ECR repository / single image for the services? - sin
I do use a single ECR image. I'm migrating our CD into aws, so the system is already running, and currently each service that uses that same image has a different name for the container. I'm not sure why shouldn't I just change the name for the container to that image name. - nyoely
actually it doesn't matter if you have same container name under different services. - sin

2 Answers

1
votes

CodeBuild action in codePipeline currently supports only one output artifact. You can zip all the image definition files in to one zip file and add a lambda invoke action to split it in to multiple artifacts and use them in ECS deploy actions.

0
votes

You can construct the file to list multiple container-image pairs in the imagedefinitions.json file like below:

[{
  "name": "simple-app",
  "imageUri": "httpd:2.4"
},
{
  "name": "simple-app",
  "imageUri": "mysql"
},
{
  "name": "simple-app-2",
  "imageUri": "java1.8"
}]

Here is an example of how it is done in my buildspec.yml file:

 post_build:
   commands:
     - docker push $IMAGE1_URI:$IMAGE_TAG
     - docker push $IMAGE2_URI:$IMAGE_TAG
     - printf '[{"name":"conatiner1_name","imageUri":"%s"}, {"name":"container2_name","imageUri":"%s"}]' $IMAGE1_URI:$IMAGE_TAG $IMAGE2_URI:$IMAGE_TAG > imagedefinitions.json

More details here: https://docs.aws.amazon.com/codepipeline/latest/userguide/file-reference.html#pipelines-create-image-definitions