ForgeVision Engineer Blog

フォージビジョン エンジニア ブログ

別AWSアカウントに存在する AWS CodeCommit をソースステージとする AWS CodePipeline の作成方法

本記事の内容

こんにちは、こんばんわ!クラウドインテグレーション事業部の魚介系エンジニア松尾です。

AWS上で構成する CI/CDパイプライン として AWS CodePipeline を利用されている方は多くいらっしゃると思います。今回は、別のAWSアカウントに存在する AWS CodeCommit に存在するソースコードを用いて AWS CodePipeline でパイプラインを作成する手順を紹介します。

本手順では、CloudFormation、CDKは利用しません。AWSマネージメントコンソール および AWS CLI を利用して行います。

構成イメージ

CodePipeline アカウントに存在する AWS CodePipeline で構成する matsuo-sample-pipeline パイプラインから、CodeCommit アカウントに存在するAWS CodeCommit に作成した matsuo-sample-repo リポジトリ に対しソースコードを取得し、ソースステージでソースコードの取り扱いを可能にすることを目的とします。

AWS CodePipeline で matsuo-sample-pipeline パイプライン を作成する

CodePipeline アカウントの AWS CodePipeline で matsuo-sample-pipeline パイプラインを作成します。

ソースステージのリポジトリ名、ブランチ名は存在しないものを入力してOKです。(あとで CodeCommit アカウントに存在するリポジトリに変えます)

ビルドステージで利用する AWS CodeBuild ビルドブロジェクトを指定します。

本記事ではデプロイステージはスキップしますが、利用するデプロイ処理を設定してもOKです。(あとでパイプラインにデプロイステージを追加することもできます)

パイプラインが作成されました。このタイミングでは存在しない CodeCommit リポジトリにアクセスするため、パイプラインはエラー終了します。

AWS Key Management Service で カスタマー管理型のキー を作成する

パイプラインでアーティファクトを取り扱う際に暗号/復号するためのカスタマー管理型のキーを作成します。

キーの管理アクセス許可、キー使用方法のアクセス許可はキーの管理権限を委譲する任意のIAMユーザーを設定します。本手順では何も設定せずに次へ進みます。

CodeCommit アカウントで IAMロールを作成する (CodePipelineアカウントからAssumeRoleを行えるようにする)

CodeCommit アカウントで CodePipelineアカウントに存在するパイプラインから リポジトリ へのアクセスを許可する IAMロールを作成します。IAMロールの設定は下記のように行います。

信頼関係に設定するJSON

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<CodePipelineアカウントのアカウントID>:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

ポリシーは何も設定せずに次へ進みます。

作成したIAMロールへ、以下のJSONを参考にインラインポリシーを設定します。

インラインポリシーに設定するJSON

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "S3Object",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::<CodePipelineアーティファクト保管用S3バケット名>/*"
            ]
        },
        {
            "Sid": "KMS",
            "Effect": "Allow",
            "Action": [
                "kms:DescribeKey",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:ReEncrypt*",
                "kms:Decrypt"
            ],
            "Resource": [
                "<作成したカスタマー管理型のキーのARN>"
            ]
        },
        {
            "Sid": "CodeCommit",
            "Effect": "Allow",
            "Action": [
                "codecommit:GetBranch",
                "codecommit:GetCommit",
                "codecommit:UploadArchive",
                "codecommit:GetUploadArchiveStatus",
                "codecommit:CancelUploadArchive"
            ],
            "Resource": [
                "<CodeCommitリポジトリのARN>"
            ]
        }
    ]
}

作成した カスタマー管理型のキー のキーポリシーを設定し、CodeCommitアカウントに存在する IAMロール からキーへのアクセスを許可する

CodeCommitアカウントに存在する IAMロール からキーへのアクセスへのアクセスを許可し、ソースステージにソースコードを配置できるようにするため、作成した カスタマー管理型のキー のキーポリシーを設定します。

キーポリシーに設定するJSON

{
    "Id": "key-consolepolicy-3",
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<CodePipleineアカウントのアカウントID>:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow use of the key",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "<パイプラインのビルドステージに指定したCodeBuildビルドプロジェクトに関連付けされているサービスロールのARN>",
                    "<CodeCommitアカウントに作成したIAMロールのARN>"
                ]
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*"
        }
    ]
}

編集をクリックしてキーポリシーを変更します。変更内容はキーポリシーに設定するJSONを参考にしてください。

CodePipeline アカウントで パイプラインに関連付けされたサービスロールのポリシーを変更する

CodePipeline アカウントで パイプラインに関連付けされたサービスロールに対し下記の権限を付与します。

  • CodeCommitアカウントで作成したIAMロールへのAssumeRoleを許可する
  • カスタマー管理型のキーへのアクセスを許可する

以下のJSONを参考にインラインポリシーを設定します。

インラインポリシーに設定するJSON

{
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "<CodeCommitアカウントに作成したIAMロールのARN>"
        },
        {
            "Sid": "KMS",
            "Effect": "Allow",
            "Action": [
                "kms:DescribeKey",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:ReEncrypt*",
                "kms:Decrypt"
            ],
            "Resource": [
                "<作成したカスタマー管理型のキーのARN>"
            ]
        }
    ],
    "Version": "2012-10-17"
}

CodePipelineアーティファクト保管用S3バケットのパケットポリシーを変更する

CodePipelineアーティファクト保管用S3バケットに対して、CodeCommtiアカウントからアクセス可能にするためのバケットポリシーを設定します。

バケットポリシーに設定するJSON

{
    "Version": "2012-10-17",
    "Id": "SSEAndSSLPolicy",
    "Statement": [
        {
            "Sid": "DenyUnEncryptedObjectUploads",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<CodePipelineアーティファクト保管用S3バケット名>/*",
            "Condition": {
                "StringNotEquals": {
                    "s3:x-amz-server-side-encryption": "aws:kms"
                }
            }
        },
        {
            "Sid": "DenyInsecureConnections",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::<CodePipelineアーティファクト保管用S3バケット名>/*",
            "Condition": {
                "Bool": {
                    "aws:SecureTransport": "false"
                }
            }
        },
        {
            "Sid": "CodeCommitAccountS3GetPut",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<CodeCommitアカウントのアカウントID>:root"
            },
            "Action": [
                "s3:Get*",
                "s3:Put*"
            ],
            "Resource": "arn:aws:s3:::<CodePipelineアーティファクト保管用S3バケット名>/*"
        },
        {
            "Sid": "CodeCommitAccountS3List",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam:<CodeCommitアカウントのアカウントID>:root"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::<CodePipelineアーティファクト保管用S3バケット名>"
        }
    ]
}

パイプラインのソースステージに CodeCommit アカウントに存在するリポジトリを設定する

パイプラインが存在するアカウントと異なるアカウントに存在する CodeCommit リポジトリを設定する作業はAWSマネージメントコンソールでは行えないため、AWS CLI 経由で設定する必要があります。

本手順では、AWS CLI の実行環境として AWS CloudShell を利用します。

CloudShell を起動します。

aws codepipeline get-pipeline コマンドを実行し、パイプラインの設定情報が記載されたJSONファイルを書き出します。

aws codepipeline get-pipeline コマンド

aws codepipeline get-pipeline --name <パイプライン名> > pipeline.json

パイプラインの設定JSONファイルを下記のように編集します。

編集後のパイプラインの設定JSONファイル

{
    "pipeline": {
        "name": "matsuo-sample-pipeline",
        "roleArn": "arn:aws:iam::123456789012:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1-matsuo-sample-pipelin",
        "artifactStore": {
            "type": "S3",
            "location": "codepipeline-ap-northeast-1-123456789012",
            "encryptionKey": {
                "id": "<作成した カスタマー管理型のキーのエイリアスARN>",
                "type": "KMS"
            }
        },
        "stages": [
            {
                "name": "Source",
                "actions": [
                    {
                        "name": "Source",
                        "actionTypeId": {
                            "category": "Source",
                            "owner": "AWS",
                            "provider": "CodeCommit",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BranchName": "<ソースステージで取り扱うCodeCommitリポジトリのブランチ名>",
                            "OutputArtifactFormat": "CODE_ZIP",
                            "PollForSourceChanges": "false",
                            "RepositoryName": "<ソースステージで取り扱うCodeCommitリポジトリ名>"
                        },
                        "outputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "inputArtifacts": [],
                        "roleArn": "<CodeCommitアカウントに作成したIAMロールのARN>",
                        "region": "ap-northeast-1",
                        "namespace": "SourceVariables"
                    }
                ]
            },
            {
                "name": "Build",
                "actions": [
                    {
                        "name": "Build",
                        "actionTypeId": {
                            "category": "Build",
                            "owner": "AWS",
                            "provider": "CodeBuild",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "ProjectName": "matso-sample-buiidproject"
                        },
                        "outputArtifacts": [
                            {
                                "name": "BuildArtifact"
                            }
                        ],
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "BuildVariables"
                    }
                ]
            }
        ],
        "version": 1,
        "executionMode": "QUEUED",
        "pipelineType": "V2"
    }
}

aws codepipeline update-pipeline コマンドを実行し、編集したパイプラインの設定JSONファイルをパイプラインに反映します。

aws codepipeline update-pipeline コマンド

aws codepipeline update-pipeline  --cli-input-json file://pipeline.json

実行後にパイプラインの設定にアクセスすると編集したパイプラインの設定JSONファイルの記述に従ったCodeCommitリポジトリ名、ブランチ名が反映されていることが確認できます。

パイプラインを実行して動作を確認する

設定を終えましたらパイプラインを実行して動作を確認してみましょう。ソースステージの処理が成功していることが確認できます。

ソースステージのアクション結果詳細を確認すると「出力」タブから CommitId を表示することができます。

CodeCommitリポジトリのコミットIDと一致していることが確認できました。

まとめ

本記事では別のAWSアカウントに存在する AWS CodeCommit に存在するソースコードを用いて AWS CodePipeline でパイプラインを作成する手順をご紹介しました。同一アカウント内ではアーティファクトの暗号/復号、アーティファクト保管用S3バケットへのアクセス権制御など、パイプライン作成時に自動で実行してくれるため意識することはあまり無いのですが、クロスアカウントの場合はそれらの設定を自身で行う必要があるため設定箇所が多いことがわかります。

実際に私もトライアンドエラーをしながら設定を行なって行きましたが、CodePipelineのソースステージの仕組みを理解することにも繋がりました。

インターネット上には、AWSマネージメントコンソール および AWS CLI のみを利用する場合の手順として、まとまっている情報がありませんでしたのでどなたかのお役に立てば幸いです。

では次回もお楽しみに!!!