AWS SAM でネストされたスタックを扱う方法 ~概要編~

記事タイトルとURLをコピーする

こんにちは、アプリケーションサービス部ディベロップメントサービス 1 課の滝澤です。

本記事をご覧いただきありがとうございます。

本記事は AWS Serverless Application Model(以下、SAM) でネストされたスタックを扱う方法について説明します。

SAM の概要についてはこちらの記事をご覧ください。

blog.serverworks.co.jp

ネストされたスタックの基本

CloudFormation ユーザーガイド ネストされたスタックの操作

ネストされた Stack とは、一つの親 Stack 内に複数の子 Stack を含む CloudFormation の構造です。これにより、リソースや役割ごとなどに独立してファイルを管理することができます。

前提(SAM プロジェクトの初期化)

SAM CLI は執筆時点で最新のversion 1.108.0を使用しています。

今回のベースは AWS が用意しているテンプレートのHello World Exampleを使用することにしました。

以下のコマンドを使用することで対話形式で新しいサーバーレスアプリケーションを初期化することができます。 本質ではないので詳しい説明は割愛します。

sam init
$ sam init

Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
        1 - Hello World Example
        2 - Data processing
        3 - Hello World Example with Powertools for AWS Lambda
        4 - Multi-step workflow
        5 - Scheduled task
        6 - Standalone function
        7 - Serverless API
        8 - Infrastructure event management
        9 - Lambda Response Streaming
        10 - Serverless Connector Hello World Example
        11 - Multi-step workflow with Connectors
        12 - GraphQLApi Hello World Example
        13 - Full Stack
        14 - Lambda EFS example
        15 - Hello World Example With Powertools for AWS Lambda
        16 - DynamoDB Example
        17 - Machine Learning
Template: 1

(以下略)

子スタックの定義

まず、プロジェクトのルートに子スタックとなるテンプレートファイルを作成します。

作成するリソースは Amazon S3 として、ファイル名は s3.yaml と命名します。

AWSTemplateFormatVersion: "2010-09-09"

Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "sam-app-${AWS::AccountId}"

親スタックの定義

親スタックでは、AWS::CloudFormation::Stack を使用して子スタックのテンプレートファイルを指定します。

子スタックを定義しているテンプレートの URL は、プロジェクトのルートからのパスで指定します。

今回はルートに定義しているので s3.yaml で指定しています。

S3:
  Type: AWS::CloudFormation::Stack
  Properties:
    TemplateURL: s3.yaml

デプロイ

sam deploy コマンドを使用してデプロイしてみます。

初めてデプロイするときにプロンプトを用いたガイドを有効にすることができる--guidedオプションもあります。

こちらの記事で詳しく説明していますので興味がある方はぜひご覧ください。

blog.serverworks.co.jp

さて、sam deploy した結果、無事にネストされたスタックをデプロイすることができました。

バケットも無事に作成することができていますね。

注意点

Requires capabilities : [CAPABILITY_AUTO_EXPAND] というエラー

今回紹介した例では、ネストされた子スタックは素の CloudFormation で記述したので問題なくデプロイが完了しました。

しかし、子スタックでも以下のようにサーバーレスのアプリケーションを定義してデプロイした場合、デフォルトだとエラーが出ます。

WSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31

Globals: ...

Resources:
  HelloWorldFunction: ...

エラー内容

Requires capabilities : [CAPABILITY_AUTO_EXPAND]

これは、以下のリファレンスに記載があるように CAPABILITY_AUTO_EXPAND を指定する必要があるのに指定していないために起こります。

1 つまたは複数のネストされたアプリケーションが含まれているアプリケーションでは、CAPABILITY_AUTO_EXPAND を指定する必要があります。

アプリケーションの機能: IAM ロール、リソースポリシー、ネストされたアプリケーションより

対処法

対処法 1:--capabilitiesオプションを使用する

--capabilities オプションで"CAPABILITY_AUTO_EXPAND"を指定してあげましょう。

sam deploy --capabilities "CAPABILITY_AUTO_EXPAND"

※ 追加の capability が必要な場合はここで指定する必要があります。

 sam deploy --capabilities "CAPABILITY_IAM" "CAPABILITY_AUTO_EXPAND"

対処法 2:samcofig.toml

config ファイルに記入する方法です。

毎回オプションで指定する必要がないため、継続してデプロイする必要があればおすすめです。

以下を samconfig.tomlに追加

capabilities ="CAPABILITY_AUTO_EXPAND"

※ こちらも同様に追加の capability が必要な場合はここで指定する必要があります。

capabilities =["CAPABILITY_IAM","CAPABILITY_AUTO_EXPAND"]

終わりに

最後までお読み頂きありがとうございました。

本記事では SAM でネストされたスタックを扱う方法について説明しました。 次回、ネストされたスタックでのパラメータの受け渡しについての記事も執筆予定ですのでぜひそちらもご覧いただければと思います。

本記事が少しでもお役に立てれば幸いです。

滝澤 稜(執筆記事の一覧)

アプリケーションサービス部ディベロップメントサービス1課

2022年に新卒で入社しました。 うどんが大好物です。