はじめに
前回の記事の続編。
前回は、クロスアカウントで、ビルド環境でビルドしたコンテナイメージをstage環境にコピーする部分だったが、今回の範囲は、それをproduction環境にコピーする部分だ。
前提知識としては、前回のパイプラインを理解できていること。
新しい概念は出てこないので、サクサク書いていく。
プロバイダの設定は前回と同じと考えてほしい。
本来だったらプロバイダを、dev, stage, production とするところを、簡略化するために今回も build_account, service_account としている。
また、ECRのコピー元を一意に特定するためにCommitIDを使っている。
このため、マージコミットはFast Forwardを使うようにする。Non Fast Forwardの場合は別の方法でCommitIDを連携する必要があるため注意が必要だ。
変更点
クロスアカウント設定等は前回と同様に行えばよい。
今回は、差分としてEventBridgeの設定部分を書いておく。
EventBridgeの設定(build_account側)
################################################################################
# EventBridge(Build Account) #
################################################################################
resource "aws_cloudwatch_event_rule" "codecommit_merge_build_account" {
provider = aws.build_account
name = local.event_rule_name
description = "CodeCommit Merge Event Rule"
event_pattern = data.template_file.event_pattern_build_account.rendered
}
resource "aws_cloudwatch_event_target" "event_bus_build_account" {
provider = aws.build_account
rule = aws_cloudwatch_event_rule.codecommit_merge_build_account.name
target_id = local.event_target_id
arn = "arn:aws:events:ap-northeast-1:${data.aws_caller_identity.service_account.account_id}:event-bus/default"
role_arn = aws_iam_role.eventbridge_build_account.arn
}
data "template_file" "event_pattern_build_account" {
template = file("${path.module}/event_pattern_build_account.json")
vars = {
build_account_id = data.aws_caller_identity.build_account.account_id
codecommit_repository_arn = data.aws_codecommit_repository.application.arn
}
}
################################################################################
# IAM Role for EventBridge #
################################################################################
resource "aws_iam_role" "eventbridge_build_account" {
provider = aws.build_account
name = local.eventbridge_iam_role_name
assume_role_policy = data.aws_iam_policy_document.eventbridge_build_account_assume.json
}
data "aws_iam_policy_document" "eventbridge_build_account_assume" {
statement {
effect = "Allow"
actions = [
"sts:AssumeRole",
]
principals {
type = "Service"
identifiers = [
"events.amazonaws.com",
]
}
}
}
resource "aws_iam_role_policy_attachment" "eventbridge_build_account" {
provider = aws.build_account
role = aws_iam_role.eventbridge_build_account.name
policy_arn = aws_iam_policy.eventbridge_build_account_custom.arn
}
resource "aws_iam_policy" "eventbridge_build_account_custom" {
provider = aws.build_account
name = "SendEventToServiceAccountPolicy"
description = "Send Event to Service-Account Policy"
policy = data.aws_iam_policy_document.eventbridge_build_account_custom.json
}
data "aws_iam_policy_document" "eventbridge_build_account_custom" {
version = "2012-10-17"
statement {
effect = "Allow"
actions = [
"events:PutEvents",
]
resources = [
"arn:aws:events:ap-northeast-1:${data.aws_caller_identity.service_account.account_id}:event-bus/default",
]
}
}
{
"detail-type": [
"CodeCommit Repository State Change"
],
"resources": [
"${codecommit_repository_arn}"
],
"detail": {
"referenceType": [
"branch"
],
"event": [
"referenceUpdated"
],
"referenceName": [
"production"
]
},
"source": [
"aws.codecommit"
]
}
EventBridgeの設定(service_account側)
################################################################################
# EventBridge(Service Account) #
################################################################################
resource "aws_cloudwatch_event_rule" "codecommit_merge_service_account" {
provider = aws.service_account
name = local.event_rule_name
description = "CodeCommit Merge Event Rule"
event_pattern = data.template_file.event_pattern_service_account.rendered
}
resource "aws_cloudwatch_event_target" "event_bus_service_account" {
provider = aws.service_account
rule = aws_cloudwatch_event_rule.codecommit_merge_service_account.name
target_id = local.event_target_id
arn = aws_codepipeline.service_account.arn
role_arn = aws_iam_role.eventbridge_service_account.arn
}
data "template_file" "event_pattern_service_account" {
template = file("${path.module}/event_pattern_service_account.json")
vars = {
build_account_id = data.aws_caller_identity.build_account.account_id
codecommit_repository_arn = data.aws_codecommit_repository.application.arn
}
}
################################################################################
# IAM Role for EventBridge #
################################################################################
resource "aws_iam_role" "eventbridge_service_account" {
provider = aws.service_account
name = local.eventbridge_iam_role_name
assume_role_policy = data.aws_iam_policy_document.eventbridge_service_account_assume.json
}
data "aws_iam_policy_document" "eventbridge_service_account_assume" {
statement {
effect = "Allow"
actions = [
"sts:AssumeRole",
]
principals {
type = "Service"
identifiers = [
"events.amazonaws.com",
]
}
}
}
resource "aws_iam_role_policy_attachment" "eventbridge_service_account" {
provider = aws.service_account
role = aws_iam_role.eventbridge_service_account.name
policy_arn = aws_iam_policy.eventbridge_service_account_custom.arn
}
resource "aws_iam_policy" "eventbridge_service_account_custom" {
provider = aws.service_account
name = "StartPipelinePolicy"
description = "Start CodePipeline Policy"
policy = data.aws_iam_policy_document.eventbridge_service_account_custom.json
}
data "aws_iam_policy_document" "eventbridge_service_account_custom" {
version = "2012-10-17"
statement {
effect = "Allow"
actions = [
"codepipeline:StartPipelineExecution",
]
resources = [
"arn:aws:codepipeline:ap-northeast-1:${data.aws_caller_identity.service_account.account_id}:*",
]
}
}
{
"detail-type": [
"CodeCommit Repository State Change"
],
"account": [
"${build_account_id}"
],
"resources": [
"${codecommit_repository_arn}"
],
"detail": {
"referenceType": [
"branch"
],
"event": [
"referenceUpdated"
],
"referenceName": [
"production"
]
},
"source": [
"aws.codecommit"
]
}
ポイント
ポイントになるのはイベントパターンの
"detail": {
"referenceType": [
"branch"
],
"event": [
"referenceUpdated"
],
"referenceName": [
"production"
]
},
の部分で、これによって、productionブランチの更新を拾える。
つまり、productionブランチに対するマージコミットのタイミングでイベント連携され、パイプラインを起動できるということだ。
CodeCommitのイベント連携であるため、CommitIDもちゃんとservice_account側に通知されるので、あとはbuildspec側で
phases:
pre_build:
commands:
(中略)
- IMAGE_TAG=$(echo ${CODEBUILD_RESOLVED_SOURCE_VERSION} | cut -c 1-7)
で CODEBUILD_RESOLVED_SOURCE_VERSION
の環境変数も参照可能になる。