内容
業務でECS Blue/GreenデプロイのCI/CDパイプライン構築を行った。
ECSの1タスクで複数コンテナを稼働している場合、少し修正が必要だったため、その修正点についてまとめます。
目次
問題点
ECSの1タスクで複数コンテナを稼働している場合、buildspec.yml
内で生成するimageDetail.json
が1つしか出力できない。
ビルドフェーズを分ける必要があると思うが、ただその場合だとパイプラインの時間がかかってしまう。
また、コンテナの数だけimageDetail.jsonを出力する方法も考えられるが、色々試行錯誤してみたがうまくいかなかった。
そのため今回は別の対応で構築できたので、その方法をまとめます。
もっといい方法があるよという場合は、是非コメントで教えて下さい。
対応方法
通常の場合
imageDetail.jsonはタスク定義が参照するECRのDockerイメージURIを最新のものを使えるようにする役割がある。
したがって稼働するコンテナが1つの場合では1つのimageDetail.jsonを出力するだけでよい。
複数コンテナの対応方法
buildspec.yml
でimageDetail.jsonを出力せずに、タスク定義ファイルのテンプレートを用意しておいて、buildspec.ymlの中でsedコマンドを使用してtaskdef.jsonを作成して出力する。
タスク定義ファイルのテンプレートを準備
/codedeploy/
ディレクトリにtaskdef_template.json
を作成。
imageの項目を置き換える文字列にする
{
"taskDefinitionArn": "arn:aws:ecs:***:***:task-definition/sample-task-definition:**",
"containerDefinitions": [
{
"name": "container1",
"image": "<IMAGE_CONTAINER1_NAME>", # ここ
・
・
・
},
{
"name": "container2",
"image": "<IMAGE_CONTAINER2_NAME>", # ここ
・
・
・
},
{
"name": "supervisor",
"image": "<IMAGE_CONTAINER3_NAME>", # ここ
・
・
・
}
],
・
・
・
}
buildspec.yml内で直接ECRリポジトリのDockerイメージURIに置換
sedコマンドを利用して、文字列を置換し、taskdef.json
ファイルに出力。
各変数はCodeBuildの環境変数や、buildspec.yml内で定義した変数を使用している。
post_build:
commands:
・
・
- sed -e "s@<IMAGE_CONTAINER1_NAME>@$REPOSITORY_URI_CONTAINER1:$IMAGE_TAG@" -e "s@<IMAGE_CONTAINER2_NAME>@$REPOSITORY_URI_CONTAINER2:$IMAGE_TAG@" -e "s@<IMAGE_CONTAINER3_NAME>@$REPOSITORY_URI_CONTAINER3:$IMAGE_TAG@" codedeploy/taskdef_template.json > taskdef.json
・
・
作成したtaskdef.jsonをアーティファクトとして出力
artifacts:
files:
- appspec.yml
- taskdef.json
CodePipelineのデプロイフェーズを編集
CodePipelineデプロイフェーズの「タスク定義の動的な更新イメージ」で、通常では「入力アーティファクト」と「タスク定義のプレースホルダー文字」の項目を設定しているが、削除する。
以上の操作により、ECRのイメージURIを直接記述したtaskdef.jsonをappspec.ymlが参照できるので、複数コンテナの場合でもデプロイを完了することができる。
以上。