🛺

【CFn】イベントブリッジをトリガーにしたクロスアカウントパイプライン

2022/06/03に公開

CI/CD構成でAWSリソースを管理したいとき、よくCodePipelineを使用すると思いますが、ブランチごとに異なるアカウントにリソースを作成することもよくある構成だと思い、実装してみました。

クロスアカウントでCFnスタックをパイプラインで管理したいとき、そのパイプライン構成を作成できるテンプレートが探しても見つけられなかったです、、。 CI/CDの構築方法でクロスアカウントのアクセス評価理論、イベントブリッジなどがAWS初学者の自身には難しかったため、アウトプットの意味でも記事にしようと思った次第です。

ちなみにガッツリ以下の記事を参考にしています。(なので、テンプレートの構成など、ほとんど同じになっています、、ありがとうございます、、)
別のAWSアカウントにあるCodeCommit RepositoryをソースとするCodePipelineをCloudFormationで構築してみた

タイトルにもある通り、パイプラインを起動する条件の部分でイベントブリッジを使用してみました。これを入れた理由としてはイベントブリッジを使用するほうが推奨されていたことと、ポーリングで状態変化を検知すると、ちょっとラグがあるように感じたためです。

注意事項、やらないこと

  • コンソール画面で3つテンプレートをデプロイします。CLIでデプロイできたほうが使い勝手が良かったかなと思っています。
  • ロールの権限に使わない権限が入っていたり、余計なところがあると思います。
  • 別アカウントにスタックを作成できるStackSetsというものがあるみたいですが、調べきれなかったので使用していないです。
  • CFnのExportとImport機能を使用していないです。(使用すればもう少しパラメータの受け渡しが簡単になると思います。)

構成図

構成図

  • CodeCommit
    開発環境に1つのみ存在、developブランチ、prodブランチの更新でそれぞれ開発、本番パイプラインが起動します。
  • DeployStage
    各パイプラインのデプロイステージでCFnをプロバイダーとして選択し、ソース内のテンプレートをデプロイしています。(デプロイするテンプレートは1個です)
  • 承認
    デプロイする前で手動承認を入れています。
    (開発環境での承認はいらないかもしれないですが、とりあえず構成を同じにしたかったので、入れています。)
  • イベントブリッジ
    パイプラインの起動条件はイベントブリッジを使用しています。
    イベントブリッジの詳細部分は以下で説明しています。

クロスアカウントのリソースアクセス方法

ここの点がちょっと自分的に分かりづらかった点ですが、クロスアカウントアクセスするにはアクセスするときに必要なロールでの許可と、アクセスされる側のリソースでのリソースベースのポリシーで両方アクセスを許可する必要があります。
(ロールでアクセス先リソースの指定とその操作の許可、リソースベースの方で信頼関係の設定と、操作の許可が必要になります。)
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_evaluation-logic-cross-account.html

今回はクロスアカウントアクセスされるリソースは、本番環境のパイプラインに必要なArtifact Bucket,KMSキー,カスタムイベントバスの3つです。そのため、開発環境で用意してあるアクセス用ロールに上記3つのリソースのARNを指定しており、各リソースベースのポリシーの信頼関係に開発環境のルートユーザーを指定してあります。構成図中に※で記してあるロールで、引き受けるリソースは本番環境のパイプラインのソースステージです。

クロスアカウント用のロールは以下部分で定義しています。
本番環境のS3とKMSにアクセスする権限を付与していることが分かるかと思います。

https://github.com/D2toru/cross-account-pipeline/blob/main/deploy_templates2.yml#L80-L121

本番アカウントのカスタムイベントバスをターゲットにしているルールが使用するロールの定義部分です。ここでもクロスアカウント用に権限を付与しています。

https://github.com/D2toru/cross-account-pipeline/blob/main/deploy_templates2.yml#L39-L58

イベントブリッジのイメージ

イベントブリッジ

  • イベントバス
    イベントバストは各種イベントが通過する「道」のようなイメージです。各ルールはイベントバスごとに設定でき、イベントの中であるルールにマッチしたルールが発火するようになっています。
    初期ではデフォルトイベントバスしかありませんが、アカウント内で発生したイベントはデフォルトイベントバスに流れるため、デフォルトイベントバスにルールを設定していくことで、CodeCommitのブランチ更新イベントをルールでキャッチできます。

  • ルール
    上記にあるようにルールにはマッチする条件と、イベントを送信するターゲットを設定できます。
    ルールのキャッチ方法は詳細に設定することができ、CodeCommitの特定のブランチが更新されたというようなレベルでマッチできます。その他にも各リソースごとにいろんな種類のイベントがあります。
    ターゲットはARNを指定することで、パイプラインの起動などができます。
    また、ターゲットは他アカウントのカスタムイベントバスをターゲットにもでき、その場合、元々のイベントをそのまま他アカウントのカスタムイベントバスに送信できます。今回は本番アカウントのカスタムイベントバスに送信して、ルールでprodブランチ更新ルールにマッチさせ、本番パイプラインを起動しています。

テンプレートの使い方

  • git
    以下gitに公開しています。

https://github.com/D2toru/cross-account-pipeline

以下手順でスタックを実行すれば、この記事で紹介した構成がデプロイされるようになっています。
各テンプレートで作成したリソースのARNなどを一個後のテンプレートに入れたりしないといけないので、一撃でできるわけではないです、、

  1. 本番環境でtemplate1でスタックを作成
  2. 開発環境でtemplate2でスタックを作成
  3. 本番環境でtemplate3でスタックを作成

(各テンプレートのパラメータの具体的な説明はREDME内に載せています。)
全てのスタックが問題なく終了すれば、パイプラインが完成し、SNSトピックの確認メールが届いていると思います。

ターゲットとなるリポジトリ

実際にテンプレートを管理するリポジトリの構成は以下のようになっていることを想定しています。

(プロジェクト直下)
templates
|__ deploy_template.yml  (テンプレート本体)
|__ deploy_template.json (テンプレートのパラメータファイル)

実際にパイプラインを起動させたいときはdevelopブランチをpushすると、開発のパイプラインが動作し、prodブランチをpushすると、本番環境のパイプラインが起動し、テンプレートのchange setが作成された時点で手動承認依頼メールが設定したメールに飛んでくると思います。

全然説明しきれていない感じが否めないですが、どなたかのお役に立てれば幸いです。
何か間違っている点があったらコメントお願いします〜

Discussion