Table of Contents
TerraformでAWS CodePipeline(ECR pushで発火) + CodeBuildを作る
AWS CodePipeline記事を探してみるとGithub pushで発火はいろいろありますが、ECR pushで発火はあまりありませんでした。ですから書いて見ました。
結論
- CodePipelineのCodeBuildのbuildspec.ymlをS3を置く場合は
versioning
をenabled
することが必須です ECRで変更を検知してCodePipelineに知らせるCloudWatchイベントルールが必須
を認識することが大事- AWSコンソール上でポチポチでECRをsourceにするCodePipelineを作ると
自動
で作られてしまって認識が難しかった - 参考資料です
- AWSコンソール上でポチポチでECRをsourceにするCodePipelineを作ると
...
コンソールを使用してパイプラインを作成または編集すると、CodePipeline は、リポジトリで変更が生じた場合にパイプラインを開始する CloudWatch イベントルールを作成します。
...
https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/action-reference-ECR.html から
- docker imageをbuildするところのCPUアーキテクチャーが問題になりますから、注意が必要です
- MAC(M1)でdocker imageをbuildしてECRにpushしたら、AWS上でdocker imageが使われる時エラーになる可能性があります
- buildしたところのCPUアーキテクチャーと使われるところのCPUアーキテクチャーが違うと動けません
- 筆者はWindowsユーザーです
構成
ディレクトリ紹介
- Terraformスクリプトがいる
./terraform
- CodeBuildで必要なファイルを集めた
./codebuild
ファイル紹介
GitHubに全体コード公開してます。
https://github.com/fusic/tb_pipeline_source_ecr
./terraform/provider.tf
Terraformのproviderのまとめです。
./terraform/variables.tf
Terraformで全体的に使いたい変数を定義しました。
./terraform/main.tf
./modules
で定義されたAWSリソースたちを束ねるところです。
./terraform/modules/cw_events/main.tf
- ECRにpushしたらCodePipelineに知らせるCloudWatchイベントルールです。
- この設定がないとECRにpushしてもCodePipelineで何も起こりません。
./terraform/modules/cd_pipeline/main.tf
Source
で名付けたstage
のaction
にCodePipelineを発火するECRのリポジトリ名とタグ名を設定しました。Source
で名付けたstage
のaction
にCodeBuildのbuildspec.ymlがあるS3を設定しました。CodeBuildのbuildspec.yml担当S3がCodePipelineで管理されるようにしてますが、CodePipelineから外してCodeBuild単独でbuildspec.yml担当S3を参照する形にしても問題ないと思います。
resource "aws_codepipeline" "main" {
name = var.app_name
role_arn = var.iam_role_codepipeline_arn
artifact_store {
type = "S3"
location = var.s3_pipeline_artifact_id
}
stage {
name = "Source"
action {
name = "Source"
category = "Source"
owner = "AWS"
provider = "ECR"
version = "1"
run_order = 1
output_artifacts = ["ecr_source"]
configuration = {
RepositoryName = var.ecr_web_name
ImageTag = var.app_env # stgとかprdとか
}
}
# https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-S3.html
action {
category = "Source"
configuration = {
"PollForSourceChanges" = "false"
"S3Bucket" = var.buildspec_bucket_name
"S3ObjectKey" = "build.zip"
}
name = "s3_source"
output_artifacts = ["s3_source"]
owner = "AWS"
provider = "S3"
run_order = 1
version = "1"
}
}
stage {
name = "Build"
action {
name = "Build"
category = "Build"
owner = "AWS"
provider = "CodeBuild"
version = "1"
run_order = 2
input_artifacts = ["s3_source"]
configuration = {
ProjectName = var.app_name
}
}
}
}
./terraform/modules/cdb/main.tf
logs_config
は少なくとも1つENABLED
することをお勧めします。しないとAWSコンソール上でもCodeBuildで何が起こっているか見えないからです。- CodeBuildの
image
は慎重に選んでください。OSバージョンが違います。またプログラミング言語のマイナーバージョン情報はGithubのDockerfileでしか確認できません。- (2021年 12月 2日基準)例えば https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/available-runtimes.html にはrubyは2.7まで表記されてます。ですが https://github.com/aws/aws-codebuild-docker-images/blob/master/ubuntu/standard/5.0/Dockerfile#L220 からは 2.7.2が採用されたことが分かります。
./terraform/modules/cw_events/event_pattern.tpl
CodePipelineにECRがpushされたことを知らせることが大事です。 検知したいdocker imageのtagを指定できます。
{
"source": [
"aws.ecr"
],
"detail": {
"action-type": [
"PUSH"
],
"image-tag": [
"prd"
],
"repository-name": [
"${repository_name}"
],
"result": [
"SUCCESS"
]
},
"detail-type": [
"ECR Image Action"
]
}
./terraform/modules/cw_logs/main.tf
CodeBuildで使うログです。ないとAWSコンソール上でもCodeBuildのログが見れません。作ることをお勧めします。
./terraform/modules/ecr/main.tf
docker imageをpushするECRを作ります。
./terraform/modules/iam 配下
もろもろ必要なIAM RoleやIAM Policyを作ります。
./terraform/modules/s3/main.tf
CodePipelineのCodeBuildのbuildspec.ymlをS3を置く場合は versioning
を enabled
することが必須です。
...
resource "aws_s3_bucket" "codebuild_buildspec" {
bucket = "${var.app_name}-codebuild-buildspec"
acl = "private"
force_destroy = true
# codepipelineの正確な参照のために必要
versioning {
enabled = true
}
}
./codebuild/buildspec.yml
- CodeBuildでどうように動くかを定義するファイルです。
- S3にbuildspec.ymlをzipで配置する必要があります。
- プログラミング言語のバージョンのマイナーバージョン設定は公式的には不可能です。ですが選んだCodeBuildのimageのDockerfileを参考して応用する余地はあります
./codebuild/update_codebuild_files.sh
buildspec.ymlをzipにしてS3にアップロードするコマンドのまとめです。
./deploy_by_pushing_docker.sh
ECRにログインする、docker imageをbuildする、ECRにpushするコマンドのまとめです。
実行前に設定する変数がありますが、下の exportでshellで使う環境変数を設定する
で説明します。
#!/bin/bash
ECR_REPO=$AWS_SP_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com
# ECRログイン
aws ecr get-login-password \
--region ap-northeast-1 \
--profile $AWS_SP_PROFILE_NAME \
| docker login \
--username AWS \
--password-stdin $ECR_REPO
#### ruby(web) docker image
WEB_CONTAINER_NAME=src-ecr
ECR_WEB_URI=$ECR_REPO/$AWS_SP_APP_NAME:$AWS_SP_APP_ENV
docker build -t $ECR_WEB_URI . -f ./docker/production/Dockerfile
docker push $ECR_WEB_URI
実行手順
aws profile設定します
profile名は src-ecr-prd
にしてください。terraformで参照してます。
AWS Access Key ID
と AWS Secret Access Key
は保有しているものを入力してください。
aws configure --profile src-ecr-prd
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: ap-northeast-1
Default output format [None]:
terraformを実行
APP_ROOT/terraform
terraform init
terraform apply
exportでshellで使う環境変数を設定する
AWSコンソール上でアカウントIDを確認してから下の AWS_SP_ACCOUNT_ID
に設定してください。
export AWS_SP_PROFILE_NAME=src-ecr-prd
export AWS_SP_ACCOUNT_ID=xxxxx
export AWS_SP_APP_NAME=src-ecr-prd
export AWS_SP_APP_ENV=prd
Codebuild用buildspecとCodedeploy用ファイルをzipでアップロード
cd APP_ROOT/codebuild
sh update_codebuild_files.sh
ECRへdocker imageたちをbuildしてpushする
cd APP_ROOT
sh deploy_by_pushing_docker.sh
Choi Jiho
Company : Fusic CO., LTD Program Language : PHP, Go, Ruby