前回投稿で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を入力して次へ進む。これ以降は通常のロール作成時と同じ。

クロスアカウント用ロール作成.png

 

デプロイ用ロール信頼ポリシーの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.以降を実施)

  1. コンソールで単体アカウント用にパイプラインを作成
  2. そのJSON定義を取得してクロスアカウント向けに編集
  3. パイプラインをアップデート
$ aws codepipeline update-pipeline --cli-input-json file://[パイプライン名].json

 

  1. アップデートしたパイプラインをスタート
$ aws codepipeline start-pipeline-execution --name [パイプライン名]

 

特にエラーが出なければパイプラインは走っているが、その先でコケることはよくあるのでコンソール画面から状況を確認する。アカウントAのマネジメントコンソール画面から全体の状況は把握できる。デプロイステージの詳細はアカウントBのコンソールからしか見れない。

というわけで、果てしなく続くと思われた長い旅路がようやく終わりましたよ。しかしいいかげんに普通の旅にも出たいもんだ。

airplane


関連がありそうな記事