前回投稿でAWS CodePipelineのクロスアカウント設定(前半)ではリソース配布元のアカウントAの内容中心に書いた。後半は配布先となるアカウントBの設定内容を書いていく。
前回投稿
AWS CodeDeployでクロスアカウントデプロイ実行(パイプラインあり-1)
繰り返しになるけれども、前提条件をおさらいとして記載。
やりたいこと
AWSの異なるアカウント間で、CodePipelineによりCodeDeployからec2インスタンスにリソースをデプロイする。ソースはリソース配布側のCodeCommit。この記事では配布元を開発環境/アカウントA、配布先を検証環境/アカウントBとして話を進める。
主な参考ページ
他のリソースを使用するパイプラインを CodePipeline で作成するAWSアカウント
主な構成要素
これも前回書いているが、こっちにも書いておかないとわけわからなくなるので再掲。
1-資材配布元(アカウントA)
① CodeCommitリポジトリ(ec2にローカルリポジトリを作成〜資材格納)
② KMSキー (両方のアカウントにアクセス許可する)
③ S3バケット (アカウントBにアクセス許可するバケットポリシーを付与)
④ CodePipelineが使用するサービスロール
⑤ CodePipleline定義(コンソールで作成したパイプライン定義JSONをCLIから更新)
2-資材配布先(アカウントB)
① CodeDeploy定義(アプリケーション/デプロイメントグループ)
② ec2用のIAMロール(CodeDeployがアカウントAのKMSキー、S3にアクセスするためのポリシーを付与)
③ ②のIAMロールをアタッチしたデプロイ先ec2
④ クロスアカウント用サービスロール(CodeDeployとS3操作にassumeする)
上記アイテムを作成済みとして、作業概要は前回記事に記載した。以降、アカウントB側で用意するアイテムの内容を書く。
2-① CodeDeploy定義
アカウントBのコンソールにて、アプリケーションとデプロイメントグループを作成する。詳細は割愛。
2-② ec2用のIAMロール
KMSとS3用のインラインポリシーを作成する。AWS参考ページでは2つに分けていたが統合しても問題ないと思う。
KMS用インラインポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:DescribeKey",
"kms:GenerateDataKey*",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:Decrypt"
],
"Resource": [
"arn:aws:kms:us-east-1:[アカウントAのID]:key/[Key ID]" #KMSのARN
]
}
]
}
S3用インラインポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*"
],
"Resource": [
"arn:aws:s3:::[アカウントAのS3バケット名]/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::[アカウントAのS3バケット名]"
]
}
]
}
2-④ クロスアカウントデプロイ用IAMロール
サービスをCodeDeployとしてロールを作成する。この時アカウントAにassumeする前提で以下設定を行う。以下図の矢印箇所にアカウントAのIDを入力して次へ進む。これ以降は通常のロール作成時と同じ。
デプロイ用ロール信頼ポリシーのJSONは以下のようになる。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[アカウントAのID]:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
},
{
"Effect": "Allow",
"Principal": {
"Service": "codedeploy.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
デプロイ用メインのカスタムポリシー。CodeDeployのパーミッションを定義。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codedeploy:CreateDeployment",
"codedeploy:GetDeployment",
"codedeploy:GetDeploymentConfig",
"codedeploy:GetApplicationRevision",
"codedeploy:RegisterApplicationRevision"
],
"Resource": "*"
}
]
}
デプロイ用インラインポリシー。S3とCodeCommitのパーミッション定義。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject*",
"s3:PutObject",
"s3:PutObjectAcl",
"codecommit:ListBranches",
"codecommit:ListRepositories"
],
"Resource": [
"arn:aws:s3:::[S3バケット名]/*"
]
}
]
}
これとは別にec2周りのポリシーも割り当てる。検証時は取り急ぎマネージドのAmazonEC2ReadOnlyAccessでもアタッチしておけばいい。
これでやっとアイテムが出揃った。ここまで来たら、前回投稿の分も重複するがアカウントAの環境にて以下実行。(2. までは前回までの段階で完了しているとして、3.以降を実施)
- コンソールで単体アカウント用にパイプラインを作成
- そのJSON定義を取得してクロスアカウント向けに編集
- パイプラインをアップデート
$ aws codepipeline update-pipeline --cli-input-json file://[パイプライン名].json
- アップデートしたパイプラインをスタート
$ aws codepipeline start-pipeline-execution --name [パイプライン名]
特にエラーが出なければパイプラインは走っているが、その先でコケることはよくあるのでコンソール画面から状況を確認する。アカウントAのマネジメントコンソール画面から全体の状況は把握できる。デプロイステージの詳細はアカウントBのコンソールからしか見れない。
というわけで、果てしなく続くと思われた長い旅路がようやく終わりましたよ。しかしいいかげんに普通の旅にも出たいもんだ。