CloudFormation StackSetsを使う上で覚えておきたいこと

業務でCloudFormationのStackSets(以降StackSets)という機能を使ってマルチアカウント・マルチリージョンデプロイを試してみて、いくつか気をつけるべき点があったのでメモがてらまとめておこうと思う.

StackSetsについて

StackSetsを簡単に説明する.StackSetsとは,複数のAWSアカウントや複数のリージョンに跨ってAWSサービスをデプロイする時に使用するサービスである.単一のアカウントにデプロイするサービスとしてCloudFormation Stackがあるが,その拡張版といってよい.StackSetsでは,StackSetsを実行するアカウントとStackSetsによってサービスがデプロイされるアカウントが存在する.前者を親アカウント,後者を子アカウントと呼ぶことにする.親アカウントでStackSetsを実行すると,子アカウントにスタックが作成され,そのスタックのテンプレートに記載されている内容が子アカウント上で設定される.

https://d2908q01vomqb2.cloudfront.net/972a67c48192728a34979d9a35164c1295401b71/2019/09/04/6955-1-CloudFormation-StackSets.png

StackSetsを実行すると親アカウントにスタックセットと呼ばれる子アカウントのスタックを管理するリソースが作成され,そのスタックセット配下には各アカウントの各リージョン毎に一意なスタックインスタンス(子アカウントのスタックへのリファレンス)が作成される.詳しくは公式ページを参照あれ.

docs.aws.amazon.com

StackSetsを使う際の注意点

AWS CLIのバージョンの違いによるaws cloudformation describe-stack-setの表示項目の違い

aws cloudformation describe-stack-setは作成したスタックセットの詳細を取得するコマンドである.AWS OrganizationsのOrganization Unit(以降OU)を使ったデプロイを使っている場合,aws cloudformation describe-stack-setを実行することで,OrganizationalUnitIdsの項目に対象のスタックセットがどのOUにデプロイされているかが表示される.しかし,古いAWSコマンドのバージョンによってはOrganizationalUnitIdsという項目が表示されない事象がある.どのバージョンまでが表示されなくて,どのバージョンから表示されるかは分からないが,自分の環境のバージョンで試した結果は少なくともaws-cli/1.16.250では表示されず,aws-cli/1.18.125では表示された.OUを使ったデプロイが今年に入ってからの機能なので,AWSコマンドの古いバージョンを使っている場合は注意する.

aws.amazon.com

親アカウントが属しているOUにデプロイするとき,親アカウント自身にはデプロイされない

OUを使うデプロイを考えた時,子アカウントだけでなく親アカウントもOUに含めることで親アカウントにもデプロイするよう試してみたが,親アカウントにはデプロイできなかった. これは公式ページにも記載されている.親アカウントにもデプロイしたい場合は別途StackやStackSetsを使ってデプロイしなければならない.

StackSets は、マスターアカウントが組織内または組織の OU 内にあっても、スタックインスタンスを組織のマスターアカウントにデプロイしません。

このページの「サービスマネージド型のアクセス許可を持つスタックセットを作成する際の考慮事項」はOUを使ったデプロイを想定している方はよく読んでおくとよいかもしれない. docs.aws.amazon.com

マルチリージョンにデプロイする際,グローバルリージョンにしか存在しないリソースの設定には気をつける

マルチリージョンにサービスをデプロイする前提で,グローバルリージョンにしか存在しないサービス(例えばIAM)をStackSetsで設定する場合は気をつけなければならない.例えば,ap-northeast-1のリージョンでIAMロールを作成し,us-east-1のリージョンでもIAMロールを作成した時,作成した2つのIAMロール名が同じ場合はエラーになる.この対応としては「どこか1つのリージョンで設定する」もしくは「IAMロール名をリージョン毎に変える」等で対応できる.これは当たり前といえば当たり前だが,意外とグローバルリージョンにしか存在しないサービスはあるので頭の片隅に置いておくとよいと思う.

サービスによってはクロスリージョンの通信ができないことによってStackSetsの実行が失敗する場合がある

サービスによってはクロスリージョンの通信ができないことによりStackSetsの実行が失敗するものがあるのでそれらを考慮する必要がある.
例えば,ap-northeast-1に作成したAWS Configで通知をAmazon Simple Notification Service(以降SNS)に送信したい時,SNSap-northeast-1に作成されている必要がある.これを例えばus-east-1に作成したSNSに通知しようとするとエラーとなる.他にも例えば,LambdaをStackSetsでデプロイする際,ap-northeast-1に作成されたLambdaのアーティファクトS3はap-northeast-1に作成されている必要がある.これを例えばus-east-1に作成したアーティファクトS3からコードを取得しようとするとエラーとなる.
このように,サービスによってはクロスリージョンアクセス不可能な設定があるので,それぞれのリージョンで必要なサービスを配置しておかないとStackSetsを流した時にエラーになることがある.
個人的な見解になるが,サービスによってクロスリージョンアクセスする・しないを分けるのはややこしいので,特に強い理由がなければ連携するサービスは1つのリージョンにおさめるのが分かりやすくて良いと思っている.

まとめ

  • StackSetsを使う上での注意点を列挙した
  • OUと連携できるようになってからStackSetsは余計な設定をすることなく使えるようになったので重宝しそう