サーバーレスで活用するCloudFormationのNested Applications
弊社のサーバレス開発事例にて利用している
Nested Applications
についてご紹介いたします。
CloudFormationのリソース数の制限
AWS CloudFormation
には制限があることをご存知でしょうか。
制限のほとんどは、上限解放することができない制限となっております。
重要な制限として、リソース数の制限があります。
リソースは一つのテンプレートに最大で200までしか作成することができません。
「テンプレートに記載したリソース数 = リソース数」
ではない
例えば、シンプルなAWS Lambdaをテンプレートに定義した場合、
下記2つのリソースが作成されます。
- AWS::Lambda::Function
- AWS::IAM::Role
テンプレートに記載したリソース数は
最終的に出力されるリソース数とは合致しません。
リソース数はテンプレートへの記載を増やす毎に、膨らんでいきます。
特にサーバーレスの場合はAWS Lambdaに対してのイベントソースとして
複数のAPIエンドポイントを紐づけるケースがあり、
すぐにリソース数がいっぱいになってしまうこともあります。
では、どのようにすればよいのでしょうか。
解決策を記載します。
Nested Applicationsを利用してネストされたスタックを作成する
AWS Serverless Application Model(SAM)は拡張されたフォーマットのため、
AWS::CloudFormation::Stack
定義を利用することができません。
代替手段として、 Nested Applicationsの
AWS::Serverless::Application
が利用可能です。
Nested Applicationsを利用することで 最大で40,000 の
リソースを作成することが可能になります。
また、ネストされるテンプレートは自動的にS3にアップロードされます。
Nested Applicationsは Serverless Application Repository
の
アプリケーションをネストできることに注目されていますが、
ローカルにあるテンプレートをネストすることも可能です。
ローカルにあるテンプレートをネストする場合の記述例:
Transform: AWS::Serverless-2016-10-31
Resources:
applicationaliasname:
Type: AWS::Serverless::Application
Properties:
Location: ../my-other-app/template.yaml
Nested Applicationsを利用して、サーバーレスのスタックを作成
それでは、実際にやってみましょう。
サンプルは下図のフォルダ構成となります。
筆者本人のGitHubアカウントにてリポジトリも公開しておりますので、
よろしければご参照下さい。
テンプレートファイル(template.yml)
テンプレートファイルは AWS::Serverless::Application
のリソースを定義し
ネストされたスタックを構築します。パラメータを受け渡すことも可能です。
下記の記述例では、 Parameters
に定義された変数とS3のバケット名を受け渡しています。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Parameters:
Stage:
Type: String
Default: test
Resources:
app1:
Type: AWS::Serverless::Application
Properties:
Location: ./template_app1.yml
app2:
Type: AWS::Serverless::Application
Properties:
Location: ./template_app2.yml
Parameters:
Stage: !Ref Stage
BucketTest: !Ref S3Bucket
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: aws-sam-nested-application-test-bucket-0-001
ネストされたテンプレートファイル
サンプルでは、ネストされたテンプレートファイルのそれぞれに AWS::Serverless::Function
のリソースを定義しました。
親のテンプレートファイルから受け渡されたパラメータも参照しています。
テンプレート1(template_app1.yml)
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Resources:
App1Function:
Type: AWS::Serverless::Function
Properties:
FunctionName: app1
CodeUri: handlers/app1
Handler: app1
Runtime: go1.x
S3Bucket001:
Type: AWS::S3::Bucket
Properties:
BucketName: aws-sam-nested-application-test-bucket-1-001
テンプレート2(template_app2.yml)
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Parameters:
Stage:
Type: String
Default: dev
BucketTest:
Type: String
Globals:
Function:
Runtime: go1.x
Timeout: 900
Environment:
Variables:
STAGE: !Ref Stage
Resources:
App2Function:
Type: AWS::Serverless::Function
Properties:
FunctionName: app2
CodeUri: handlers/app2
Handler: app2
S3Bucket2001:
Type: AWS::S3::Bucket
Properties:
BucketName: aws-sam-nested-application-test-bucket-2-001
デプロイ
デプロイは sam deploy
の実行時にCAPABILITY_AUTO_EXPANDのオプションを付与する必要があります。
#!/bin/sh
# Create Package
sam package
--template-file ./template.yml
--output-template-file ./template-output.yml
--s3-bucket aws-sam-nested-application-packages
--profile temp_profile
# Deploy
sam deploy
--template-file ./template-output.yml
--stack-name aws-sam-nested-application
--capabilities CAPABILITY_IAM CAPABILITY_AUTO_EXPAND
--profile temp_profile
実行結果
Nested Applicationsの作成に成功していることが確認できました!
テンプレートの分割は計画的に
サーバレス開発の場合、気づいたらリソース数が逼迫しているということも
珍しくないと思います。中・大規模のサーバレス開発なら尚更です。
リソースの整理に伴う再作成が余儀なくされる前に、計画的にテンプレートを分割することをオススメいたします。
弊社ではGoとAWS SAMを活用したサーバレスアプリケーション開発実績があります
少しでもご興味を持ちましたら、弊社にエントリーしていただければ幸いです。
一緒に楽しく成長しあえる仲間を募集しています。
・リモートワークでAWSなサーバーレスシステムに携わりたいエンジニア大募集
MMMのサーバーレスへの取り組みについては以下でご紹介しています。ぜひご覧ください。