AWS SAMテンプレートの分割(テンプレートのネスト)

AWS

AWS SAMテンプレートを分割(ネスト)させる方法です。

リソースの数が多くなってくると煩雑になるのでテンプレートを分割して
管理したくなると思いますがAWS SAMテンプレートでも分割(ネスト)が可能です。
ネストした場合、スタックはファイル別に作成されますが、関連付けされているので
親側のスタックを削除すればネストしているスタックも含めて全て削除されます。

■参考URL
ネストされたアプリケーションを使用する

分割前のAWS SAMテンプレート

LambdaとDynamoDBの定義があります。
今回はここからDynamoDBの定義を別のファイルに分離します。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app

  Sample SAM Template for sam-app

# 入力パラメータ
Parameters:
  Env:
    Description: Enter environment.dev, stg, or prod.
    Type: String
    AllowedValues:
      - dev
      - stg
      - prod
    Default: dev

Mappings: 
  EnvMap: 
    dev: 
      DynamoDbEndpoint: "http://dev:8000"
    stg: 
      DynamoDbEndpoint: "http://stg:8000"
    prod: 
      DynamoDbEndpoint: "http://prod:8000"

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      FunctionName: HelloWorld
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Events:
        HelloWorld:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: get
      Environment:
        Variables:
          DYNAMODB_ENDPOINT: !FindInMap [EnvMap, !Ref Env, DynamoDbEndpoint]

  YourTableName:
    Type: AWS::DynamoDB::Table
    Properties: 
      TableName: your-table-name
      BillingMode: PAY_PER_REQUEST # On-Demand Mode.
      AttributeDefinitions: 
        - AttributeName: id
          AttributeType: S
        - AttributeName: type
          AttributeType: N
        - AttributeName: update-date
          AttributeType: S
        - AttributeName: update-user
          AttributeType: S
      KeySchema: 
        - AttributeName: id
          KeyType: HASH
        - AttributeName: type
          KeyType: RANGE
      GlobalSecondaryIndexes:
        - IndexName: "GSI_1"
          KeySchema:
          - AttributeName: update-date
            KeyType: "HASH"
          - AttributeName: update-user
            KeyType: RANGE
          Projection:
            ProjectionType: ALL

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn

分割後のテンプレート1 (メイン)

分割したファイルを利用するには
Type: AWS::Serverless::Application
リソースを利用します。
「 Parameters」セクションで分割したテンプレートに値を渡す事が可能です。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app

  Sample SAM Template for sam-app

# 入力パラメータ
Parameters:
  Env:
    Description: Enter environment.dev, stg, or prod.
    Type: String
    AllowedValues:
      - dev
      - stg
      - prod
    Default: dev

Mappings: 
  EnvMap: 
    dev: 
      DynamoDbEndpoint: "http://dev:8000"
    stg: 
      DynamoDbEndpoint: "http://stg:8000"
    prod: 
      DynamoDbEndpoint: "http://prod:8000"

Globals:
  Function:
    Timeout: 3

Resources:
  # DynamoDB用のテンプレートは別ファイルで参照
  DynamoDbStack:
    Type: AWS::Serverless::Application
    Properties:
      Location: template_sub/template_dynamodb.yaml
      # 受け渡すパラメータを定義
      Parameters:
        StackName: !Ref AWS::StackName
        Env: !Ref Env

  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: HelloWorld
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
      Environment:
        Variables:
          DYNAMODB_ENDPOINT: !FindInMap [EnvMap, !Ref Env, DynamoDbEndpoint]

Outputs:
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn

分割後のテンプレート2 (DynamoDB)

メインのテンプレートからパラメータを受け取りたい場合は「Parameters」
セクションで受け取る事が出来ます。

# 入力パラメータ
Parameters:
  StackName:
    Type: String
  Env:
    Type: String

Resources:
  YourTableName:
    Type: AWS::DynamoDB::Table
    Properties: 
      TableName: your-table-name
      BillingMode: PAY_PER_REQUEST # On-Demand Mode.
      AttributeDefinitions: 
        - AttributeName: id
          AttributeType: S
        - AttributeName: type
          AttributeType: N
        - AttributeName: update-date
          AttributeType: S
        - AttributeName: update-user
          AttributeType: S
      KeySchema: 
        - AttributeName: id
          KeyType: HASH
        - AttributeName: type
          KeyType: RANGE
      GlobalSecondaryIndexes:
        - IndexName: "GSI_1"
          KeySchema:
          - AttributeName: update-date
            KeyType: "HASH"
          - AttributeName: update-user
            KeyType: RANGE
          Projection:
            ProjectionType: ALL

deployの実行

ネストされたテンプレートを利用するためには
sam deploy の実行時にCAPABILITY_AUTO_EXPANDのオプションを付与する必要があります。
今回は毎度入力しなくて良いように、「samconfig.toml」にオプションを追加。

capabilities = "CAPABILITY_IAM CAPABILITY_AUTO_EXPAND"

以上

タイトルとURLをコピーしました