Reputation: 73
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.
Upvotes: 7
Views: 2640
Reputation: 2284
We are running CodeBuild as an action under CodePipeline.
Here's an example for running two different ECS service tasks on the same ECR image:
phases:
install: ...
pre_build: ...
build: ...
post_build:
commands:
- ...
- printf '[{"name":"web","imageUri":"%s"}]' $ECR_REPOSITORY_URL:$LATEST_VERSION > web_image_definitions.json
- printf '[{"name":"worker","imageUri":"%s"}]' $ECR_REPOSITORY_URL:$LATEST_VERSION > worker_image_definitions.json
artifacts:
files:
- web_image_definitions.json
- worker_image_definitions.json
Now in your CodePipeline action for the build action you wanna set Output artifacts
to be named e.g. BuildOutput
.
Next create two Deploy actions (one for each ECS service) and for the respective deployment actions you wanna ensure to set Input artifacts
to BuildOutput
and set Image definitions file - optional
to respectively web_image_definitions.json
and worker_image_definitions.json
for each deploy action.
Upvotes: 2
Reputation: 2476
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
Upvotes: 1
Reputation: 106
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.
Upvotes: 1