AWS CodePipelineで別アカウントのCodeCommitを利用する

開発環境のCodeCommitでソースコードを管理し、同じ開発環境のアカウント内にあるEC2で開発者は動作確認をする。ステージングとプロダクション用のアカウントは別アカウントで運用しているときに、開発環境で検証されたコードへクロスアカウントアクセスしソースコードを取得しCodePipelineを使ってステージング、プロダクションへデプロイする。

■本番環境(ステージング、プロダクション)用アカウント
CodePipelineで必要なロールはすでに定義してありパイプラインも作成済みと仮定する。
CodePipelineのRoleに開発環境のクロスアカウントアクセス用ロールの引き受けを許可するAuumeRoleをインラインポリシーで追加する。

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": [
            "arn:aws:iam::[開発環境のアカウントID]:role/クロスアカウントアクセス用サービスロール名"
        ]
    }
}

CodeBuild、CodeDeploy用にデフォルトで作成されたロールは特に編集しない。

[CodePipeline用のIAMロール]

※上記のインラインポリシーは含まれていない

{
    "Statement": [
        {
            "Action": [
                "s3:ListBucket",
                "s3:ListBucketVersions"
            ],
            "Resource": "[S3バケットのARN]",
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:GetObjectVersion",
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "[S3バケットのARN]/*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "codecommit:CancelUploadArchive",
                "codecommit:GetBranch",
                "codecommit:GetCommit",
                "codecommit:GetUploadArchiveStatus",
                "codecommit:UploadArchive"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codebuild:BatchGetBuilds",
                "codebuild:StartBuild"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codedeploy:CreateDeployment",
                "codedeploy:GetApplication",
                "codedeploy:GetApplicationRevision",
                "codedeploy:GetDeployment",
                "codedeploy:GetDeploymentConfig",
                "codedeploy:RegisterApplicationRevision"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "elasticbeanstalk:CreateApplicationVersion",
                "elasticbeanstalk:DescribeApplicationVersions",
                "elasticbeanstalk:DescribeEnvironments",
                "elasticbeanstalk:DescribeEvents",
                "elasticbeanstalk:UpdateEnvironment",
                "autoscaling:DescribeAutoScalingGroups",
                "autoscaling:DescribeLaunchConfigurations",
                "autoscaling:DescribeScalingActivities",
                "autoscaling:ResumeProcesses",
                "autoscaling:SuspendProcesses",
                "cloudformation:GetTemplate",
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStackResources",
                "cloudformation:DescribeStackEvents",
                "cloudformation:DescribeStacks",
                "cloudformation:UpdateStack",
                "ec2:DescribeInstances",
                "ec2:DescribeImages",
                "ec2:DescribeAddresses",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeKeyPairs",
                "elasticloadbalancing:DescribeLoadBalancers",
                "rds:DescribeDBInstances",
                "rds:DescribeOrderableDBInstanceOptions"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:invokefunction",
                "lambda:listfunctions"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "sns:*"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ],
    "Version": "2012-10-17"
}

[CodeDeploy用のIAMロール]

※AWSでデフォルトのAWSCodeDeployRole をアタッチ

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "autoscaling:CompleteLifecycleAction",
                "autoscaling:DeleteLifecycleHook",
                "autoscaling:DescribeAutoScalingGroups",
                "autoscaling:DescribeLifecycleHooks",
                "autoscaling:PutLifecycleHook",
                "autoscaling:RecordLifecycleActionHeartbeat",
                "autoscaling:CreateAutoScalingGroup",
                "autoscaling:UpdateAutoScalingGroup",
                "autoscaling:EnableMetricsCollection",
                "autoscaling:DescribeAutoScalingGroups",
                "autoscaling:DescribePolicies",
                "autoscaling:DescribeScheduledActions",
                "autoscaling:DescribeNotificationConfigurations",
                "autoscaling:DescribeLifecycleHooks",
                "autoscaling:SuspendProcesses",
                "autoscaling:ResumeProcesses",
                "autoscaling:AttachLoadBalancers",
                "autoscaling:PutScalingPolicy",
                "autoscaling:PutScheduledUpdateGroupAction",
                "autoscaling:PutNotificationConfiguration",
                "autoscaling:PutLifecycleHook",
                "autoscaling:DescribeScalingActivities",
                "autoscaling:DeleteAutoScalingGroup",
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceStatus",
                "ec2:TerminateInstances",
                "tag:GetTags",
                "tag:GetResources",
                "sns:Publish",
                "cloudwatch:DescribeAlarms",
                "cloudwatch:PutMetricAlarm",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeInstanceHealth",
                "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticloadbalancing:DescribeTargetHealth",
                "elasticloadbalancing:RegisterTargets",
                "elasticloadbalancing:DeregisterTargets"
            ],
            "Resource": "*"
        }
    ]
}

[CodeBuild用のIAMロール]

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:logs:ap-northeast-1:[本番環境のアカウントID]:log-group:[ロググループの場所]",
                "arn:aws:logs:ap-northeast-1:[本番環境のアカウントID]:log-group:[ロググループの場所]:*"
            ],
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": [
                "[CodeCommitのARN]"
            ],
            "Action": [
                "codecommit:GitPull"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": [
                "[S3バケットのARN]",
                "[S3バケットのARN]/*"
            ],
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation"
            ]
        }
    ]
}

次にアーティファクト保管用のS3バケットにバケットポリシーを適用する。

{
    "Version": "2012-10-17",
    "Id": "SSEAndSSLPolicy",
    "Statement": [
        {
            "Sid": "DenyUnEncryptedObjectUploads",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::[バケットの名前]/*",
            "Condition": {
                "StringNotEquals": {
                    "s3:x-amz-server-side-encryption": "aws:kms"
                }
            }
        },
        {
            "Sid": "DenyInsecureConnections",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::[バケットの名前]/*",
            "Condition": {
                "Bool": {
                    "aws:SecureTransport": "false"
                }
            }
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[開発環境のアカウントID]:root"
            },
            "Action": [
                "s3:Get*",
                "s3:Put*"
            ],
            "Resource": "arn:aws:s3:::[バケットの名前]/*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[開発環境のアカウントID]:root"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::[バケットの名前]"
        }
    ]
}

次にKMSを使ってカスタマー管理Keyを作成する。

{
    "Version": "2012-10-17",
    "Id": "key-name",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[本番環境のアカウントID]:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow access for Key Administrators",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[本番環境のアカウントID]:user/[アカウント名]"
            },
            "Action": [
                "kms:Create*",
                "kms:Describe*",
                "kms:Enable*",
                "kms:List*",
                "kms:Put*",
                "kms:Update*",
                "kms:Revoke*",
                "kms:Disable*",
                "kms:Get*",
                "kms:Delete*",
                "kms:TagResource",
                "kms:UntagResource",
                "kms:ScheduleKeyDeletion",
                "kms:CancelKeyDeletion"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow use of the key",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::[本番環境のアカウントID]:role/[CodeBuild用のIAMロール]",
                    "arn:aws:iam::[開発環境のアカウントID]:root",
                    "arn:aws:iam::[本番環境のアカウントID]:role/[CodeDeploy用のIAMロール]",
                    "arn:aws:iam::[本番環境のアカウントID]:role/[CodePipeline用のIAMロール]"
                ]
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow attachment of persistent resources",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::[本番環境のアカウントID]:role/[CodeBuild用のIAMロール]",
                    "arn:aws:iam::[開発環境のアカウントID]:root",
                    "arn:aws:iam::[本番環境のアカウントID]:role/[CodeDeploy用のIAMロール]",
                    "arn:aws:iam::[本番環境のアカウントID]:role/[CodePipeline用のIAMロール]"
                ]
            },
            "Action": [
                "kms:CreateGrant",
                "kms:ListGrants",
                "kms:RevokeGrant"
            ],
            "Resource": "*",
            "Condition": {
                "Bool": {
                    "kms:GrantIsForAWSResource": "true"
                }
            }
        }
    ]
}

EC2へ割り当てているロールにKMSへのアクセスを許可するインラインポリシーを追加

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "kms:*"
        ],
        "Resource": [
            "[KeyのARN]"
        ]
    }
}

AWS CLIでCodepipelineの設定をJSON形式でダウンロードし編集

aws codepipeline get-pipeline --profile [本番環境のアカウントID] --name [パイプラインの名前] > pipeline.json

{
    "pipeline": {
        "version": 8, 
        "roleArn": "CodePipeline用のIAMロール", 
        "stages": [
            {
                "name": "Source", 
                "actions": [
                    {
                        "inputArtifacts": [], 
                        "name": "Source", 
                        "roleArn": "[開発環境のアカウントID]:[クロスアカウントアクセス用のポリシー]", 
                        "actionTypeId": {
                            "category": "Source", 
                            "owner": "AWS", 
                            "version": "1", 
                            "provider": "CodeCommit"
                        }, 
                        "outputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ], 
                        "configuration": {
                            "PollForSourceChanges": "false", 
                            "BranchName": "master", 
                            "RepositoryName": "リポジトリ名"
                        }, 
                        "region": "ap-northeast-1", 
                        "runOrder": 1
                    }
                ]
            }, 
            {
                "name": "Build", 
                "actions": [
                    {
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ], 
                        "name": "Build", 
                        "region": "ap-northeast-1", 
                        "actionTypeId": {
                            "category": "Build", 
                            "owner": "AWS", 
                            "version": "1", 
                            "provider": "CodeBuild"
                        }, 
                        "outputArtifacts": [
                            {
                                "name": "BuildArtifact"
                            }
                        ], 
                        "configuration": {
                            "ProjectName": "プロジェクト名"
                        }, 
                        "runOrder": 1
                    }
                ]
            }, 
            {
                "name": "Approval", 
                "actions": [
                    {
                        "inputArtifacts": [], 
                        "name": "Approval", 
                        "region": "ap-northeast-1", 
                        "actionTypeId": {
                            "category": "Approval", 
                            "owner": "AWS", 
                            "version": "1", 
                            "provider": "Manual"
                        }, 
                        "outputArtifacts": [], 
                        "configuration": {
                            "NotificationArn": "[NortificationのARN]"
                        }, 
                        "runOrder": 1
                    }
                ]
            }, 
            {
                "name": "Deploy", 
                "actions": [
                    {
                        "inputArtifacts": [
                            {
                                "name": "BuildArtifact"
                            }
                        ], 
                        "name": "Deploy", 
                        "region": "ap-northeast-1", 
                        "actionTypeId": {
                            "category": "Deploy", 
                            "owner": "AWS", 
                            "version": "1", 
                            "provider": "CodeDeploy"
                        }, 
                        "outputArtifacts": [], 
                        "configuration": {
                            "ApplicationName": "アプリケーション名", 
                            "DeploymentGroupName": "デプロイグループ名"
                        }, 
                        "runOrder": 1
                    }
                ]
            }
        ], 
        "name": "[パイプライン名]", 
        "artifactStores": {
            "ap-northeast-1": {
                "type": "S3", 
                "location": "[S3バケット名]", 
                "encryptionKey": {
                    "type": "KMS", 
                    "id": "[KeyのARN]"
                }
            }
        }
    }
}

CodePipelineの設定をUpdateする。

aws codepipeline update-pipeline --profile [本番環境のアカウントID] --cli-input-json file://pipeline.json

■開発環境用アカウント

本番環境のCodeCommitアクセス用ロールにS3バケットおよびKMSへのアクセスを許可したクロスアカウントアクセス用のポリシーを定義し、本番環境のアカウントIDに対してAssumeRoleを許可する。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "UploadArtifactPolicy",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::[S3バケット名]/*"
            ]
        },
        {
            "Sid": "KMSAccessPolicy",
            "Effect": "Allow",
            "Action": [
                "kms:DescribeKey",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:ReEncrypt*",
                "kms:Decrypt"
            ],
            "Resource": [
                "[KeyのARN]"
            ]
        },
        {
            "Sid": "CodeCommitAccessPolicy",
            "Effect": "Allow",
            "Action": [
                "codecommit:GetBranch",
                "codecommit:GetCommit",
                "codecommit:UploadArchive",
                "codecommit:GetUploadArchiveStatus",
                "codecommit:CancelUploadArchive"
            ],
            "Resource": [
                "[CodeCommitリポジトリのARN]"
            ]
        }
    ]
}

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::[本番環境のアカウントID]:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}
スポンサーリンク






シェアする

  • このエントリーをはてなブックマークに追加

フォローする