この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
「TerraformでCodePipelineを作ったが、ファイルの変更してもCodepipelineがトリガー(発火)してくれない」
TerraformでCodeCommitをソースとしたCodePipelineを作っていました。
コンソールからパイプラインの作成はできて、手動トリガーでの実行もできたのですがCodeCommitのファイル変更時にCodePipelineが発火してくれないことがありました。
結論から書くと、CodePipeline用のEventBridgeの定義の作成が漏れていました。 (マネジメントコンソール上からCodePipelineを作ると自動的に作成されます。)
少しはまったので、サンプルコードを含めてブログにします。
事象・原因
以下のようにCodepipelineを作成していました。 しかし、Codecommitでファイルを変更してもパイプラインが動きません。
codepipeline.tf
resource "aws_codepipeline" "sample_app" {
name = local.name_prefix
role_arn = aws_iam_role.codepipeline.arn
artifact_store {
location = aws_s3_bucket.codepipeline_artifact.bucket
type = "S3"
}
stage {
name = "Source"
action {
name = "Source"
category = "Source"
owner = "AWS"
provider = "CodeCommit"
version = 1
output_artifacts = ["source_output"]
configuration = {
RepositoryName = aws_codecommit_repository.sample_app.repository_name
BranchName = "main"
OutputArtifactFormat = "CODE_ZIP"
}
}
}
stage {
name = "Build"
action {
name = "Build"
category = "Build"
owner = "AWS"
provider = "CodeBuild"
version = 1
input_artifacts = ["source_output"]
output_artifacts = ["build_output"]
configuration = {
ProjectName = aws_codebuild_project.sample_app.id
}
}
}
stage {
name = "Deploy"
action {
name = "Deploy"
category = "Deploy"
owner = "AWS"
provider = "ECS"
version = 1
input_artifacts = ["build_output"]
configuration = {
ClusterName = aws_ecs_cluster.this.id
ServiceName = aws_ecs_service.sample_app.name
}
}
}
}
マネジメントコンソールからソースアクションを見てみると、検出オプション「Amazon CloudWatch Events(推奨)」となっています。
この検出オプションでは、CodeCommitの変更イベントをEventBridge Rule(CloudWatch Events)で検出して、CodePipelineをターゲットにイベント送信を行います。 CodePipelineでは、イベントを受け取ってパイプラインの実行を開始します。
ここで、EventBridge Rule(CloudWatch Events)を作っていないことに気づきました。
ちなみに、マネジメントコンソールから手動でCodePipeline作成する場合、EventBridge Ruleは自動で生成されます。
解決策
EventBridge Ruleを追加します。
Terraform修正
マネジメントコンソールから作成時に自動で生成されるリソースを参考に、Terraform書いてみました。
codepipeline.tf
resource "aws_codepipeline" "sample_app" {
name = local.name_prefix
role_arn = aws_iam_role.codepipeline.arn
artifact_store {
location = aws_s3_bucket.codepipeline_artifact.bucket
type = "S3"
}
stage {
name = "Source"
action {
name = "Source"
category = "Source"
owner = "AWS"
provider = "CodeCommit"
version = 1
output_artifacts = ["source_output"]
configuration = {
RepositoryName = aws_codecommit_repository.sample_app.repository_name
BranchName = "main"
OutputArtifactFormat = "CODE_ZIP"
}
}
}
stage {
name = "Build"
action {
name = "Build"
category = "Build"
owner = "AWS"
provider = "CodeBuild"
version = 1
input_artifacts = ["source_output"]
output_artifacts = ["build_output"]
configuration = {
ProjectName = aws_codebuild_project.sample_app.id
}
}
}
stage {
name = "Deploy"
action {
name = "Deploy"
category = "Deploy"
owner = "AWS"
provider = "ECS"
version = 1
input_artifacts = ["build_output"]
configuration = {
ClusterName = aws_ecs_cluster.this.id
ServiceName = aws_ecs_service.sample_app.name
}
}
}
}
# cloudwatch event rule
resource "aws_cloudwatch_event_rule" "codepipeline_sample_app" {
name = "${local.name_prefix}-codepipeline-sample-app"
event_pattern = templatefile("./file/codepipeline_event_pattern.json", {
codecommit_arn : aws_codecommit_repository.sample_app.arn
})
}
resource "aws_cloudwatch_event_target" "codepipeline_sample_app" {
rule = aws_cloudwatch_event_rule.codepipeline_sample_app.name
arn = aws_codepipeline.sample_app.arn
role_arn = aws_iam_role.event_bridge_codepipeline.arn
}
iam.tf
resource "aws_iam_role" "event_bridge_codepipeline" {
name = "${local.name_prefix}-event-bridge-codepipeline-role"
assume_role_policy = data.aws_iam_policy_document.event_bridge_assume_role.json
inline_policy {
name = "codepipeline"
policy = data.aws_iam_policy_document.event_bridge_codepipeline.json
}
}
data "aws_iam_policy_document" "event_bridge_assume_role" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["events.amazonaws.com"]
}
}
}
data "aws_iam_policy_document" "event_bridge_codepipeline" {
statement {
actions = ["codepipeline:StartPipelineExecution"]
resources = ["${aws_codepipeline.sample_app.arn}"]
}
}
file/codepipeline_event_pattern.json
{
"source": ["aws.codecommit"],
"detail-type": ["CodeCommit Repository State Change"],
"resources": ["${codecommit_arn}"],
"detail": {
"event": ["referenceCreated", "referenceUpdated"],
"referenceType": ["branch"],
"referenceName": ["main"]
}
}
動作確認
上記をapply後CodeCommitに変更をコミットしたところ、CodePipelineが起動することを確認できました。
おわりに
似たような事象が発生した際の、参考になれば幸いです。
以上、AWS事業本部の佐藤(@chari7311)でした。