10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CloudFormationの nested stack が使いづらい件

Last updated at Posted at 2019-11-29

一言で言うと 子スタックのチェンジセットが操作しづらい ので使いづらい。
いろいろ検索してみたけど日本語の結果が出てこなかったので検索用メモとして。
(こういうときにつけるタグってなんだろう。。。)

nested stack1 とは

ネストされたスタックは、他のスタックの一部として作成されたスタックです。

複数のスタックを連携させる方法としては出力値を用いたクロススタック参照2などもあるが、それよりももっと直接にスタックの親子関係を構築する仕組み。

使用例

以下のような複数のテンプレートがあるときに、

  • parent.yaml に対して aws cloudformation package を実行する
  • package処理結果のyamlに対して aws cloudformation deploy を実行する

という手順を踏むことで、子テンプレートの内容を含めてまとめて parent.yaml のスタックでリソース管理できる。

parent.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: parent template

# 他のスタックをリソースとして定義
Resources:
  ChildStack1:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      TemplateURL: ./child1.yaml

Outputs:
  Child1Policy:
    Description: child 1 policy
    Value: !GetAtt ChildStack1.Outputs.Policy # 子スタックの出力値を参照できる
    Export:
      Name: child1-policy
child1.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: child 1 stack

# サンプルとしてIAMポリシーを定義
Resources:
  SamplePolicy:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      Description: SamplePolicy
      Path: /
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: lambda:InvokeFunction
            Resource: "*"

Outputs:
  Policy:
    Description: child 1 policy
    Value: !Ref SamplePolicy
実行手順
# 関連リソースをパッケージング
# -- child1.yaml が関連リソースとしてS3へアップロードされる
# -- アップ先のバケットは先に用意しておくこと
$ aws cloudformation package --template-file parent.yaml \
      --s3-bucket sample-bucket-1234567890 \
      --output-template-file packaged-parent.yaml

# スタックにチェンジセットを作成(まだリソース作成は行わない)
$ aws cloudformation deploy --no-execute-changeset \
      --template-file packaged-parent.yaml \
      --stack-name sample-stack

[追記]
この例ではIAMを操作しているため、リソースの作成時には --capabilities CAPABILITY_IAM3 を指定しないとエラーになる。
具体的には --no-execute-changeset をつけない aws cloudformation deploy で変更を反映する場合に上記の引数が必要。

これを実行すると sample-stackに以下のチェンジセットが作成される。

nested-stack-changeset.png

親スタックからは子スタックが新規リソース(更新時は変更リソース)として扱われる。

問題点

この時点では ChildStack1 の管理スタックはまだ作成されておらず、このチェンジセットを適用すると child1.yaml の内容はチェンジセットなしに直接適用される。
更新についても同様で、aws cloudformation deploy --no-execute-changeset で作成されるチェンジセットで確認できるのは子スタックが変更されるという内容のみで、子のチェンジセット内で何が変更されるかはわからない という状況になる。

対応方法

[20210923追記]
@tsuchikazu さんより情報提供いただきました
2020年11月に AWS CloudFormation 変更セットがネストされたスタックのサポートを開始 がアナウンスされて、子スタックの変更セットが親スタックから参照できるようになりました。

使用例

事前にchild変更前の内容を適用
# 子スタックをパッケージング
$ aws cloudformation package \
    --template-file parent.yaml \
    --output-template-file packaged-parent.yaml \
    --s3-bucket sample-bucket-1234567890

# スタックを作成、即時反映
$ aws cloudformation deploy \
    --template-file packaged-parent.yaml \
    --stack-name sample-stack \
    --capabilities CAPABILITY_IAM
child1.yamlの修正、IAMポリシーに権限を追加してみた
AWSTemplateFormatVersion: 2010-09-09
Description: child 1 stack

Resources:
  SamplePolicy:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      Description: SamplePolicy
      Path: /
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action:
              - lambda:InvokeFunction
              - lambda:ListFunctions
            Resource: "*"

Outputs:
  Policy:
    Description: child 1 policy
    Value: !Ref SamplePolicy
チェンジセットを作成する
# 再度子スタックの定義をパッケージング
$ aws cloudformation package \
    --template-file parent.yaml \
    --output-template-file packaged-parent.yaml \
    --s3-bucket sample-bucket-1234567890

# ネストスタックを含むチェンジセットを作成
# Note: この時点で CAPABILITIES_IAM に許可を出さないとチェンジセットがエラーになる
$ aws cloudformation create-change-set \
    --stack-name sample-stack \
    --change-set-name sample-stack-includes \
    --template-body file://packaged-parent.yaml \
    --include-nested-stacks \
    --capabilities CAPABILITY_IAM

create-change-set--include-nested-stacks をつけることで子スタックもまとめてチェンジセットを作ることができる。
※引数を付けないとデフォルトでは子スタックの変更セットは作成されないので注意

こうするとブラウザからチェンジセットを表示すると以下のようになる。

  • 親スタックのチェンジセット
    image.png

  • 子スタックのチェンジセット(リンク先)
    image.png

物足りない点

一応仕組みとしてはネストされたスタックの変更セットが扱えるようにはなったが、もう少しここなんとかしてほしい感があるところについて。

aws cloudformation deploy で使えない

aws cloudformation deploy でこの機能に相当する引数が見当たらないため、現時点では aws cloudformation create-change-set でチェンジセットを明示的に作成する手間がある。
できれば aws cloudformation package で関連リソースをアップしたら aws cloudformation deploy でチェンジセットも実行も簡単に行えるようにしたい。
(むしろ sam deploy [--no-execute-changeset] でもっと簡単に(ry )

ここは調査不足かもしれないので情報あったらコメお願いします。

チェンジセットの反映分が一覧して見れない

マネジメントコンソール上の表示でも aws cloudformation describe-change-set の出力でも、親チェンジセットと子チェンジセットは別物の扱いなので、一覧して表示する仕組みがない。
スタック一覧みたいに ネスト表示 のオプションで子チェンジセットの変更内容も親側でまとめて表示できるともっと便利になると思うのだが(´・ω・`)

関連情報

英語圏だと関係しそうな情報が出てきた。

以下はネストされたスタックのチェンジセットについて

  • Change sets for nested stacks
    • ネストされたスタックのチェンジセットをUIやCLIから操作する方法など
    • 子スタックの変更後にパッケージングしないと動かなかったが、その点の記載がなくて最初どうやって差分を用意するのかについてしばらく悩んだ
  1. AWS - ネストされたスタックの操作

  2. AWS - チュートリアル: 別の AWS CloudFormation スタックのリソース出力を参照する

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

10
6
2

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
10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?