共通のテンプレートを使用して構築した既存の複数の CloudFormation スタックをネストで管理してみる
クラウド事業本部の平木です!
皆さんは複数ある CloudFormation をどのように管理していますか?
クロスアカウントやクロスリージョンの場合は CloudFormation StackSets を活用したり、
CLI で更新するスクリプトを組んだり様々かと思います。
CloudFormation ではネスト化することで共通したリソースについてはモジュール化し、テンプレートを再利用しやすくなります。
今回は、共通したリソースを同じテンプレートで作成していた既存の複数の独立した CloudFormation スタックを、リソースのインポート機能を活用しネスト化してみたのでその手順をご紹介します。
流れ
イメージとしては以下です。
ProjectX と ProjectY というプロジェクトではそれぞれ共通のテンプレートを使用し、
スタック X とスタック Y という CloudFormation を作成していました。
共通テンプレートを更新したいときに、このままだとそれぞれで更新作業が必要になり、
大変になってしまうのでネスト化することで解決しようと思いました。
実際にやってみる
既存の状態
共通テンプレートでは以下のような簡単な VPC を構築するテンプレートを使用しました。
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
↓プロジェクト Y
親スタックの作成
ネストの親スタック用のテンプレートを作成します。
ネスト化する際は、リソースのインポート
以下はサンプルです。
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 のコンソール画面において、
アクションから「既存のリソースを使用 (リソースをインポート)」を押します。
「次へ」を押します。
親スタック用のテンプレートをアップロードし次へを押します。
インポートするスタックのスタック ID をそれぞれ入力します。
スタック ID は、各スタックの「スタックの情報」から参照できます。
任意のスタック名を入力し、次へを押します。
変更の項目が表示され、インポート対象が問題なければ「リソースをインポート」を押します。
少しばかり時間が経つとステータスがIMPORT_COMPLETE
に変わり、既存のスタックにネストされた
というフラグが付いているのが分かります。
これで完了です。
DeletionPolicy をなくしたい場合
スタックをインポートする場合、DeletionPolicy が必要となります。
通常であればその運用でも問題ないかと思いますが、当然 DeletionPolicy が適用されている以上、親スタック削除時には子スタックは残ります。
ただ、DeletionPolicy の適用をなくしたい時もあるかと思います。
その際はシンプルに親スタックのテンプレートにて後から DeletionPolicy の記述を削除し、スタック更新することで削除可能になります。
コメントアウトをしスタックを更新後、親スタックの削除と一緒に子スタックも削除できました。
DeletionPolicy を適用することで誤って親スタックを削除してしまっても子スタックを残しておくことができるため本番稼働している場合にはそのままにしておくと良いかもしれません。
参考
おわりに
今回は既存のスタックをネスト化するためにインポートしてみました。
ネスト化することで共通のテンプレートを修正し、親スタックのみ更新することで全ての子スタックを更新可能となるのでぜひ同じような環境の方いましたらぜひネスト化してみてください。
この記事がどなたかの役に立つと嬉しいです。