他アカウントの CodeCommit を使用した CodePipeline

開発アカウントに CodeCommit を使用して、プロダクションアカウントでビルドやデプロイを行うためのメモ。

f:id:section27:20180924032104p:plain

1. プロダクションアカウント

1-1. CodePipeline のサービスロールのためのポリシーを作成する

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketVersioning"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::codepipeline*",
                "arn:aws:s3:::elasticbeanstalk*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "codecommit:CancelUploadArchive",
                "codecommit:GetBranch",
                "codecommit:GetCommit",
                "codecommit:GetUploadArchiveStatus",
                "codecommit:UploadArchive"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codedeploy:CreateDeployment",
                "codedeploy:GetApplicationRevision",
                "codedeploy:GetDeployment",
                "codedeploy:GetDeploymentConfig",
                "codedeploy:RegisterApplicationRevision"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "elasticbeanstalk:*",
                "ec2:*",
                "elasticloadbalancing:*",
                "autoscaling:*",
                "cloudwatch:*",
                "s3:*",
                "sns:*",
                "cloudformation:*",
                "rds:*",
                "sqs:*",
                "ecs:*",
                "iam:PassRole"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:InvokeFunction",
                "lambda:ListFunctions"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "opsworks:CreateDeployment",
                "opsworks:DescribeApps",
                "opsworks:DescribeCommands",
                "opsworks:DescribeDeployments",
                "opsworks:DescribeInstances",
                "opsworks:DescribeStacks",
                "opsworks:UpdateApp",
                "opsworks:UpdateStack"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStacks",
                "cloudformation:UpdateStack",
                "cloudformation:CreateChangeSet",
                "cloudformation:DeleteChangeSet",
                "cloudformation:DescribeChangeSet",
                "cloudformation:ExecuteChangeSet",
                "cloudformation:SetStackPolicy",
                "cloudformation:ValidateTemplate",
                "iam:PassRole"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codebuild:BatchGetBuilds",
                "codebuild:StartBuild"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Effect": "Allow",
            "Action": [
                "devicefarm:ListProjects",
                "devicefarm:ListDevicePools",
                "devicefarm:GetRun",
                "devicefarm:GetUpload",
                "devicefarm:CreateUpload",
                "devicefarm:ScheduleRun"
            ],
            "Resource": "*"
        }
    ]
}

1-2. CodePipeline のサービスロールを作成する

CodePipeline サービスのロールを作成する

1-3. IAMの暗号化キーを作成する

  • IAM から 暗号化キー を選択して、使用するリージョンで キーの作成 を選択する
  • エイリアスと説明の作成で、エイリアス を入力し 次のステップ を選択する
  • タグの追加で必要に応じてタグを追加し、次のステップ を選択する
  • キーの使用アクセス許可の定義 の キー管理者 を必要に応じて設定し、次のステップ を選択する
  • キーの使用アクセス許可の定義 の このアカウント で 1-2 の手順で作成した CodePipeline のサービスロールを選択する、 外部アカウント で 外部アカウントの追加 を選択して開発アカウントIDを入力する
  • キーポリシーのプレビューで 完了 を選択する

1-4. CodePipeline のサービスロールに暗号化キーのポリシーを追加する

1-2 の手順で作成した CodePipeline のロールに 1-3 の手順で作成した暗号化キーの ARN をリソースに設定して作成したポリシーをアタッチする

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "kms:*"
        ],
        "Resource": [
            "arn:aws:kms:ap-northeast-1:${ProductionAccount}:key/2222222-3333333-4444-556677EXAMPLE"
        ]
    }
}

1-5. CodeBuild のサービスロールのためのポリシーを作成する

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "codebuild:*",
                "iam:PassRole",
                "logs:FilterLogEvents",
                "logs:GetLogEvents",
                "logs:CreateLogStream",
                "logs:CreateLogGroup",
                "logs:PutLogEvents",
                "s3:CreateBucket",
                "s3:GetObject",
                "s3:List*",
                "s3:PutObject"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

1-6. CodeBuild のサービスロールを作成する

CodeBuild サービスのロールを作成し、1-5 の手順で作成した CodeBuild のポリシーと 1-4 の手順で作成したポリシーをアタッチする

2. 開発アカウント

2-1. CodeCommit にクロスアカウントアクセスのためのポリシーを作成する

1-3 の手順で作成した暗号化キーの ARN を設定して、 クローンしたイメージを暗号化して CodePipeline の S3 に PutObject するためのポリシーを作成する。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
              "codecommit:BatchGetRepositories",
              "codecommit:Get*",
              "codecommit:GitPull",
              "codecommit:List*",
              "codecommit:CancelUploadArchive",
              "codecommit:UploadArchive",
              "s3:*"
            ],
            "Resource": "*"
        },
        {
           "Effect": "Allow",
            "Action": [
                "kms:*"
            ],
            "Resource": [
                "arn:aws:kms:ap-northeast-1:${ProductionAccount}:key/2222222-3333333-4444-556677EXAMPLE"
            ]
        }
    ]
}

2-2. CodeCommit のロールを作成する

  • IAM から ロール を選択し ロールの作成 を選択する
  • 別のAWSアカウント を選択し、アカウントID にプロダクションアカウントのアカウントIDを入力し、次のステップ:アクセス権限 を選択する
  • 2-1 の手順で作成したポリシーをアタッチし、次のステップ:確認 を選択する
  • ロール名を入力し、ロールの作成 を選択する

2-3. CodeCommit を作成する

CodeCommit を作成する。CodeCommit はあらかじめ作成しておいてもよい。

3. プロダクションアカウント

3-1. CodePipeline のサービスロールに開発アカウントのポリシーを追加

CodePipeline に開発アカウントの CodeCommit のロールにアクセスするポリシーを作成しアタッチする

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::${DevelopAccount}:role/${CodeCommitRoleName}"
            ]
        }
    ]
}

3-2. CodePipeline の Artifact Store となる S3 Bucket を作成する

codebuild.amazonaws.com サービスと開発アカウントの CodeCommit ロールからアクセスされる CodePipeline で使う S3 Bucket を作成する。

Key Description
BucketName CodePipeline が使用するバケット
CodeCommitRoleName 2-2 の手順で作成したロール名
DevelopAccount 開発アカウントID
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  BucketName:
    Type: String
  CodeCommitRoleName:
    Type: String
  DevelopAccount:
    Type: String
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref S3Bucket
      PolicyDocument:
        Statement:
        - Action: s3:*
          Effect: Allow
          Resource:
          - !Sub arn:aws:s3:::${BucketName}
          - !Sub arn:aws:s3:::${BucketName}/*
          Principal:
            Service:
            - codebuild.amazonaws.com
            AWS:
            - !Sub arn:aws:iam::${DevelopAccount}:role/${CodeCommitRoleName}

3-3. CodeBuild

Key Description
CacheLocation CodeBuild のキャッシュが使用するバケット
CodeBuildRoleName 1-6 の手順で作成したロール名
Image CodeBuildに使用するコンテナ名
Name CodeBuild名
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  CacheLocation:
    Type: String
  CodeBuildRoleName:
    Type: String
  Image:
    Type: String
  Name:
    Type: String
Resources:
  CodeBuild:
    Type: AWS::CodeBuild::Project
    Properties:
      Artifacts:
        Type: CODEPIPELINE
      Cache:
        Location: !Sub ${CacheLocation}/ivy2
        Type: S3
      Description: !Ref Name
      EncryptionKey: arn:aws:kms:ap-northeast-1:${ProductionAccount}:key/2222222-3333333-4444-556677EXAMPLE
      Environment:
        ComputeType: BUILD_GENERAL1_SMALL
        Image: !Ref Image
        EnvironmentVariables:
        - Name: BUCKET_NAME
          Value: !Ref CacheLocation
        PrivilegedMode: true
        Type: LINUX_CONTAINER
      Name: !Ref Name
      ServiceRole: !Sub arn:aws:iam::${AWS::AccountId}:role/${CodeBuildRoleName}
      Source:
        Type: CODEPIPELINE

3-4. CodePipeline

Key Description
BucketName 3-2 の手順で作成したバケット
CodeCommitRoleName 2-2 の手順で作成したロール名
CodePipelineRoleName 1-2 の手順で作成したロール名
DevelopAccount 開発アカウントID
Name CodePipeline名
RepositoryName 2-3 の手順で作成した CodeCommit リポジトリ
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  BucketName:
    Type: String
  CodeCommitRoleName:
    Type: String
  CodePipelineRoleName:
    Type: String
  DevelopAccount:
    Type: String
  Name:
    Type: String
  RepositoryName:
    Type: String
Resources:
  CodePipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      ArtifactStore:
        EncryptionKey:
          Id: arn:aws:kms:ap-northeast-1:${ProductionAccount}:key/2222222-3333333-4444-556677EXAMPLE
          Type: KMS
        Location: !Ref BucketName
        Type: S3
      Name: !Ref Name
      RoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role/${CodePipelineRoleName}
      Stages:
      - Actions:
        - ActionTypeId:
            Category: Source
            Owner: AWS
            Provider: CodeCommit
            Version: 1
          Configuration:
            PollForSourceChanges: false
            RepositoryName: !Ref RepositoryName
            BranchName: master
          Name: source
          OutputArtifacts:
          - Name: MyApp
          RoleArn: !Sub arn:aws:iam::${DevelopAccount}:role/${CodeCommitRoleName}
        Name: source
      - Actions:
        - ActionTypeId:
            Category: Build
            Owner: AWS
            Provider: CodeBuild
            Version: 1
          Configuration:
            ProjectName: !Ref Name
          InputArtifacts:
          - Name: MyApp
          OutputArtifacts:
          - Name: App
          Name: build
        Name: build

参考