はじめに
AWS API Gatewayにはステージ機能があり、/dev, /prod などの複数ステージにデプロイしてURLで切り替えることができます。
ですが、CloudFormationでAWS::Serverless::ApiリソースとしてデプロイしようとするとStageNameがstringしか指定できず、1つのステージしか作成できません。 (参考:リソースリファレンス)
API GatewayではAPIキーや使用量プラン、デプロイもステージに対して紐づくコア機能ですが、SAMでは複数ステージが想定されていないようにみえます。
ということで、SAMにおけるAPI Gatewayのステージの役割とかどう管理していくべきかを考えていきたいと思います。
ちなみにこの件はGitHubリポジトリのIssueがOpenとなっており、議論が進められています。
今回は主にこの議論のまとめ的な要素が多めです。
参考URL
- https://github.com/awslabs/serverless-application-model/issues/198
- https://hackernoon.com/managing-multi-environment-serverless-architecture-using-aws-an-investigation-6cd6501d261e
環境ごとのリソースを管理する方法
SAMで環境ごとのリソースを管理するアプローチは以下の2パターンが考えられます。
- 1つのスタックで管理する
- 1つのAPI Gateway内で複数ステージを作成
- 1つのLambda内で複数エイリアスを作成
- API Gatewayのステージ変数でエイリアスを指定
- 環境ごとに別スタックで管理する
- CloudFormationのパラメータを参照して別名のリソースをそれぞれ作成する
現状では、ServerlessのCloudFormationではステージが複数指定できないという課題があるためほぼ後者一択という感じもありますが、前者を選択したい場合は一旦SAMをきれいに使うことを諦めてAWS::ApiGateway::Stageリソースを活用していけば複数ステージ作成も可能です。
その代わりSAMの便利な記法が使えなくなるデメリットが発生しますがそのあたりはトレードオフですね。
単独スタックでまとめるべきか分離するべきか
議論としては分離するのがベターという意見が多めです。
さらに可能ならAWSアカウントも分けたほうがよいとも言われています。
デプロイ事故などを防ぐにはやはり分けておいたほうが安全ですね。
ただそうすると、APIステージやLambdaエイリアスはどんな時に使えばよいのかという疑問は残ります。
小規模なリソースについて環境ごとに個別にスタックを作成するとスタックやリソース自体が増えて管理が煩雑になるので1つのスタックにまとめてしまい、スタック自体がある程度の規模になるとテンプレート内での環境管理の方が大変になるので分離する。というのが一つのアプローチかもしれません。
まとめ
この件は先日のAWS Summit Tokyo 2019の会場でServerlessブースにいた方を捕まえて色々お聞きしてヒントを頂いた話を元にまとめています。
本当にお忙しい中対応いただいてありがたい限りです。
Issue上でのcontributorの発言内容をまとめておくと、
- 複数ステージをデプロイ出来るような機能はいずれリリースするつもりがある
- Stage変数をArrayで指定する形式が有力?
- とはいえべき論としてはステージごとにスタックを分けるのがよさそう
- ドキュメントもその方向で修正していく
ということのようで、
IssueがOpenしたのが2017年9月、いずれ対応するよとコメントが出されたのが2018年6月で、その後特に動きなし、という状況ですので、SAMにおいては複数ステージを使うことは考えないほうがよさそうです。
API Gatewayのステージという機能自体が使われない機能感がありますね。