9
6

More than 3 years have passed since last update.

[AWS SAM] テンプレートの階層化(スタックのネスト)

Posted at

AWS::Serverless::Applicationを使用したテンプレートの階層化

サービスごとにテンプレートファイルを分けて以下のような構成を作る

src/
  ├─ api-gateway/
  │   ├─ template.yaml  # API Gateway定義、API GatewayからコールされるLambda等の定義
  │   ├─ swagger.yaml
  │   ├─ aaa/function.py # Lambda関数
  │   └─ bbb/function.py # Lambda関数
  
  ├─ iot-core/
  │   ├─ template.yaml  # IoT Coreの定義、デバイス間通信時にコールされるLambda定義等
  │   └─ ccc/function.py # Lambda関数
  
  ├─ cognito/
  │   ├─ template.yaml  # Cognitoのユーザプール定義、認証時にコールされるLambda等の定義
  │   └─ ddd/function.py # Lambda関数
  
  
  ├─ s3/
  │   ├─ template.yaml  # S3のバケット定義、バケット操作時にコールされるLambda等の定義
  │   └─ eee/function.py # Lambda関数
      
  └─ template.yaml  # 各サービスのtemplate.yamlをまとめるためのtemplate.yaml

各サービスフォルダ以下のtemplate.yamlapi-gateway/template.yaml等)は、通常通りCloudFormationまたはSAMの書式に従って記述する

src/template.yamlで、各サービスフォルダ以下のtemplate.yamlで定義されたリソースをアプリケーション(AWS::Serverless::Application)として定義する

AWS::Serverless::Applicationの構文については公式ドキュメント参照

src/template.yamlは以下のようになる

src/template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:

  CognitoStack:
    Type: AWS::Serverless::Application
    Properties:
      Location: cognito/template.yaml # template.yamlのパス
      Parameters:
        StackName: !Ref AWS::StackName

  ApiGatewayStack:
    Type: AWS::Serverless::Application
    Properties:
      Location: api-gateway/template.yaml
      Parameters:
        StackName: !Ref AWS::StackName
        S3BucketName: !GetAtt S3Stack.Outputs.S3BucketName

  IoTCoreStack:
    Type: AWS::Serverless::Application
    Properties:
      Location: iot-core/template.yaml
      Parameters:
        StackName: !Ref AWS::StackName

  S3Stack:
    Type: AWS::Serverless::Application
    Properties:
      Location: s3/template.yaml
      Parameters:
        StackName: !Ref AWS::StackName

Locationに各template.yamlのパスを指定、
Parametersに各template.yamlに渡すパラメータを指定している

Parametersで渡された値は以下のように参照する

Parameters:
  StackName:
    Type: String

Resources:
  testFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub '${StackName}_testFunction'
      ...

テンプレート間のパラメータ受け渡し

例えばs3/template.yamlで生成したバケット名をapi-gateway/template.yamlで参照したい場合、
s3/template.yamlは以下のようにOutputsを使用してバケット名を出力する

s3/template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Parameters:
  StackName:
    Type: String

Resources:
  InfoS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub '${StackName}-test-bucket'
      AccessControl: Private
      PublicAccessBlockConfiguration:
        BlockPublicAcls: True
        BlockPublicPolicy: True
        IgnorePublicAcls: True
        RestrictPublicBuckets: True

Outputs:
  S3BucketName:  # バケット名を出力
    Value: !Ref InfoS3Bucket  # 上記InfoS3Bucketで定義したバケットの名前を出力する

出力された値は、src/template.yamlで他のtemplate.yamlParametersで渡す

src/template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  ...

  ApiGatewayStack:
    Type: AWS::Serverless::Application
    Properties:
      Location: api-gateway/template.yaml
      Parameters:
        StackName: !Ref AWS::StackName
        S3BucketName: !GetAtt S3Stack.Outputs.S3BucketName # s3/template.yamlで出力した値を渡す
  ...

  S3Stack:
    Type: AWS::Serverless::Application
    Properties:
      Location: s3/template.yaml
      Parameters:
        StackName: !Ref AWS::StackName

生成されるスタック

スタックをネストして定義すると、出力結果は以下のように、
template.yamlごとに「ネストされた」とついたスタックが生成される
1.png

親になっているスタックを削除すると、ネストされている全スタックの全リソースが削除される

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6