はじめに
ECSとECRを触れるようになったので、今回はCodeCommit, CodeBuild, CodePipelineを使って、AWSサービスのみでCI/CDパイプラインを構築してみました。
GitHub ActionsによるCI/CDパイプラインの構築については以前記事を書きました。
もし興味があればこちらをご覧ください。
AWSのCI/CD関連サービス
CI(Continuous Integration)では、ソースコードをホスティングサービス(GitHub, Bitbucketなど)にプッシュしたときに、自動でテスト(ビルド)サーバ(GitHub Actions, Jenkins CI, Circle CIなど)でテストを行い、ビルドの成功可否を開発者にフィードバックします。
CIを行うことで早期にバグを発見することができるようになります。
CodeCommitはホスティングサービスの役割、CodeBuildはテストサーバの役割をもつAWSサービスです。
また、CD(Continuous Delivery)はCIを拡張した手法で、ビルドやテストだけでなく、リリースプロセス全体を自動化します。
CDでは、ビルドとテストを実行した後、テスト環境またはステージング環境にデプロイして、システムテストやUIテストを行います。
開発者は、これらのテストが完了した後に、最後のステップとして本番(運用)環境への更新を承認します。
CDを行うことでリリースサイクルを早め、市場からのフィードバックをすぐにソフトウェアへ反映させることができるようになります。
CodeDeployはデプロイを自動化する役割をもつAWSサービスで、ECSのblue/greenデプロイ(古いサーバを残したまま新しいサーバを構築し、一定期間経過後に新しいサーバが安定したのを確認してから古いサーバを消去するデプロイ手法)などに使用します。
CI/CDの流れと使用するサービスをまとめると以下の図のようになります。
CodePipelineでCI/CD全体のステップを管理することができます。
CodeCommit
以下でCodeCommitの操作を学びます。
- CodeCommitにリポジトリを作成し、ローカルにクローンを作成
- GitHubのコードをローカルにプルして、1で作成したクローンにコードを追加
- コードをCodeCommitにプッシュ
実装
CodeCommitを開いて"リポジトリを作成"を選択すると以下の画面になります。
リポジトリ名と説明(任意)を記述すれば作成完了です。
以下の画面になるので、接続のステップを順番に実行していきます。
まず、brew install git
でGitクライアントをインストールします。
次にGit認証情報を作成します。
ログイン中のIAMユーザecs-course
にCodeCommitへのアクセス権限を付加します。
認証情報タブからAWS CodeCommitリポジトリへのHTTPS接続の認証に使用できるユーザー名とパスワードを生成します。
git clone ~
でリポジトリsimplehttp
のクローンをローカルに作成します。
git remote -v
を実行すると、リモートリポジトリがCodeCommitにあることが確認できます。
origin https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/simplehttp (fetch)
origin https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/simplehttp (push)
cd simplehttp
でディレクトリを移動し、git clone https://github.com/gkoenig/go-simplehttp.git /tmp/simplehttp
でGitHubからリポジトリをクローンします。
cp /tmp/simplehttp/Dockerfile /tmp/simplehttp/README.md /tmp/simplehttp/simpleHTTP.go .
でsimplehttp
にファイルをコピーします。
コミットとプッシュを行います。
$ git add .
$ git commit -m 'initial commit'
$ git push
コンソールからsimplehttp
を開くと、正常にプッシュされたことを確認できます。
CodeBuild
以下でCodeBuildの操作を学びます。
- IAMロールの作成
- ビルドプロジェクトの作成
実装
一つの手順が長いので項目をわけます。
IAMロールの作成
CloudWatchLogsやCodeCommitへのアクセスに関するIAMポリシーを新しく作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CloudWatchLogsPolicy",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"*"
]
},
{
"Sid": "CodeCommitPolicy",
"Effect": "Allow",
"Action": [
"codecommit:GitPull"
],
"Resource": [
"*"
]
},
{
"Sid": "S3GetObjectPolicy",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"*"
]
},
{
"Sid": "S3PutObjectPolicy",
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"*"
]
},
{
"Sid": "ECRPullPolicy",
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
],
"Resource": [
"*"
]
},
{
"Sid": "ECRAuthPolicy",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": [
"*"
]
},
{
"Sid": "S3BucketIdentity",
"Effect": "Allow",
"Action": [
"s3:GetBucketAcl",
"s3:GetBucketLocation"
],
"Resource":
"*"
}
]
}
ポリシー名はCodeBuildServiceRolePolicy
とします。
次にIAMロールを作成します。
CodeBuild
というユースケースを選択します。
ロール名はCodeBuildServiceRole
とします。
AmazonElasticContainerRegistryPublicPowerUser
を選択します。
ビルドプロジェクトの作成
CodeBuildの画面からビルドプロジェクトを新しく作成します。
Buildspecの設定の部分でbuildspecファイルを使用する
を選択する場合は、ソースコードのルートディレクトリにbuildspec.yml
が必要となります。
buildspec.yml
には以下のように、buildコマンドを記述します。
<<account-id>>
にはアカウントIDを記述します。
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws --version
- echo $AWS_DEFAULT_REGION
- $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
- REPOSITORY_URI=<<account-id>>.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-simplehttp
- 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 -t $REPOSITORY_URI:latest .
- docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- docker push $REPOSITORY_URI:latest
- docker push $REPOSITORY_URI:$IMAGE_TAG
ビルドプロジェクトを作成できたら、ビルドを開始します。
すべて成功すればOKです。
ECRのリポジトリ画面からもイメージがプッシュされたことを確認できます。
CodePipeline
CodePipelineを使って、CI/CDパイプラインを構築します。
- アーティファクト作成のために
buildspec.yml
を更新 - パイプラインの構築
- CodeCommitリポジトリとの連携
- CodeBuildのビルドプロジェクトとの連携
- デプロイプロバイダとしてECSを設定

実装
ビルドやテストのプロセスをアーティファクトimagedefinitions.json
として出力するために、buildspec.yml
に以下の記述を加えてプッシュします。
- printf '[{"name":"simplehttp-container","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json
CodePipelineから新規のパイプラインを作成します。
ソースコードのリポジトリ(CodeCommit)との連携を設定します。
デプロイプロバイダにAmazon ECS
を選択し、クラスターやサービスは前の記事で作成したものを選択します。
デプロイプロバイダをAmazon ECS
にすることで、リポジトリのコードを変更したとき、パイプラインが新しいDockerイメージを作成してコンテナレジストリにプッシュし、更新されたイメージをECSにデプロイします。
パイプラインを作成すると実行を開始し、以下の画面になれば成功です。
参考資料