CloudFormation StackSetsとSSMパラメーターストア

目次

はじめに

AWS環境を構築していると、例えば本番環境と検証環境で環境固有の変数は異なるが後は同一構成で作成する、ということがあると思います。そういったときにAWSリソースをCloudFormationテンプレートでデプロイし、環境固有の変数はSSMパラメーターストアに登録すると、複数の環境を作るために最小限の労力で手作業によるミスを最小化して対応できます。今回はそうした構成をどのように実現するか説明します。

CloudFormation StackSetsを使用する

AWSでマルチアカウント管理をしており、例えば共通機能をまとめた共通サービスアカウントのCloudFormation StackSetsから、本番環境用のAWSアカウントと検証環境用のAWSアカウントにクロスアカウントでスタックをデプロイすれば、一つのスタックセットで環境固有の変数のみ共通サービスアカウントのSSMパラメーターストアから取得し、複数の環境を一度にセットアップできて美しい構成になるのではないかと考えたのですが、これは記事執筆時点では出来ない構成の様です。

動的な参照を使用してテンプレート値を指定する - AWS CloudFormation

ssm の動的な参照パターンを使用するときには以下の追加の考慮事項に注意してください。 現在、CloudFormation はクロスアカウント SSM パラメータアクセスをサポートしていません。

実現したかった構成

その代わり、SSMパラメーターストアを共通サービスアカウントに持つのではなく、各環境側に持つようにして、SSMパラメーターストアの値自体は共通サービスアカウントからCloudFormation StackSetsで配るということで妥協しました。この形であれば、StackSetsから各環境にStackが作成されて動的参照が行われるときに、各環境のSSMパラメーターストアが参照されるようです。なお、SecureStringはCloudFormationテンプレートで配ることが出来ないため、結局一部の作業は最終的に各環境で個別の手作業が必要になります。

AWS::SSM::Parameter - Type-SecureString · Issue #82 · aws-cloudformation/cloudformation-coverage-roadmap · GitHub

StackSetsをクロスアカウントで配る際に、配る元のアカウントのSSMパラメーターストアを参照できない事については、AWSサポートに機能追加するよう要望を出しました。Product Feature Requestに登録頂けることを期待しています。

妥協案

SSMパラメーターストアの階層設計

SSMパラメーターストアの階層設計について、公開情報がほとんど見当たらなかったため、こちらの記録も残します。

参考: 階層とタグによるパラメータの組織化及びAmazon EC2 Systems Manager パラメータ ストアのAmazon CloudWatchイベント | Amazon Web Services ブログ

結論としては、マルチアカウント管理の環境でパラメーターを登録する場合は、以下のように階層を作成するのが良いかと思います。

規則:/システム名/アカウントID/サービス名/パラメーター 例:/TestSystem/123123123123/VPC/VpcName

この形にすることで、どのシステムの、どのアカウント(環境)の、どのサービスの、どのパラメーターを指しているかが明確になりました。厳密には、自アカウントの中でパラメーターストアを呼び出すため、規則としてアカウントIDの階層を作る必要はありませんが、将来的に先述のクロスアカウントでStackSetsを配る場合の対応がされることがあれば、パラメーターストアを統合することが可能なようにするためです。

テンプレートから動的参照する際には以下のような形で呼び出します。

VpcName: !Sub '{{resolve:ssm:/TestSystem/${AWS::AccountId}/VPC/VPCName}}

CloudFormation StackSetsのデプロイモデル

余談になりますが、CloudFormation StackSetsにはサービスマネージド型とセルフマネージド型があります。

サービスマネージド型の方が、AWS Organizationsの機能をそのまま使う形でStackSetsをクロスアカウントでデプロイできるのですが、なぜかデプロイ先の指定がOUレベルまでしか出来ない制約がありました。

そのため、これまではわざわざセルフマネージド型を採用して、クロスアカウントでStackSetsをデプロイできるようにIAMロールを各アカウントに配っていたのですが、どこかのタイミングでサービスマネージド型でもOU内のアカウントを指定する形でデプロイできるようになったようです。

Account level targets for service-managed Stack Sets - AWS CloudFormation

サービスマネージド型でアカウントIDを指定してデプロイ

まとめ

本記事では、AWSをマルチアカウント管理していて、共通サービスアカウントのCloudFormation StackSetsからクロスアカウントで各AWSアカウントにスタックをデプロイし、環境固有の変数はSSMパラメーターストアから取得する構成をご紹介しました。どなたかのお役に立てば幸いです。