CodePipelineでクロスアカウントにアクセスするCI/CDを構築した話

# はじめに

お疲れ様です。 [AWS Advent Calender](https://qiita.com/advent-calendar/2020/aws) の15日目の記事です。
今回はCodePipelineで **クロスアカウントにアクセスをするCI/CD** を構築してみたので、備忘録がてらまとめておこうと思います。
構築過程や詳細なコードなどは特に書いていないので予めご了承ください。

# もくじ
- なぜやろうと思ったのか(裏話的なことなので飛ばしておkです。)
    - 今の問題点
- 本文
    - 構成図
    - 構築時のポイント
- おわりに

# なぜやろうと思ったのか

　私の所属するプロジェクトではCodePipelineをCI/CDツールとして利用しており、CodeCommitの特定のブランチに資源をプッシュすると自動的にデプロイまで行われるようになっています。普段の使い勝手は非常に良いのですが、本番環境にリリースする際には **本番環境にあるCodePipelineを起動させるために、本番環境のCodeCommitに資源を置く** 必要があります。後述しますがこれには複数の問題がありました。
組織としてAWSのアカウントを環境別に分けていることはあると思いますが、弊社インフラ部隊が少人数かつ各種対応に忙殺されており、なかなか一歩踏み出せない状況になっていたのでこちらから問題の解決にアプローチをかけてみました。

## 今の問題点
![undraw_Post_re_mtr4 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/180676ad-72cc-f696-94c1-507f562d143c.png)

本番環境に資源を運ぶのは往々にして時間のかかる作業かつ、人の手による作業になるため以下のような問題が発生する可能性があります。実際に2つ目3つ目の問題は自分のチームでも起きています。

- 誤って古い資源をリリースしてしまう
- リリース作業に時間がかかる
- リリースできる人が偏る or リリースのためのドキュメントが必要になる

せっかくそれなりの期間をかけて開発したものを世に送り出すのに、一苦労しなきゃいけないのも嫌ですよね。
この記事が今同じような状況にあり、リリースにかかる時間を減らしたいと考えている人や単純にクロスアカウントアクセスを組みたいと考えている人にとって参考になると幸いです。

# 本文
さっそく設定していきます。
## 今回の構成図
![Untitled Diagram-Page-2 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/93b264a1-db90-3855-734c-1f2dbbd2d470.png)
ざっくりとこんな感じでやってました。LambdaのデプロイにはAWS samを利用しています。

## 構築時のポイント
![undraw_design_notes_8dmv (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/860f9726-241f-04a4-b916-67e744367c74.png)


通常作成する際と異なるポイントが2つありました。

- AWSコンソール以外からCodePipelineを作成する(今回はAWS CLIを利用しました)
- AWS KMSを利用する

### AWSコンソール以外からCodePipelineを作成する。
AWSコンソールから作成すると、Source ProvicerとしてCodeCommitを選択した際、リポジトリに選択できるのは **"その"AWSアカウントの同じリージョンのリポジトリ** のみになります。
例えばAWS CLIから設定するのであれば以下のように自由に設定できるので、別環境のリポジトリも指定可能です。(だいぶ端折ってますが)
検証時にはAWS CLIを利用してCodePipelineを作成し、別環境のCodeCommitのブランチを指定しました。

``` CodePipeline.json
"configuration": {
  "RepositoryName": "${開発環境のリポジトリ名}",
  "BranchName": "${ブランチ名}"
}
```

割と単純ですがこんな感じで指定ができます。

### AWS KMSを利用する。
CodeCommitの資源をs3にあげる際、カスタムCMKを使用することでクロスアカウントにアクセス許可をすることが可能です。
そのため以下の設定を行いました。

- カスタムCMKの作成
- Artifact用のs3バケットのバケットポリシーに作成したCMKによる制限をかける
- CodeBuildやCodePipeline作成時、暗号化キーにカスタムCMKを設定する

カスタムCMKの作成はAWSコンソールから行いました。
バケットポリシーについては [このあたり](https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/S3-artifact-encryption.html) のドキュメントを参照ください。
AWS CLIでCodeBuild、CodePipelineの作成時に以下のプロパティで作成したCMKを設定します。

``` Codebuild.json 
{
    "encryptionKey": "arn:aws:kms:ap-northeast-1:ひみつ:key/ひみつ"
}
```

``` CodePipeline.json
"artifactStore": {
  "type": "S3",
  "location": "ひみつ",
  "encryptionKey": {
    "id": "arn:aws:kms:ap-northeast-1:ひみつ:key/ひみつ",
    "type": "KMS"
  }
}
```

余談ですが、この構成の場合CI/CD Pipeline内で扱われるデータはデフォルトで暗号化されています。詳しくはCodeCommit、CodeBuild、s3のドキュメントをご確認ください。

以上の設定で別アカウントのCodeCommitの資源の変更を検知して、本番環境のCodePipelineを起動させる機構を作成することができます。

## 終わりに
　休日の時間を使って構築しましたが、実現できると今抱えている問題の解決や今後のリリース回りが整理できた状況に持っていけるなーと思い技術検証するまでに至りました。検証中はカスタムCMKの扱い方などハマった部分もありましたが、なんとか実現することができてよかったです！!
ここまで書いておいてなんですが、実はまだ本番環境には適用できていません...笑 これから弊社インフラチームと会話して実現可能かなど会話して作成していくことになります。その前に自分の頭を整理するためにも端折った部分はありますが今回は記事におこしてみました。今後自分のチームで実現して、それが社内でも適用されるナレッジになると嬉しいですね。

それでは、皆さんもよきAWSライフを。

![undraw_Freelancer_re_irh4 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/3f25d6ac-c6dd-7b69-47ac-fb97cd108ed6.png)

## References
[AWS Key Management Service と AWS CodeCommit リポジトリの暗号化](https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/encryption.html)
[データの暗号化(CodeBuild)](https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/security-encryption.html)
[Amazon S3 にあるオブジェクトの暗号化には、AWS KMS で管理されたキー、またはカスタム AWS KMS キーのどちらを使うべきですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/s3-object-encrpytion-keys/)
[CodePipeline 用に Amazon S3 に保存したアーティファクトのサーバー側の暗号化を設定する](https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/S3-artifact-encryption.html)
[CodePipeline でパイプラインを作成する](https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/pipelines-create.html)

## 他に利用したサイト
[diagrams.net](https://www.diagrams.net/)
作図とかによく利用しています、Google Driveから誰でも無料で利用でき、AWSのアイコンなども豊富にあるので使いやすいです。

[undraw](https://undraw.co/)
資料などで使える画像が豊富にあります。商用利用も可能で画像の色なども自由に変えられるのでこちらもおすすめです。