column

コラム

Lambdaのマルチアカウントデプロイ 設計編

  • TAG

    タグ未登録
  • UPDATE

    2021/03/01

こんにちは、クラウドCoEの熊谷です。

今回は、「Lambdaのマルチアカウントデプロイ」と題し、テスト環境と本番環境とでAWSアカウントを分けるような運用環境において、テスト環境で構築したLambdaを本番環境にデプロイする方法をご紹介します。

「Lambdaのマルチアカウントデプロイ 設計編」、「Lambdaのマルチアカウントデプロイ 構築編」に分けて記載します。 設計編となる今回は、利用するAWSサービスと構成のポイント等、構築編で必要となるナレッジについてご説明します。

マルチアカウントデプロイのメインとなるAWSサービス

構成図(メインとなるAWSサービスのみ)

テスト環境でテストが完了したLambdaを、本番環境にデプロイすることを想定した構成です。

まずは概要を掴んでいただくために、IAMロール、EventBridge等一部記載していないAWSサービスもあります。触れていないサービスに関しても後ほど詳細をご説明します。

構成図に登場するAWSサービスとその用途

CodeCommit

CodeCommitを利用してLambdaのソースを管理します。

CodeCommitはAWSのリポジトリ管理用のマネージドサービスです。CodeCommitで管理したソースの変更イベントをトリガーにその他のAWSサービスを起動する等、自動デプロイの起点とすることが出来ます。

今回はテスト環境にリポジトリをホストし、本番環境でLambdaをデプロイする際はテスト環境のリポジトリを参照する構成とします。

CodeBuild

CodeBuildSAMを組み合わせて、CodeCommitのソースを基にLambdaデプロイ用のCloudFormation(以下、CFn)のスタックテンプレートを作成します。

LambdaやAPI Gateway等、AWSのServerless Applicationをデプロイする為にはSAMというCFnの拡張機能を用います。

EC2やRDSを構築する為の通常のCFnテンプレートとは記載内容が若干異なる部分がありますが、CFnテンプレートからスタックを作成し、AWSサービスをデプロイする点は同じです。詳しくはAWSの公式サイトをご参照ください。

What is the AWS Serverless Application Model (AWS SAM)?

CodePipeline

CodeCommit、CodeBuildを組み合わせ、CFnでLambdaをデプロイする一連の流れを自動で実行する為にCodePipelineを利用します。

CodePipelineはCodeCommit/CodeBuild/CodeDeployと共に「AWSのCode4兄弟」と呼ばれることもあるサービスですが、この4つのサービス全てを組み合わせないと自動デプロイの仕組みを導入できないわけではありません。

上の構成図をご覧ください。

今回は「Sourceステージ」・「Buildステージ」・「Deployステージ」と3つのステージをCodePipelineで定義していますが、テスト環境・本番環境の「Deployステージ」ではCodeDeployを使っていないことがわかります。

CodeDeployはCodePipelineでAWSサービスをデプロイする為に利用できるアクションプロバイダーの1つであり、CodeDeploy以外にもアクションプロバイダーとして指定できるAWSサービスはたくさんあります。

今回はアクションプロバイダーを「CloudFormation」とすることにより、Buildステージで作成したCFnスタックテンプレートをCFnを用いてデプロイします。

S3

CodePipelineの各ステージで作成されたものはS3に格納されます。

今回の構成を例に、具体的に説明しましょう。

「Sourceステージ」ではCodeCommitのソースが圧縮され、S3に格納されます。

そして次のステージである「Buildステージ」でS3に出力されたCodeCommitのソースを参照し、CFnのテンプレートが作成されます。作成されたテンプレートは、同じくS3に格納されます。

更にその次のステージである「Deployステージ」で、S3に配置されたCFnのテンプレート参照し、CFnのスタック作成を実行します。

ポイントは、各ステージからS3に成果物を格納する際は必ず暗号化するという点です。

暗号化するためのキーとして、KMSで作成したカスタムマネージドキーか、S3のデフォルトキーのどちらかが利用可能です。しかし暗号化せずS3に成果物を格納することは出来ません。

この「キーの扱い」がマルチアカウントデプロイをする際の注意点の1つになります。

クロスアカウントアクセスの設定

ここまではCode系のサービスについて主に説明しました。

これらAWSサービスを適切に構築しただけでは、まだLambdaのマルチアカウントデプロイは実現できません。

実現する為には、次の3つの設定が残っています。

  • CodePipeline@本番環境が、リポジトリ@テスト環境を参照する為の設定
  • テスト環境のリポジトリのソースを、本番環境のS3に暗号化した上で格納する為の設定
  • CodeCommit@テスト環境へのマージイベントをCodePipeline@本番環境で拾う設定

あるAWSアカウントでホストされたAWSサービスが、別のAWSアカウントのリソースにアクセスすることをクロスアカウントアクセスと言います。Lambdaのマルチアカウントデプロイでは上記の3つのクロスアカウントアクセスが必要になります。

ここからはこれらの3つの実現方法について述べます。

CodePipeline@本番環境がテスト環境のIAMロールを使ってリポジトリを参照

作成するIAMロール

IAMについては、弊社の過去のコラムで触れていますので是非ご参照ください。

IAMを理解する第1回(機能編)
IAMを理解する第2回(IAMポリシー編)

テスト環境・本番環境の各CodePipelineにアタッチするサービスロール、Buildステージ及びDeployステージで必要なサービスロールの権限については次回のコラムでご説明します。

この構成ではたくさんのIAMロールが登場しますが、注記するべきIAMロールはテスト環境のActionロール本番環境CodePipelineのサービスロールの2つのみです。

 

テスト環境のActionロールの役割

テスト環境のActionロールは、本番環境のCodePipelineのサービスロールが利用(AssumeRole)します。

より詳細には、本番環境のCodePipelineのSourceステージが、このテスト環境のIAMロールを用いてテスト環境のCodeCommitのリポジトリを参照し、本番環境のS3に成果物を格納することになります。

よってActionロールにはCodeCommit、S3、そしてKey Management Serviceについて適切なIAMポリシーを設定しなくてはなりません。

  • テスト環境のリポジトリの参照権限、コミット参照権限等のCodeCommitに関する権限
  • 本番環境のS3に対するPut権限
  • 本番環境のCMKの参照及び利用(暗号化/復号)権限
本番環境CodePipelineがテスト環境のActionロールを利用する為の設定

また本番環境AWSアカウント内にホストされたAWSサービスがこちらのActionロールを利用する為に、Actionロールの信頼関係に本番環境AWSアカウントを設定します。

IAMロールの「信頼関係」タブを確認すると、そのIAMロールを利用することが出来るIAMエンティティ(IAMユーザ、グループ、AWSアカウント等、IAMロールの利用者になることが出来る存在のこと)が閲覧できます。

テスト環境のリポジトリのソースを、本番環境のS3に暗号化した上で格納する

本番環境のCodePipelineでカスタマー管理キーを利用する

今回KMSを利用する範囲はごく一部です。本番環境のCodePipelineのSourceステージが、テスト環境のActionロールを用いて本番環境のS3にソースを成果物としてpushする際に、本番環境のCMKを用いて暗号化します。

ポイントは、AWSが勝手に作成及び管理してくれるS3管理キーを用いず、本番環境側でカスタマ―管理キー(CMK)をKMSで作成する必要がある点です。

前述の通り、CodePipelineの各ステージの成果物は、S3に格納される際に必ず暗号化されます。そして今回の構成において本番環境のCodePipelineで暗号化に利用できるのはAWS利用者がKMSに作成したCMKのみです。

CodePipelineでは暗号化に利用するキーを指定しない場合Amazon S3が管理するキーがデフォルトで選択されますが、今回はこちらは利用できません。

S3のオブジェクトのプロパティから、「サーバー側の暗号化設定」を確認すると、どのキーを利用して暗号化されているかを確認することが出来ます。

何故S3管理キーを利用できないのか

S3管理キーを用いたサーバサイド暗号化(SSE-S3)は、私たちがS3にデータを格納する際によく利用する暗号化手法でしょう。どのAWSアカウントでも一様に同じ手順で利用できるため、このキーがどのようなものかを意識する機会があまりないかもしれません。

あるAWSアカウントで管理されるAWS管理キーは、他のAWSアカウント内にホストされたAWSサービスで利用することができないという仕様(※)があります。

※これはEBSやRDSのスナップショットをAWSアカウント間で共有する際に考慮するべき仕様でもあります。詳細はAWSの公式サイトをご参照ください。
暗号化された Amazon RDS DB スナップショットを別のアカウントと共有する方法を教えてください。

デフォルトとなるSSE-S3を利用して本番環境のS3にソースをpushすると、テスト環境のS3管理キーを用いて暗号化された成果物が本番環境のS3に格納されます。

よってテスト環境の管理キーを用いて暗号化された成果物は、本番環境CodePipelineのBuildステージで復号できず、CodeBuildが異常終了します。

同様に、テスト環境のActionロールは本番環境のS3管理キーを用いて成果物を暗号化することは出来ません。

よって、本番環境でのCMKの作成と、テスト環境のActionロールへのCMK利用権限の付与が必要になります。

テスト環境のイベントを本番環境のCodePipelineで拾う

最後はクロスアカウントイベント配信の設定についてです。

こちらの設定をしなくても、前述のIAMロール・CMKの設定さえすれば本番環境のCodePipelineを用いたLambdaのデプロイは実現可能です。

しかし現在の設定のままでは、テスト環境のCodeCommitのmasterブランチへのマージ作業後、本番環境のAWSアカウントにログインし、CodePipelineを起動するボタンを押すという手作業が発生してしまいます。つまり、自動で本番環境にLambdaがデプロイされることはありません。

今回はテスト環境のCodeCommitのmasterブランチへのマージ作業後に本番環境のCodePipelineを自動で起動するために、EventBridgeのRuleとEventBusを利用します。

構成図

設定内容

設定手順は次回のブログで記載しますので、今回はイベントを拾う為の条件(イベントルール)とEventBusに必要な設定をご説明します。

テスト環境側

テスト環境のリポジトリのmasterブランチへのマージをトリガーに起動するEventBridge Ruleを作成します。ターゲットには本番環境のEventBusを指定します。

この設定により、「CodeCommitのmasterブランチへのマージ⇒EventBridge起動⇒本番環境のEventBus起動」というパイプを作ることが出来ます。

本番環境側

EventBridgeのイベントパターンの設定はテスト環境のEventBridge Ruleと同じです。つまり、本番環境側のEventBridgeでもテスト環境のCodeCommitのイベントを指定することになります。

ターゲットには本番環境のCodePipelineを指定します。

またテスト環境のEventBridgeが本番環境のEventBusを起動できるよう、本番環境のEventBus側のリソースポリシーを変更します。

それでは次回のコラムでは実際にCodePipelineを構築していきます。

RECOMMEND

おすすめ記事一覧