【AWS】クロスアカウントなCodePipelineのアクセス制御をわかりやすく図解してみた

**皆さん、CI/CD 実践していますか？（挨拶）**

本記事では、CodeCommit と CoddePipeline を用いたクロスアカウントな CI/CD 環境を構築する際のアクセス制御方法をなるべく初心者にもわかりやすく解説していきます。


## やりたいこと

**「CodeCommit と CoddePipeline を用いたクロスアカウントな CI/CD 環境」** と言われてもピンとこないと思うので、図を書いてみました。やりたいことはこれです。↓

![CrossAccountCodePipeline-概要図.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2443303/da7e2b9f-646e-7eb2-7711-a533e02c05f1.png)

要するに、環境毎に CodeCommit (Git) のブランチを作って、そのブランチにコミットした時に対応する環境の CodePipeline を起動して、ビルドやテスト、デプロイを自動的に実行したい、ということです。

:::note warn
本記事では、アクセス制御の概念を理解していただくことを目的としているため、IAMポリシーなど具体的な設定値や設定方法には言及しません。具体的な設定値や設定方法については、AWS公式ドキュメントをご参照ください。
:::


# シンプルに考える

AssumeRole について理解していただいたところで、本題に入ります。

やりたいことはこれです。↓（再掲）

![CrossAccountCodePipeline-概要図.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2443303/da7e2b9f-646e-7eb2-7711-a533e02c05f1.png)

この図では、

* dev ブランチにコミット → 開発アカウントのパイプラインを起動
* stg ブランチにコミット → ステージングアカウントのパイプラインを起動
* prod ブランチにコミット → 本番アカウントのパイプラインを起動

となっていますが、開発アカウント、ステージングアカウント、本番アカウントの構成は同じなので、どれかひとつのアカウントでやりたいことを実現できれば、他のアカウントも同じ要領で実現できます。

というわけで、以降は開発アカウントに絞って考えていきます。

![CrossAccountCodePipeline-概要図（シングルアカウント）.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2443303/272aa92d-daaa-32ca-9ee7-f0fef54c60cd.png)


# 設定すべきこと

結論から言うと、やりたいことを実現するには以下の設定が必要になります。

**1. CodePipeline が CodeCommit にアクセスできるようにする**
**2. CodeCommit 上のソースコードを CodePipeline のアーティファクトバケットに格納できるようにする**
**3. CodeCommit の変更イベントを開発アカウントに通知し、パイプラインを起動するルールを設定する**

**結構、大変そうだと思いませんか？**
　→少なくとも、経験が浅い人にとってはハードルが高いと思います。
　　→なので、この記事を書こうと思ったわけです。

上記の設定をすべて反映すると、以下のような構成になります。
これが今回やりたいことのゴールです。

![CrossAccountCodePipeline-詳細図（シングルブランチ）.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2443303/b3c47c37-6b30-6f92-877e-e577a11085d8.png)

それでは、ひとつひとつ解説していきます。


## 1. CodePipeline が CodeCommit にアクセスできるようにする

まずは、開発環境の CodePipeline が管理アカウントの CodeCommit にアクセスできるようにする必要があります。
これを実現するには、以下の設定が必要です。

**① 管理アカウント上に CodeCommit にアクセス可能な IAM Role を作成する**
**② CodePipeline の IAM Role が上記のIAM Role を引き受けられるようにする（AssumeRole）**

![CrossAccountCodePipeline-1. IAM Role.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2443303/32052745-0f6e-87fd-6d3f-be79ab2c8e4e.png)


### AssumeRole とは？

CodeCommit と CoddePipeline に限らず、クロスアカウントなアクセス制御を実装する場合、IAM、特に **AssumeRole** の概念を正しく理解しておく必要があります。
慣れていない方にとっては、この部分が最初のハードルになると思います。

AssumeRole については、以下のサーバーワークスさんのブログがわかりやすいので、ぜひご一読ください。

https://blog.serverworks.co.jp/assume-role-divedeep


## 2. CodeCommit 上のソースコードを CodePipeline のアーティファクトバケットに格納できるようにする

CodePipeline が CodeCommit にアクセスできるようにはなりましたが、これだけでは CodePipeline がソースコードを処理することはできません。
CodePipeline がソースコードを処理するには、ソースコードを **アーティファクトバケット** に格納する必要があります。

![CrossAccountCodePipeline-2. Artifact Bucket.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2443303/81130463-bc65-4a89-f622-53b9265506c7.png)


### アーティファクトバケットとは？

**アーティファクトバケット** の前に **アーティファクト** というモノを理解する必要があります。
AWS 公式ドキュメントでは以下のように説明されています。

> アーティファクトとは、パイプラインアクションによって処理されるアプリケーションのソースコード、構築されたアプリケーション、依存関係、定義ファイル、テンプレートなどのデータの集合を指します。

https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/concepts.html#concepts-artifacts

わかりやすく言うと、

* **アーティファクトとは「パイプラインアクションのアウトプット」**
* **アーティファクトバケットとは「パイプラインアクションのアウトプットを格納するバケット」**

となります。


### この時点でパイプラインの手動実行は可能

ここまでの設定で CodePipeline が管理アカウントの IAM Role を使用して、CodeCommit からソースコードを取得し、アーティファクトバケットに格納することができるようになったはずです。
パイプラインを手動実行して、期待動作になるか確認してみましょう。
　→エラーが発生したり、起動動作にならない場合は設定に不足・不備がないか見直してみましょう。

パイプラインを手動で実行することができたら、次の段階では CodeCommit のイベントをトリガーとしてパイプラインを自動起動するように設定していきます。


## 3. CodeCommit の変更イベントを開発アカウントに通知し、パイプラインを起動するルールを設定する

異なるアカウントに対してイベントを通知するには、EventBridge で **イベントバスの設定** を追加する必要があります。

![CrossAccountCodePipeline-3. EventBridge.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2443303/9c431d3e-1879-f196-80be-75e8e0e48ee2.png)

具体的な設定方法については、以下のクラスメソッドさんのブログがわかりやすいので、こちらを参考に設定してみてください。

https://dev.classmethod.jp/articles/issue-an-event-to-the-event-bus-of-eventbridge-of-anotheraccount/


### イベントバスとは？

EventBridge の **イベントバス** については以下の記事が参考になります。

https://aws.amazon.com/jp/builders-flash/202009/awsgeek-eventbridge/?awsf.filter-name=*all


# まとめ

「CodeCommit と CoddePipeline を用いたクロスアカウントな CI/CD 環境」を構築するには以下の設定が必要です。

**1. CodePipeline が CodeCommit にアクセスできるようにする**
**2. CodeCommit 上のソースコードを CodePipeline のアーティファクトバケットに格納できるようにする**
**3. CodeCommit の変更イベントを開発アカウントに通知し、パイプラインを起動するルールを設定する**

クロスアカウントのアクセス制御は複雑になりがちですが、整理して、ひとつずつ理解していけば、必ず習得できると思います。**「困難は分割せよ」** ですね。


# 補足

もし、アーティファクトバケットへのアクセスがエラーとなる・権限がないと言われる場合は、バケットの暗号化設定を確認してみてください。

バケットを KMS キーで暗号化している場合、バケットにアクセスする IAM Role に対して、KMS キーの使用権限を付与する必要があります。
KMS キーの使用権限を付与するには、IAM Role にポリシーを追加するだけでなく、KMS キーのキーポリシーも編集する必要があります。

詳細は以下のAWS公式ドキュメントをご参照ください。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/UsingKMSEncryption.html


# あとがき

最後まで読んでいただき、ありがとうございます。
この記事が少しでも役に立てば幸いです。