AWS SAM でネストされたスタックを扱う方法 ~パラメータ編~

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

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

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

本記事は AWS Serverless Application Model(以下、SAM) でネストされたスタックを定義する際のパラメータの扱い方について解説していきます。

以下の 2 本のブログを読んでいただいていると、以後の説明に役立つかと思いますのでご興味がある方はぜひご一読ください。

blog.serverworks.co.jp

blog.serverworks.co.jp

前提(初期化 ~ ベースの用意)

今回は、AWS が用意している SAM テンプレートのHello World Exampleをベースに

親スタックとなる template.yaml ファイルへのリソースの追加と子スタックとなる s3.yaml の作成を実施します。(以下ブログで作成したものと同等)

以下に簡単に説明は致しますが、詳細な説明が気になる方はぜひ当記事をご覧いただければと思います。

blog.serverworks.co.jp

template.yaml(親) の Resource セクションにて AWS::CloudFormation::Stack リソースを定義します。

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

s3.yaml(子)では S3 バケットを 1 つ定義してあります。

AWSTemplateFormatVersion: "2010-09-09"

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

template.yaml へのパラメータの渡し方

再三になりますが、この章で行うことは以下の記事の内容とほぼ同じです。

詳細な説明はぜひ当記事をのぞいていただければと思います。

blog.serverworks.co.jp

template.yaml に Parameters セクションを追加する

template.yaml に以下の Parameters セクションを追加します。

...
Parameters:
  BucketName:
    Type: String

samconfig.toml ファイルにparameter_overridesを記述する

samconfig.toml ファイルに以下の項目を追加します。

parameter_overrides = "BucketName=sam-param-test",

これで template.yaml(親)ファイルにパラメータを渡す準備が完了しました。

親スタックから子スタックにパラメータを渡す

ここからは本題の親から子へのパラメータの渡し方を解説します。

template.yaml(親)の変更

まず、template.yaml(親)ファイルで定義した AWS::CloudFormation::Stack リソースにParametersプロパティを追加します。

そのParametersプロパティの中でParameterKey:ParameterValueの形でパラメータを渡します。

今回は samconfig.toml から受け取るパラメータをそのまま子に伝搬させます。

AWSTemplateFormatVersion: "2010-09-09"
...
Parameters:
  BucketName:
    Type: String
...
Resources:
...
S3:
  Type: AWS::CloudFormation::Stack
  Properties:
    TemplateURL: s3.yaml
    Parameters:
      BucketName: !Ref BucketName

s3.yaml(子)の変更

s3.yaml に以下の Parameters セクションを追加し、そのパラメータを使用したい箇所で Ref 関数や Sub 関数を使用して呼び出します。

...
Parameters:
  BucketName:
    Type: String
...
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "${BucketName}-${AWS::AccountId}"

デプロイしてみた

ここまでの内容を以下のコマンドを実行してデプロイしてみます。

sam deploy

AWS マネジメントコンソールを覗くと ネストされた S3 スタックにて S3 バケットが渡したパラメータを使用した名前になっていることが確認できました。

子スタックの OutPuts を別の子スタックへ渡す

ここからは前章までの内容をもとに子スタックの OutPuts を別の子スタックに渡す方法について解説します。

想定するケースとして、s3.yaml(既存)で定義したバケット名を IAM Role を定義する iam.yaml(新規作成)で使用したいものとします。

s3.yaml の変更

まず、s3.yaml ファイルに OutPuts セクションを追加してバケット名を出力するよう変更します。

Outputs:
  BucketName:
    Value: !Ref S3Bucket

OutPuts セクションでは論理 ID(今回の例だとBucketName)と Value(今回の例だと!Ref S3Bucket)をセットで出力します。

詳しくは OutPuts の公式のリファレンスを参照ください。

また今回の出力値はバケット名としたいので、CloudFormation のAWS::S3::Bucketリソースのリファレンスを確認して戻り値がバケット名であることを確認します。

iam.yaml の作成

iam.yaml ファイルはパラメータを受け取って使用するだけですのでここまでの内容で作成することができます。

ファイル内容は以下のように作成しました。

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  BucketName:
    Type: String

Resources:
  SamSampleRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: S3Access
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                Resource: !Sub "arn:aws:s3:::${BucketName}/*"

作成した S3 バケットへの GetObject を許可する IAM Role を定義しています。

template.yaml の変更

s3.yaml からの OutPuts を iam.yaml のスタックにパラメータとして渡してあげます。

...
Resource:
...
IAM:
  Type: AWS::CloudFormation::Stack
  Properties:
    TemplateURL: iam.yaml
    Parameters:
      BucketName: !GetAtt S3.Outputs.BucketName

これで s3.yaml の OutPuts を iam.yaml に渡すことができるようになりました。

デプロイしてみる

ここまでの内容を以下のコマンドを実行してデプロイしてみます。

sam deploy

AWS マネジメントコンソールを覗くと、iam.yaml に渡されたバケット名が IAM Policy の対象リソースで使用されているのが確認できました。

終わりに

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

本記事では SAM のネストされたスタックでパラメータを受け渡しする方法について解説しました。

本記事が SAM を用いた効率的なアプリケーションの開発の一助となれれば幸いです。

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

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

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