【YOLO】③DockerイメージのビルドからECSデプロイまでをパイプライン化する
はじめに
前回までの記事でYOLO12を使用したテストアプリを作成~ECS上でのDockerコンテナ起動まで行いました。
今回は「AWS CodePipeline」を使用してAWS上にCI/CD環境を構築し、今まで手動で行っていたDockerイメージのビルド~ECSへのデプロイを自動化します。
本稿は前回記事の続きですので、テストアプリの作成およびECR、ECSを構築済みの前提で手順記載しております。
不明点あれば前回記事もご参照いただければ幸いです。
本稿では以下の流れでCI/CD環境の構築を実施します。
- CodeBuildのソースプロバイダにGitHubを指定できるように設定
- CodeBuild実行時に必要な
buildspec.yml
ファイルの作成 - DockerイメージをビルドするためにCodeBuildを作成
- CodePipelineを作成し、各ステージに対応するAWSサービスを指定(ソースはGitHubを指定)
- ローカルに作成済みの各種ファイルをGitHubにプッシュ
- プッシュをトリガーにDockerイメージのビルド~ECSへのデプロイが自動で実行されることを確認
GitHubとCodeBuildの連携
今回はGitHubをビルドソースの配置先として使用します。
元々は AWS CodeCommit
を利用していたのですが、 AWS CodeCommit
は2024/7/27時点で新規アカウントでの使用を制限されており、
今後完全撤廃される可能性が高いサービスのため、代替サービスとしてGitHubを採用しました。
GitHubなどの外部サービスをCodeBuildのビルドソースとして使用する場合、当然ながら連携設定を行う必要があります。
簡単に設定できるので先に完了させておきましょう。
マネジメントコンソールの AWS デベロッパー用ツール
画面にて設定できます。
※GitHubアカウントおよびリポジトリ作成済みの前提です
今回、接続名は「yolo12-test-app」としました。
必要なIAMポリシーおよびロールの作成もここで行います。
GitHub連携に必要なポリシーだけでなく、ビルド時に必要な他AWSサービス連携用のポリシーもついでに記述します。
ここで作成するIAMロールは後述のCodeBuild作成時に使用します。
- IAMポリシーの作成(ポリシー名:CodeBuildBasePolicy-yolo12-test)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": "*",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
},
{
"Effect": "Allow",
"Resource": "*",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetBucketAcl",
"s3:GetBucketLocation",
"s3:ListBucket"
]
},
{
"Effect": "Allow",
"Resource": "*",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:CompleteLayerUpload",
"ecr:GetDownloadUrlForLayer",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
]
},
{
"Effect": "Allow",
"Resource": "*",
"Action": [
"codebuild:CreateReportGroup",
"codebuild:CreateReport",
"codebuild:UpdateReport",
"codebuild:BatchPutTestCases",
"codebuild:BatchPutCodeCoverages"
]
},
{
"Effect": "Allow",
"Resource": [
"作成した接続のARN"
],
"Action": [
"codeconnections:GetConnectionToken",
"codeconnections:GetConnection"
]
}
]
}
- IAMロールの作成(ロール名:codebuild-project-service-role-yolo12-test)
上記で作成したIAMポリシーをアタッチしてください。
信頼ポリシーは以下の通り設定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
以上でGitHubの連携設定および必要なIAMロールの作成は完了です。
buildspec.ymlの作成
まず初めに buildspec.yml
の作成から行います。
このファイルは CodeBuild
でのビルド実行時に、「どの環境で実行するか」「どんなコマンドでビルドするか」を指定するファイルです。
具体的には、AWSアカウントIDやDockerコマンドを記述します。
version: 0.2 # Buildspecファイルのバージョン
env:
variables:
AWS_DEFAULT_REGION: ap-northeast-1 # AWSのデフォルトリージョン
AWS_ACCOUNT_ID: アカウントID # AWSアカウントID
IMAGE_REPO_NAME: yolo12-test-ecr # Dockerイメージのリポジトリ名
IMAGE_TAG: latest # Dockerイメージのタグ
phases:
build:
commands:
# ECRにログイン
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
# Dockerイメージをビルド
- docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
# Dockerイメージにタグを付ける
- docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
# DockerイメージをECRにプッシュ
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
# imagedefinitions.jsonファイルを生成
# 「"name":」にはECSのタスク定義で設定したコンテナ名を入れる
- printf '[{"name":"yolo12-test-container","imageUri":"%s"}]' $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json # ビルド成果物としてimagedefinitions.jsonを指定
基本的にはローカルで実行していたDockerコマンドをそのまま転記した形式になります。
しかし1点重要な項目として imagedefinitions.json
の作成 というものがありますので、そちらについて補足説明いたします。
imagedefinitions.json
とはCodePipelineを使用してECSにデプロイを実行する際に参照される定義ファイルのことです。
デプロイ先ECSのコンテナ名と、デプロイ対象とするDockerイメージのイメージURIを指定します。
処理としてはprintf
で上記内容をjsonファイルとして作成し、artifacts:
で後工程で参照可能となるようにビルド成果物に含めてアーティファクトストア(S3)上に保管しています。
必須項目となるため、うっかり記述を忘れないようにしましょう。(自分への戒め)
buildspec.yml
の作成が完了しましたら、アプリのルートディレクトリ直下に保存してください。(GitHub上にプッシュ)
CodeBuildの作成
続いてCodePipelineのビルドステージで使用する CodeBuild
のビルドプロジェクトを作成します。
ビルド環境にはLambdaを使用したかったのですが、LambdaはDcokerイメージのビルドをサポートしていないためEC2を選択しています。
またCodeBuildを指定のVPC内に作成することも可能ですが、そのためにはプライベートサブネットやNATゲートウェイが必要だったりと制約があるため注意が必要です。
今回は特にVPC内のリソースにアクセスする要件が無いため、非VPCで作成します。
設定値(他はデフォルト)
項目名 | 設定値 |
---|---|
プロジェクト名 | yolo12-test-buildproject |
ソースプロバイダ | GitHub |
リポジトリ | GitHubアカウントのリポジトリ |
GitHubリポジトリ | https://github.com/<user-name>/<repository-name> |
プロビジョニングモデル | オンデマンド |
環境イメージ | マネージド型イメージ |
コンピューティング | EC2 |
Running mode | Container |
OS | Amazon Linux |
イメージ | aws/codebuild/amazonlinux-x86_64-standard:5.0 |
サービスロール | 既存のサービスロール |
ロール名 | codebuild-project-service-role-yolo12-test |
特権付与 | 有効 |
ビルド仕様 | buildspecファイルを使用する |
CloudWatch Logs | ビルド時の詳細ログを確認したい場合は有効のままにする |
S3ログ | ビルド時の詳細ログを確認したい場合は有効にする |
CodePipelineの作成
最後に本稿の要である CodePipeline
の作成に着手します。
項目数が多いため、パイプライン作成画面上の「Step」ごとに分割して記載します。
Step1:作成オプションを選択する
設定値(他はデフォルト)
項目名 | 設定値 |
---|---|
作成オプションを選択する | カスタムパイプラインを構築する |
Stp2:パイプラインの設定を選択する
設定値(他はデフォルト)
項目名 | 設定値 |
---|---|
パイプライン名 | yolo12-test-pipeline |
サービスロール | 新しいサービスロール |
ロール名 | yolo12-test-pipeline-role |
Step3:ソースステージを追加する
設定値(他はデフォルト)
項目名 | 設定値 |
---|---|
ソースプロバイダー | GitHub(GitHubアプリ経由) |
接続 | 既存の接続を選択 |
リポジトリ名 | 既存のリポジトリを選択 |
デフォルトブランチ | 既存のブランチを選択 |
ステージ障害時の自動再試行を有効にする | 無効化する |
Step4:ビルドステージを追加する
設定値(他はデフォルト)
項目名 | 設定値 |
---|---|
プロバイダーを構築する | その他のビルドプロバイダー(AWS CodeBuild) |
プロジェクト名 | yolo12-test-buildproject |
ステージ障害時の自動再試行を有効にする | 無効化する |
Step5:テストステージを追加
テストステージの追加に伴い、全体の実行時間増加やそれに伴う追加コストが発生するため、今回テストステージはスキップします。
Step6:デプロイステージを追加する
設定値(他はデフォルト)
項目名 | 設定値 |
---|---|
デプロイプロバイダー | Amazon ECS |
クラスター名 | yolo12-test-cluster |
サービス名 | yolo12-test-service |
イメージ定義ファイル
にはデフォルトで imagedefinitions.json
が設定されるため、空白のままで問題ありません。
Step7:レビュー
確認画面です。
これまでのStepで設定した内容を再確認し、問題がなければ「パイプラインを作成する」を押下してください。
実行確認
前項のStep7でパイプラインを作成する」を押下後、自動でパイプラインが起動します。
まずは初回実行が正常に終了するか確認しましょう。
すべてのステージで緑色のチェック表示となっていれば成功です。
(※画面コピー取得し忘れました・・・)
初回実行が正常終了したことを確認できましたら、次にGitHubへのプッシュをトリガーにしてパイプラインが起動するかを確認しましょう。
ローカルで適当なファイルを変更し、GitHubのmasterブランチにプッシュしてください。
(※例:「upload.html」に<h1>Pipeline test</h1>
を追加)
GitHubへのプッシュを起点にして、自動でパイプラインが実行されることを確認できればOKです!
アプリの動作に問題ないことも確認しておきましょう。
おわりに
今回はGitHub + AWSサービスを利用してCI/CDパイプラインを構築する方法についてご紹介しました。
CI/CD環境の構築をマネジメントコンソール上で行うことで、視覚的に全体の構造や処理の流れを理解しやすかったのではないかと思います。
設定項目や留意事項は多いですが、その分ちゃんと正常終了した際には謎の達成感を得られますね・・・。
次回は今回作成したパイプラインを AWS CDK
を使用してコードベースで再構築してみようと思います。
ここまでお付き合いいただきありがとうございました。
次回もお読みいただけると幸いです。
Discussion