はじめに
Infrastructure as Code(IaC)の代表格の1つである、AWS CloudFormation。
僕も業務でよく使うのですが、CloudFormationで1度にデプロイできるリソースの数(=1スタックのリソース数)は、「最大200個」と決められています。
なので当然、Serverless Frameworkでデプロイする際も、1度にデプロイできるリソースの数は200個までです。
でも、プロダクトが大きくなると「200個では足りない!」というケースもあると思います。
今回は、その場合にスタックをネストして、201個以上のリソースをデプロイする方法(+α)についてです。
CloudFormationの制限とスタックのネスト
「CloudFormationで1度にデプロイできるリソース数は、200個が上限」については、公式ページでも明言されています。
(一部ブログを見る限り、昔は明言されてなかった?)
AWS CloudFormation の制限
200個というのも、決して少なくはないのですが、プロダクト(≒リソース)が肥大化してくると、オーバーするケースもあります。(特にロール・ポリシーやアラートが色々増えると)
その解決方法の一つとして、公式サイトでも紹介されているのが「スタックのネスト」で、下記の考え方になります。
- serverless.yml内で、serverless.ymlのデプロイ先スタック(=スタックA)とは別のスタック(スタックB)を別途定義する。
- 200個を超えるリソースは、スタックBに紐づくリソースとして定義する。
- 実際にserverless.ymlをデプロイすると200個を超えるリソースが作成されるが、スタックBに紐づけたリソースはスタックBで「上限200個」に影響するので、スタックAでの「上限200個」には影響しない。
- もちろん、スタックBのリソースが200個を超えたらNG。
- スタックB自身は(serverless.ymlに定義されるので)、スタックAの「上限200個」に影響する。
【参考】ネストされたスタックの操作
そこで今回は、Serverless Frameworkで「スタックのネスト」で対応する方法について扱いたいと思います。
※純粋なCloudFormationテンプレート、及びServerless Frameworkの「resources」セクションで扱う方法については、調査完了次第ブログにします。
「serverless-plugin-split-stacks」という超便利プラグイン
...と、なんかもったいぶって書き方をしましたが、実はServerless Frameworkでスタックをネストする」のは、めちゃくちゃ簡単です。
やり方ですが、下記2つを実行するだけです。
- 「serverless-plugin-split-stacks」というプラグインをインストールする(下記)
- serverless.ymlの「plugins」セクションに「serverless-plugin-split-stacks」を追加する。
plugins: - serverless-plugin-split-stacks # この定義を追加するだけ - ...
これだけ。本当にこれだけ。CloudFormationテンプレートファイルのような「定義ファイルの分割」も一切不要です。(てか、マジで便利すぎ。このプラグイン)
上記作業さえ行っておけば、「deploy」コマンドなどを実施した際に、「serverless-plugin-split-stacks」がリソース数を計算し、200を超えたら自動で定義ファイルを分割してくれますので、こちらの作業は一切不要です。
なお「serverless-plugin-split-stacks」のカスタマイズについては、下記ブログで詳しくまとめられています。
いや、マジで便利すぎます。このプラグイン。
デプロイを分割する
今回は「1回のデプロイで作業を完結させる」ために、スタックのネスト方法を記載しましたが、あえて「デプロイ自体を複数回行い、スタック自体を分ける」のも一つの手です。
確かに「何回もデプロイをやるなんて面倒」と思うかもしれませんが、あえて分けることで、以下のようなメリットもあります。
- デプロイするリソースを分割できる
- 1ファイルにまとめてしまうと、やたらデプロイに時間がかかるリソースがある場合(CloudFrontなど)、毎回すごい時間がかかってしまう。
- 「修正(=デプロイ)頻度」「依存関係」などでファイルを分割し、必要なリソースだけデプロイすることで、そういった無駄なデプロイ時間をなくすことができる。
- 「出力」の参照ができる
- CloudFormationのスタックには「出力」という参照用項目がある。
- Serverless Frameworkでは「resources」セクションの「Outputs」で定義できます。
- 「出力」に値を設定しておけば、後でデプロイする側は、先にデプロイされた側の「出力」の値を参照できる。(ARNなど)
- CloudFormationのスタックには「出力」という参照用項目がある。
ただし、やはりデプロイを複数回にすると、どうしても管理の煩わしさの問題は発生すると思うので、そこは検討する必要があると思います。
【参考】: serverlessフレームワークで複数スタックに分割して、リスクを軽減する方法 - Qiita
まとめ
- CloudFormationでは、1スタック(=1デプロイ)200リソースが上限である。
- スタックのネストを行えば、1デプロイで200個を超えるリソースもデプロイできる。
- Serverless Frameworkでは、「serverless-plugin-split-stacks」プラグインを使うと、驚くほど簡単にスタックのネストが行える
- 場合によっては、あえてデプロイ(=スタック)自体を分けるのも一つの手
「リソース管理の煩雑さからの解放」が「冪等性(※)」と並ぶIaCの大きな魅力なので、「スタックのネスト」「スタックの分割」など、いろいろな方法で、極力リソース管理の煩わしさから解放され、注力すべき作業に注力したいですね。
てかそれがAWSやAzureなど、クラウドの大きな魅力の一つでもありますから。
※冪等性(べきとうせい):「誰が何回作業を行っても、必ず毎回同じ結果になる」性質のこと。毎回同じ品質を提供できるというメリットがある。
告知
私事ですが、今週木曜日の27日に開催される「Serverless Meetup Tokyo #16」イベント(下記)にて、スピーカーをさせて頂きます。(オンライン開催です)
コロナウィルスの影響で、オンライン開催に変更されましたが、発表自体は予定通り行いますので、よろしくお願いいたします。
※当日は、YouTubeでのライブ配信も行われます。
発表では、下記について触れる予定です
それでは、今回はこの辺で。