🐱

Cfnスタック間でのパラメータ受け渡し方法の比較

2023/11/29に公開

背景

  • 最近関わっている案件でCloudFormation(Cfn)テンプレートを使ってAWSリソースの管理を行っています。
  • 最近管理対象のリソース(スタック)が増え、手入力で行っていたパラメータの設定を、スタック間で受け渡しを行えるようにしたくなってきました。
  • スタック間でのパラメータの受け渡し方法は複数あるようなので、それぞれの利用方法とメリット・デメリットを調べ比較してみました。

比較

1. Systems Manager Parameter Store(SSM) / Secrets Manager(SM) の値を参照する

利用方法

  • Systems Manager Parameter Store / Secrets Managerに手動でパラメータやシークレット情報を登録する。
  • CfnテンプレートのParametersセクションでパラメータもしくはシークレットをデフォルト値として参照し設定する。
  • CfnテンプレートのResourcesセクションにParameterリソースを記載し、任意のリソースの設定値をSSMやSMに登録し、他テンプレートから参照できるようにする。

メリット

  • パラメータの値をセキュアかつテンプレート間で疎結合に管理ができる。
  • リソースの削除やパラメータやシークレットの設定変更がしやすい。
  • テンプレート中の可読性が高い。

デメリット

  • テンプレートの記述量が増える。
  • Systems Manager Parameter Store / Secrets Managerを利用する必要があり、コストがかかる場合がある。

コード例

入力

Parameters
    TableName: # SSMパラメータストアの型でパラメータとして設定
        Type: AWS::SSM::Parameter::Value<String>
        Default: '/dev/hoge/dynamodb/user/table-name'

Resources:
    Function:
        ....
        Environment:
            Variables:
                TABLE_NAME: !Ref TableName # 使いたいところでパラメータを参照

出力

UserTable: # 対象リソースを定義
    Type: AWS::DynamoDB::Table
    Properties:
        TableName: dev-hoge-user

TableNameParameter: # 対象リソースの属性をSSMパラメータストアに設定
    Type: AWS::SSM::Parameter
    Properties:
        Name: '/dev/hoge/dynamodb/user/table-name'
        Type: String
        Value: !Ref UserTable

2. Systems Manager Parameter Store / Secrets Manager を利用し動的参照を行う

メリット

  • ほぼ1と同じ。Parametersの記載が比較的シンプル書ける。

デメリット

  • ほぼ1と同じ。

コード例

入力

Parameters
    TableName: # パラメータとして設定
        Type: String
        Default:  '{{resolve:ssm:/dev/hoge/dynamodb/user/table-name}}' # 動的参照を利用

Resources:
    Function:
        ....
        Environment:
            Variables:
                TABLE_NAME: !Ref TableName # 使いたいところでパラメータを参照

出力

UserTable: # 対象リソースを定義
    Type: AWS::DynamoDB::Table
    Properties:
        TableName: dev-hoge-user

TableNameParameter: # 対象リソースの属性をSSMパラメータストアに設定
    Type: AWS::SSM::Parameter
    Properties:
        Name: '/dev/hoge/dynamodb/user/table-name'
        Type: String
        Value: !Ref UserTable

3. クロススタック参照を行う

メリット

  • コードの記述がシンプルで記述量が少なくて済む。

デメリット

  • リソース同士が密結合になってしまう。
    • 参照しているスタックがあると参照元のスタックで変更や削除ができなくなる。
    • アカウント内、リージョン内で重複しないようにパラメータ名を考え管理する必要がある。
    • 機密性の高い情報を格納できない。一部のシークレット等は別途SSMやSMで管理する必要がある。

コード例

入力

Resources:
    Function:
        ....
        Environment:
            Variables:
                TABLE_NAME: !ImportValue UserTableName # 使いたいところでパラメータを参照

出力

UserTable: # 対象リソースを定義
    Type: AWS::DynamoDB::Table
    Properties:
        TableName: dev-hoge-user

Outputs:
    UserTableName:
        Value: !Ref UserTable
        Export:
            Name: UserTableName # スタック全体で一意な値を設定

結論

  • 基本的に2. 動的参照を使う。
  • 業務利用されるシステムや中〜大規模のプロジェクトでスタック数が多い場合は、2. 動的参照を使うのが良い。
    • パラメータやシークレットをセキュアに管理できて、かつスタック間も疎結合にできるため管理がしやすいため。
    • 1.か2.かという問題だが、AWS公式やネットの情報を見る限り、最近は動的参照の利用が推奨されていそう。
  • 個人開発レベルで管理対象のスタックが少なく、機密情報も特にない場合は 3.クロススタック参照を使うと管理が楽で良さそう。

参考

SSMパラメータストアからの参照("非"動的参照)

https://blog.serverworks.co.jp/cloudformation-ssm-ami-nest-stack

動的参照

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/dynamic-references.html
https://dev.classmethod.jp/articles/cfn-dynamic-references-support-latest/
https://www.tech-nn.com/cfn-ssmparameter-stack-ref/

Outputs - ImportValue

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html

CloudFormation

https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2023_CloudFormation-1_0731_v1.pdf

Discussion