はじめに
CodeCommitへのアクションをトリガーに別アカウントに存在するCodePipelineを実行するように実装しました。
その際にアカウント間で必要になる権限について構築していてハマったので権限整理した結果をまとめます。
実装した構成
CodeCommitの変更イベントをEventBridgeルールで検知し、イベントバス経由でCodePipelineが存在する別アカウントへイベント送信するという構成にしています。
アカウント分けは以下のようにしています。
- CodeCommitが存在するアカウント → Aアカウント
- CodePipelineが存在するアカウント → Bアカウント
この構成の場合、Artifactを保存するS3バケットはKMSによって暗号化されている必要がありますのでご注意ください。
他のCodePipelineアカウントのリソースを使用するパイプラインをAWSに作成する
必要な権限一覧
前項の構成を実装する場合に権限を設定する必要がある箇所・設定内容は以下の通りです。
個人的に実装していて混乱したのはCodeCommitアクセス用IAMロール、S3(Artifact) バケットポリシーになるかなと思います。
- アカウントA
- EventBridge イベントルール
- CodeCommitアクセス用IAMロール
- アカウントB
- EventBridge イベントルール
- EventBridge イベントバス
- CodePipeline IAMロール
- S3(Artifact) バケットポリシー
アカウントA
EventBridge イベントルール
アカウントBのイベントバスへ送信するため、イベントバスへのアクセス許可を設定しています。
参考: Amazon EventBridge イベントバスのアクセス許可
# カスタム信頼ポリシー { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } # ポリシー { "Version": "2012-10-17", "Statement": [ { "Action": [ "events:PutEvents" ], "Effect": "Allow", "Resource": [ "<アカウントBのイベントバスARN>" ], "Sid": "" } ] }
CodeCommitアクセス用IAMロール
参考ドキュメントでは別アカウントのCodeDeployをCodePipelineで実行する内容でしたが、CodeDeployをCodeCommitに置き換えています。
別アカウントのCodeCommitをCodePipelineで動かすためには、以下の権限が必要になりそうです。
またこの権限を持ったIAM RoleはCodeCommitが存在するアカウントで作成する必要があるのでアカウントAで作成しました。
- アカウントBのCodePipelineからアカウントAのCodeCommitを実行可能に
- アカウントAにあるCodeCommitからアカウントBのArtifactバケットへコードを格納できるようにする
# カスタム信頼ポリシー { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "<AWSアカウントBに存在するCodePipelineのサービスロール IAM ARN>" }, "Action": "sts:AssumeRole" } ] } # ポリシー { "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:Get*", "s3:Put*", ], "Effect": "Allow", "Resource": [ "<アカウントBに作成したArtifactバケットのARN>" ] }, { "Action": [ "s3:ListBucket" ], "Effect": "Allow", "Resource": [ "<アカウントBに作成したArtifactバケットのARN>" ] }, { "Action": [ "kms:Decrypt", "kms:DescribeKey", "kms:Encrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*" ], "Effect": "Allow", "Resource": [ "<アカウントBに作成したArtifactバケットのKMS ARN>" ] }, { "Action": [ "codecommit:GetBranch", "codecommit:GetCommit", "codecommit:UploadArchive", "codecommit:GetUploadArchiveStatus", "codecommit:CancelUploadArchive" ], "Effect": "Allow", "Resource": [ "<アカウントAに作成したCodeCommitリポジトリのARN>" ] } ] }
アカウントB
EventBridge イベントルール
アカウントBのCodePipelineを実行する権限を設定しています。
# 信頼ポリシー { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } # ポリシー { "Version": "2012-10-17", "Statement": [ { "Action": [ "CodePipeline:StartPipelineExecution" ], "Effect": "Allow", "Resource": [ "<AWSアカウントBのCodePipeline ARN>" ], "Sid": "" } ] }
EventBridge イベントバス
アカウントAからイベント受信するためのリソースポリシーを設定しました。
defualtのイベントバスを使用していますが、カスタムイベントバスを使用する場合はResourceのarnを修正する必要があります。
参考: AWS アカウント間での Amazon EventBridge イベントの送受信
# リソースポリシー { "Version": "2012-10-17", "Statement": [{ "Sid": "CrossAccountAccess", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<AWSアカウントA ID>:root" }, "Action": "events:PutEvents", "Resource": "arn:aws:events:ap-northeast-1:<AWSアカウントB ID>:event-bus/default" }] }
CodePipeline
CodePipelineからCodeCommitへアクセスできるようにアカウントAで作成したCodeCommitアクセス用IAMロールARNを指定します。
またここではCodeCommitのみに権限を集中していますが、CodePipelineで実行するサービスごとに権限を追加する必要がありますので適宜追加いただければと思います。
# 信頼ポリシー { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "CodePipeline.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } # ポリシー { "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" ], "Effect": "Allow", "Resource": [ "<アカウントAで作成したCodeCommitアクセス用IAMロールARN>" ], "Sid": "" } ] }
S3(Artifactバケット)
CodeCommitアクセス用IAMロールの項目でも記載した通り、アカウントAのCodeCommitからアカウントBのCodePipeline Artifactバケットへコードを送るため、受け取り側であるS3バケットでもアクセスできるように設定します。
# バケットポリシー { "Version": "2012-10-17", "Statement": [ { "Sid": "Statement1", "Effect": "Allow", "Principal": { "AWS": [ "<アカウントAで作成したCodeCommitアクセス用IAMロールARN>" ] }, "Action": [ "s3:Put*", "s3:Get*" ], "Resource": "<アカウントBに作成したArtifactバケットのARN>" }, { "Sid": "Statement2", "Effect": "Allow", "Principal": { "AWS": [ "<アカウントAで作成したCodeCommitアクセス用IAMロールARN>" ] }, "Action": "s3:ListBucket", "Resource": "<アカウントBに作成したArtifactバケットのARN>" } ] }
さいごに
別アカウントにあるCodePipelineを実行する際に必要な権限・内容をまとめました。
同じもしくは似たような構成を行い混乱された方の助けになればと思います。