複数コンテナ持ちのECSサービス(タスク)のBlue/GreenデプロイをCodeSeriesでやってみた
ECSのBlue/GreenデプロイをCodeSeriesでやってる公式ドキュメントやブログはそれなりに見つかるが、複数コンテナ持ちパターンで分かりやすいモノは見つからなかったので、その備忘録
構成図
手順
前提
ECSのBlue/GreenデプロイをCodeSeriesで実施すること自体は、以下ハンズオン資料と公式チュートリアルを見ればこと足りるので、コンテナが1つパターンの基本的なパイプラインは組めてることが前提の手順とする
1.ビルドプロジェクトでバッチ設定を実施する
設定が必須なのはバッチ用のサービスロールのみ
特に拘りがなければ、環境設定で使ってる既存のIAMロールを設定しとけばOK
バッチ設定のパラメータ詳細は以下参照
2. パイプラインのビルドステージの設定を変更する
ビルドタイプをバッチビルドに設定
「出力アーティファクト」に任意の名前をビルド/デプロイするコンテナの数の分だけ入力
ここで入力した「出力アーティファクト名」は後で利用する為、控えておく
3. パイプラインのデプロイステージの設定を変更する
「入力アーティファクト」と「入力アーティファクトが持つイメージ詳細」に手順2で入力した「出力アーティファクト名」を追加する
「タスク定義のプレースホルダー文字」にコンテナを識別できる任意の文字列を入力する
ここで入力した「タスク定義のプレースホルダー文字」は後で利用する為、控えておく
4. taskdef.jsonを変更する
containerDefinitionsのimageに手順3で入力した「タスク定義のプレースホルダー文字」を入力する
taskdef.jsonの例
{
"containerDefinitions": [
{
"name": "app",
"image": "<IMAGE_NAME_APP>",
"cpu": 0,
"portMappings": [
{
"containerPort": 9000,
"hostPort": 9000,
"protocol": "tcp"
}
],
"essential": true,
"environment": [],
"mountPoints": [
{
"sourceVolume": "app",
"containerPath": "/app/public",
"readOnly": false
}
],
"volumesFrom": [],
"linuxParameters": {
"initProcessEnabled": true
},
"workingDirectory": "/app",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/aws/ecs/hogehoge",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "admin"
}
}
},
{
"name": "nginx",
"image": "<IMAGE_NAME_NGINX>",
"cpu": 0,
~ Snip ~
5. buildspec.ymlを変更する
batchセクションを追加する
バッチビルドタイプによって入力が必要なパラメータに違いがあるので、ここではコンテナを並列でビルドできるbuild-listを選択
build-listセクションに必要なパラメータは以下
- identifier
- 手順2で入力した「出力アーティファクト名」を設定すること
- env
- variables
- REPOSITORY_URI
- ビルドしたコンテナのpush先のレポジトリURLを入力
- DOCKERFILE_PATH
- Dockerfileのパスを入力
- トップディレクトリからの相対パスで入力すること
- Dockerfileのパスを入力
- REPOSITORY_URI
- variables
buildspec.ymlの例
version: 0.2
batch:
build-list:
- identifier: nginx
env:
variables:
REPOSITORY_URI: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/hogehoge/nginx
DOCKERFILE_PATH: ./nginx/Dockerfile
- identifier: app
env:
variables:
REPOSITORY_URI: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/hogehoge/app
DOCKERFILE_PATH: ./app/Dockerfile
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws --version
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $(echo ${CODEBUILD_BUILD_ARN} | cut -f 5 -d :).dkr.ecr.ap-northeast-1.amazonaws.com
- REPOSITORY_URI=${REPOSITORY_URI}
- DOCKERFILE_PATH=${DOCKERFILE_PATH}
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build -f $DOCKERFILE_PATH -t $REPOSITORY_URI:latest .
- docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker images...
- docker push $REPOSITORY_URI:latest
- docker push $REPOSITORY_URI:$IMAGE_TAG
- printf '{"ImageURI":"%s"}' $REPOSITORY_URI:$IMAGE_TAG > imageDetail.json
artifacts:
files: imageDetail.json
batchセクションのパラメータ詳細は以下参照
留意点
どれか一つのコンテナの変更であっても、全てのコンテナのビルド/デプロイが走ります。
※厳密にいうと、ソースに指定してるブランチの変更があれば、そこの変更がどこであれ、全てのコンテナのビルド/デプロイが走る。
Lambda使ってこねくり回すとかCodeSeries辞めるとかしないと、多分どうしようもない
全てのコンテナのビルド/デプロイが走ること自体に大きなデメリットはないので、強い思いがないのであれば、そういうもんと割り切るのが良いと思ってる
Discussion