共通のテンプレートを使用して構築した既存の複数の CloudFormation スタックをネストで管理してみる

共通のテンプレートを使用して構築した既存の複数の CloudFormation スタックをネストで管理してみる

リソースのインポートを活用し既存のスタックをネスト化してみました
Clock Icon2025.03.09

クラウド事業本部の平木です!

皆さんは複数ある CloudFormation をどのように管理していますか?

クロスアカウントやクロスリージョンの場合は CloudFormation StackSets を活用したり、
CLI で更新するスクリプトを組んだり様々かと思います。

CloudFormation ではネスト化することで共通したリソースについてはモジュール化し、テンプレートを再利用しやすくなります。

今回は、共通したリソースを同じテンプレートで作成していた既存の複数の独立した CloudFormation スタックを、リソースのインポート機能を活用しネスト化してみたのでその手順をご紹介します。

流れ

イメージとしては以下です。

keisuke-poc-CFn-Nest-ols-new

ProjectX と ProjectY というプロジェクトではそれぞれ共通のテンプレートを使用し、
スタック X とスタック Y という CloudFormation を作成していました。

共通テンプレートを更新したいときに、このままだとそれぞれで更新作業が必要になり、
大変になってしまうのでネスト化することで解決しようと思いました。

実際にやってみる

既存の状態

共通テンプレートでは以下のような簡単な VPC を構築するテンプレートを使用しました。

NestChild.yml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'CloudFormation template to create a VPC'

Parameters:
  VpcName:
    Type: String
    Description: Name for the VPC

  VpcCidr:
    Type: String
    Description: CIDR block for the VPC
    AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})'
    ConstraintDescription: Must be a valid CIDR block format (x.x.x.x/x)

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Ref VpcName

Outputs:
  VpcId:
    Description: VPC ID
    Value: !Ref VPC

パラメータは以下のような形です。

↓プロジェクト X

keisuke-devio-2025-03-09-15-39-53

↓プロジェクト Y

keisuke-devio-2025-03-09-15-40-51

親スタックの作成

ネストの親スタック用のテンプレートを作成します。

ネスト化する際は、リソースのインポート

以下はサンプルです。

NestParent.yml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Parent CloudFormation template to create VPCs for ProjectX and ProjectY'

Resources:
  ProjectXVpcStack:
    Type: AWS::CloudFormation::Stack
    DeletionPolicy: Retain
    Properties:
      TemplateURL: '<S3バケットにアップロードしたテンプレートのオブジェクトURL>'
      Parameters:
        VpcName: 'ProjectX-VPC'
        VpcCidr: '10.0.0.0/16'

  ProjectYVpcStack:
    Type: AWS::CloudFormation::Stack
    DeletionPolicy: Retain
    Properties:
      TemplateURL: '<S3バケットにアップロードしたテンプレートのオブジェクトURL>'
      Parameters:
        VpcName: 'ProjectY-VPC'
        VpcCidr: '10.1.0.0/16'

気を付ける点としては 3 点です。

  • DeletionPolicyを設定すること
    • DeletionPolicy を付与しないとエラーとなります。 ※あとで解除できます
  • 事前に S3 に子スタックとなるスタックで使用したテンプレートを S3 にアップロードする または TemplateBody のプロパティでテンプレートの中身を記述する
  • Parametersには既存のスタックを作成する際に指定したパラメータを記述する
    • Parameters の記述が一致しないまたは指定しない場合、一致しないことでインポート時にエラーが発生します

テンプレートが準備できたら実際にリソースのインポートを始めます。

CloudFormation のコンソール画面において、
アクションから「既存のリソースを使用 (リソースをインポート)」を押します。

keisuke-devio-2025-03-09-15-54-01

「次へ」を押します。

keisuke-devio-2025-03-09-15-55-28

親スタック用のテンプレートをアップロードし次へを押します。

keisuke-devio-2025-03-09-15-56-56

インポートするスタックのスタック ID をそれぞれ入力します。

スタック ID は、各スタックの「スタックの情報」から参照できます。

keisuke-devio-2025-03-09-16-01-46

任意のスタック名を入力し、次へを押します。

keisuke-devio-2025-03-09-16-01-14

変更の項目が表示され、インポート対象が問題なければ「リソースをインポート」を押します。

keisuke-devio-2025-03-09-16-02-57

少しばかり時間が経つとステータスがIMPORT_COMPLETEに変わり、既存のスタックにネストされたというフラグが付いているのが分かります。

keisuke-devio-2025-03-09-16-04-43

これで完了です。

DeletionPolicy をなくしたい場合

スタックをインポートする場合、DeletionPolicy が必要となります。
通常であればその運用でも問題ないかと思いますが、当然 DeletionPolicy が適用されている以上、親スタック削除時には子スタックは残ります。

keisuke-devio-2025-03-09-16-14-24

ただ、DeletionPolicy の適用をなくしたい時もあるかと思います。

その際はシンプルに親スタックのテンプレートにて後から DeletionPolicy の記述を削除し、スタック更新することで削除可能になります。

コメントアウトをしスタックを更新後、親スタックの削除と一緒に子スタックも削除できました。

keisuke-devio-2025-03-09-16-22-27

keisuke-devio-2025-03-09-16-25-36

DeletionPolicy を適用することで誤って親スタックを削除してしまっても子スタックを残しておくことができるため本番稼働している場合にはそのままにしておくと良いかもしれません。

参考

おわりに

今回は既存のスタックをネスト化するためにインポートしてみました。

ネスト化することで共通のテンプレートを修正し、親スタックのみ更新することで全ての子スタックを更新可能となるのでぜひ同じような環境の方いましたらぜひネスト化してみてください。

この記事がどなたかの役に立つと嬉しいです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.