はじめに
あるところにECS上で動いているWebアプリケーション(tomcat環境)がありました。
ソースコードはCodeCommitで管理されているようです。
CICDなるものに興味があった私は、変更がプッシュされたことをトリガーに最終的にECSで実行されているコンテナが置き換わり、変更が反映されるようにしてみよう思いました。
やりたいことのイメージ
- CodeCommitにプッシュでCodePipelineが起動
- CodeBuildでDockerイメージを作成
- DockerイメージをECRリポジトリにプッシュ
- ECRリポジトリのイメージをもとにECSのタスク定義を更新
- 新しいタスク定義を使用しECSクラスターのサービスを更新
- コンテナの置き換えが発生
ファイル群
FROM tomcat:9
COPY ./WebContent /usr/local/tomcat/webapps/myproject
version: '3'
services:
appserver:
build:
context: .
dockerfile: Dockerfile
restart: always
ports:
- 8080:8080
version: 0.2
phases:
pre_build:
commands:
- aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
build:
commands:
- docker-compose build appserver
- docker tag src-appserver $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPOSITORY_NAME:latest
post_build:
commands:
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPOSITORY_NAME:latest
- printf '[{"name":"$ECS_CONTAINER_NAME","imageUri":"%s"}]' $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPOSITORY_NAME:latest > imagedefinitions.json
- |
cat <<EOT > appspec.yml
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: "arn:aws:ecs:$AWS_REGION:$AWS_ACCOUNT_ID:task-definition/$ECS_TASK_NAME"
LoadBalancerInfo:
ContainerName: "$ECS_CONTAINER_NAME"
EOT
artifacts:
files:
- imagedefinitions.json
- appspec.yml
CodePipelineの設定
パイプラインの作成をしていきます。
buildspec.ymlで環境変数を使用しているので、パイプラインレベルで環境変数を定義しておきます。
- AWS_ACCOUNT_ID(アカウントID:12桁の数字)
- AWS_REGION(利用するリージョン)
- ECR_REPOSITORY_NAME(ECRリポジトリの名称)
- ECS_TASK_NAME(ECSタスク定義の名称)
- ECS_CONTAINER_NAME(タスク内で実行されるコンテナの名称)
CodeCommit
ソースプロバイダーにCodeCommitを指定して、トリガーにしたいリポジトリとブランチを選択します。
その他の設定はデフォルトにしておきます。
CodeBuild
ビルドプロジェクトを作成して、CodeBuildで指定します。
基本はデフォルト設定ですが、「buildspecファイルを使用する」を選択しておきます。
また、CodeBuildレベルでも環境変数を設定できるのですが、今回はパイプラインレベルで設定しているのでその値を利用します。
以下のように#{variables.AWS_ACCOUNT_ID}と記述することで、パイプラインレベルの環境変数の値を呼び出せます。
(例)
名前 AWS_ACCOUNT_ID 値 #{variables.AWS_ACCOUNT_ID} タイプ プレーンテキスト
上手く設定できていれば、 実行時にimagedefinitions.jsonとappspec.ymlがBuild Artfactとして作成されます。
CodeDeploy
デプロイプロバイダーに Amazon ECSを指定します。
クラスター名とサービス名を選択し、デプロイ先を決定します。
CodeBuildでプッシュしたDockerイメージとimagedefinitions.jsonでタスク定義を更新し、appspec.ymlでサービスの更新をしています。
さいごに
今回ビルドフェーズではDockerイメージの作成だけを行っています。
コンパイルが必要な場合、別途記述を足して下さい。
また、LoadBalancerの記述も環境によって修正が必要かもしれません。
ご覧いただきありがとうございました。