AWS ECSで自動デプロイを組んでみる
概要
GitHub にコードをプッシュしたら、自動的に ECS までデプロイできる環境を作ってみます。
参考ページ(公式ドキュメント)
前提
ECR、ECS 環境は構築済みとします。以下を参考にしていただければと思います。
手順
ローカル環境にソースコードと Docker ファイルを用意する
次のようなフォルダ構成で作成します。
.
├ src
│ └ index.html
├ Dockerfile
└ buildspec.yml
<h1>AutoDeployTest!</h1>
FROM 'nginx:latest'
RUN service nginx start
COPY src /usr/share/nginx/html
VOLUME /usr/share/nginx/html
version: 0.2
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 <aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com
- REPOSITORY_URI=<aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/samplerepo
- 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`
- echo Pushing the Docker images...
- docker push $REPOSITORY_URI:latest
- docker push $REPOSITORY_URI:$IMAGE_TAG
- echo Writing image definitions file...
- printf '[{"name":"container01","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json
※<aws_account_id>
部分には AWS アカウント ID を設定します。リージョンが違う場合はそこも変更します。
※REPOSITORY_URI
は ECR のリポジトリの URI を設定します。
※container01
の部分は、Docker イメージを参照するサービスのタスク定義のコンテナ名とします。
参考情報
buildspec.yml
のcommands
のところで、リポジトリ URI を、REPOSITORY_URI=<aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/samplerepo
で直接指定していますが、コミットされたブランチによって、デプロイ先環境を切り替えるような Pipeline を組む場合、本記載を行ごと削除して、CodePipeline 側の環境変数(CodeDeploy 側の環境変数ではない)でREPOSITORY_URI
を定義することで、Pipeline 単位で使用するリポジトリを切り替えることができます。
またimagedefinitions.json
に対して受け渡しているコンテナ名"name":"container01"
についても、printf '[{"name":"%s","imageUri":"%s"}]' $CONTAINER_NAME $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
のように書き換え、CodePipeline 側の環境変数CONTAINER_NAME
を定義して引き渡すようにすることで、動的に切り替えができます。
注意
ビルドプロセスの中で、docker Hub からイメージを PULL している場合、IP アドレス単位で時間当たりの PULL 数が制限されており、AWS の CodeBuild の IP アドレスが共有であるために、Limit に引っかかり PULL できない場合があります。その場合、CodeBuild で認証するプロセスを組み込む必要があります。
以下に対応方法を記載しましたので、参考にしてください。
GitHub リポジトリの作成
GitHub にてリポジトリを作成しておきます。
例:リポジトリ名:ecsautodeploytest
ローカルリポジトリの作成~初回プッシュ
ローカル環境で Git リポジトリを初期化して Remote に追加しておきます。
git init
git add .
git commit -m "My first commit"
git branch -M main
git remote add origin https://github.com/[ユーザ名]/ecsautodeploytest.git
git push -u origin main
※GitHub リポジトリ URL は作成したリポジトリを設定してください。
※GitHub のユーザ名、E-mail、Personal Access Token などは必要に応じて設定します。
CodePipeline の設定を行う
- AWS コンソールから
CodePileline
を選択します。 -
パイプラインを作成する
を押下します。 - 任意の
パイプライン名
を設定します。(例:ecsAutoDeployPipeline
) -
サービスロール
は自動設定されるのでそのままにします。 -
次に
を押下します。 - ソースプロバイダーとして
GitHub(バージョン2)
を選択します。 -
接続する
を押下し、任意の接続名
を設定します。(例:GitHubConnection
) - 接続を行い、GitHub 側の画面で認可を行います。
-
新しいアプリをインストールする
を選択し、連携対象のリポジトリを選択します。 -
接続
ボタンを押下します。 -
リポジトリ名
から、対象のリポジトリを選択します。(既に接続済みのものから選択できます) -
ブランチ名
から、main
を選択します。 -
出力アーティファクト形式
はCodePipeline のデフォルト
を選択します。 -
ビルドステージを追加する
で、AWS CodeBuild
を選択し、プロジェクトを作成する
を押下します。-
プロジェクト名
に任意の名前を設定します。(例:ecsAutoDeployBuild
) -
環境イメージ
はマネージド型イメージ
を選択します。 -
オペレーティングシステム
はAmazon Linux2
を選択します。 -
ランタイム
はStandard
を選択します。 -
イメージ
はaws/codebuild/amazonlinux2-x86_64-standard:3.0
を選択します。 -
イメージのバージョン
と環境タイプ
はそのままにします。 -
特権付与
にチェックを入れます。 -
CloudWatch logs
の設定を行います。(必要に応じて、CloudWatch 側でロググループを作成しておきます。ログストリームは任意の名前を設定しておくと自動的に生成されます。ビルドエラーでの調査時に詳細ログを見るためにログが必要になるので、設定して置いた方が良いです。) -
CodePipeline に進む
を押下します。
-
-
次に
を押下します。 -
デプロイステージを追加する
ページで、デプロイプロバイダ
をAmazon ECS
に設定します。 -
クラスター名
でサービスを実行するクラスタを選択します。(既に構築済みである前提とします) -
サービス名
で更新するサービスを選択します。 -
次に
を押下します。 - 確認画面で、内容を確認し、
パイプラインを作成する
を押下します。
Amazon ECR 権限を CodeBuild ロールに追加する
- AWS コンソールで
IAM
からロール
を選択します。 - 検索ボックスに
codebuild-
と入力し、CodePipeline ウィザードによって作成されたロールを選択します。 -
許可ポリシー
からアクセス許可の追加
を押下し、ポリシーをアタッチ
を選択します。 -
AmazonEC2ContainerRegistryPowerUser
を選択し、ポリシーをアタッチ
を押下します。
動作確認
ソースを一部変更してコミットします。
CodePipeline の画面を開き、デプロイ状況をウォッチします。
ECS に反映されサービスが更新されれば成功です。
所感
ECS 構築は細かい設定値が多くて大変でしたが、そこまで作ってしまえば、割と手順通りに素直に設定するとスムーズに構築できます。
Discussion