SourceにECRをしたものを設定する機会があったので書いておきます。
SourceにGitHubを指定しているサンプルはよく見かけますが、ECRを指定しているものはあまりなかったので参考になれば。
CodePipeline
resource "aws_codepipeline" "example" { name = "example" role_arn = aws_iam_role.codepipeline.arn artifact_store { location = aws_s3_bucket.artifact.bucket type = "S3" } stage { name = "Source" action { name = "Source" category = "Source" owner = "AWS" provider = "ECR" version = "1" output_artifacts = ["source"] configuration = { RepositoryName = "example" ImageTag = "stage" } } } stage { name = "Build" action { name = "Build" category = "Build" owner = "AWS" provider = "CodeBuild" version = "1" input_artifacts = ["source"] output_artifacts = ["build"] configuration = { ProjectName = aws_codebuild_project.example.id } } } stage { name = "Deploy" action { name = "Deploy" category = "Deploy" owner = "AWS" provider = "ECS" input_artifacts = ["build"] version = "1" configuration = { ClusterName = aws_ecs_cluster.example.arn ServiceName = aws_ecs_service.ecample.name FileName = "imagedefinitions.json" } } } }
Sourceの部分は provider = "ECR"
を設定して、configurationにトリガーしたいECRのリポジトリ名、イメージタグ名を設定します。(ImageTagはオプショナル)
ここでは example
リポジトリの stage
タグのプッシュをトリガーにする設定をしています。
buildspec.yml
version: 0.2 phases: install: runtime-versions: python: 3.7 build: commands: - echo Build started on `date` - REPOSITORY_URI=$(cat imageDetail.json | python -c "import sys, json; print(json.load(sys.stdin)['ImageURI'].split('@')[0])") - IMAGE_TAG=$(cat imageDetail.json | python -c "import sys, json; print(json.load(sys.stdin)['ImageTags'][0])") - echo $REPOSITORY_URI:$IMAGE_TAG post_build: commands: - echo Build completed on `date` - echo Writing image definitions file... - printf '[{"name":"web","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json artifacts: files: imagedefinitions.json
output として imageDetail.json が生成されるので、そこから imagedefinitions.json を作成します。
ECS Blue/Greenデプロイを選択する場合は、imageDetail.json そのままで大丈夫かと思いますが、今回は標準デプロイを選択したので imagedefinitions.json を作成しています。
これで設定完了!ECRにプッシュすればCodePipelineが起動する!
と思ったのですが、Terraform等から作成する場合はCloudWatch Events等は自前で用意しなきゃいけないんですね...(マネージメントコンソールから作成すれば勝手に作ってくれる)
CloudWatch Events & CloudTrail
data "aws_iam_policy_document" "cloudwatch_events" { statement { effect = "Allow" resources = ["*"] actions = [ "codepipeline:StartPipelineExecution" ] } } data "aws_iam_policy_document" "cloudwatch_events_assume_role" { statement { actions = ["sts:AssumeRole"] principals { type = "Service" identifiers = ["events.amazonaws.com"] } } } resource "aws_iam_role" "cloudwatch_events" { name = "codepipeline-cloudwatch-events" assume_role_policy = data.aws_iam_policy_document.cloudwatch_events_assume_role.json } resource "aws_iam_policy" "cloudwatch_events" { name = "codepipeline-cloudwatch-events" policy = data.aws_iam_policy_document.cloudwatch_events.json } resource "aws_iam_role_policy_attachment" "cloudwatch_events" { role = aws_iam_role.cloudwatch_events.name policy_arn = aws_iam_policy.cloudwatch_events.arn } resource "aws_cloudwatch_event_rule" "ecr" { name = "codepipeline-ecr-event-rule" description = "Amazon CloudWatch Events rule to automatically start your pipeline when a change occurs in the Amazon ECR image tag." event_pattern = <<-JSON { "source": [ "aws.ecr" ], "detail-type": [ "AWS API Call via CloudTrail" ], "detail": { "eventSource": [ "ecr.amazonaws.com" ], "eventName": [ "PutImage" ], "requestParameters": { "repositoryName": [ "example" ], "imageTag": [ "stage" ] } } } JSON depends_on = ["aws_codepipeline.example"] } resource "aws_cloudwatch_event_target" "ecr" { rule = aws_cloudwatch_event_rule.ecr.name target_id = aws_cloudwatch_event_rule.ecr.name arn = aws_codepipeline.example.arn role_arn = aws_iam_role.cloudwatch_events.arn }
data "aws_caller_identity" "current" {} resource "aws_cloudtrail" "example" { name = "example" s3_bucket_name = aws_s3_bucket.example.id event_selector { read_write_type = "All" include_management_events = true data_resource { type = "AWS::S3::Object" values = ["arn:aws:s3:::"] } } } resource "aws_s3_bucket" "example" { bucket = "cloudtrail" acl = "private" policy = <<-POLICY { "Version": "2012-10-17", "Statement": [ { "Sid": "AWSCloudTrailAclCheck", "Effect": "Allow", "Principal": { "Service": "cloudtrail.amazonaws.com" }, "Action": "s3:GetBucketAcl", "Resource": "arn:aws:s3:::cloudtrail" }, { "Sid": "AWSCloudTrailWrite", "Effect": "Allow", "Principal": { "Service": "cloudtrail.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::cloudtrail/AWSLogs/${data.aws_caller_identity.current.account_id}/*", "Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } } } ] } POLICY }
CloudWatch Events の設定だけではうまくいかなくて、↓を参考に CloudTrail も設定したらうまくいきました!
https://forums.aws.amazon.com/thread.jspa?threadID=306306&tstart=0
今後もしかしたら CloudWatch Events の作成までしてくれる可能性もあるかも?
CodePipelineのことは書いてないですが、この本かなり良かったです!

Terraform - Up & Running: Writing Infrastructure As Code
- 作者: Yevgeniy Brikman
- 出版社/メーカー: Oreilly & Associates Inc
- 発売日: 2019/09/30
- メディア: ペーパーバック
- この商品を含むブログを見る
Second Edition は v0.12 に対応していて、まだ 発売前 ですが O'Reilly の Safari Books Online では読めます!
自分も Safari Books Online で読んだのですが、 Free Trial の 10日で読める分量だと思うのでもし興味があれば是非!