はじめに
今回は、以下の記事で作成した「単一スタック」のテンプレートを、「ネストスタック」に書き換えてデプロイしてみました。
「クロススタック」の記事もぜひご参照ください。
ネストスタックとは
CloudFormationの「ネストスタック(Nested Stack)」は、1つのスタックの中で別のテンプレートを呼び出す仕組みです。
あらかじめs3に保存した子スタックのテンプレートを親スタックが呼び出します。
すべて「1つのスタック」として扱われます。
Root Stack(親)
├ Network Stack(子)
└ App Stack(子)
書き方の例
Resources:
NetworkStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/.../network.yaml
AppStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/.../app.yaml
Resources:
myVPC:
Type: AWS::EC2::VPC
スタック間の値の受け渡しは、親を仲介するようなかたちになります。
Properties:
Parameters:
VpcId: !GetAtt NetworkStack.Outputs.VpcId
Outputs:
VpcId:
Value: !Ref myVPC
クロススタックとの違い
| 項目 | ネストスタック | クロススタック |
|---|---|---|
| 関係 | 親子(強い) | 独立(弱い) |
| デプロイ | 一括 | 個別 |
| 依存管理 | 自動 | 手動 |
| 再利用性 | 中 | 高 |
| 柔軟性 | 低 | 高 |
ネストスタックには
・テンプレートを分割することにより可読性があがる
・テンプレート間の依存関係がわかりやすい
・依存関係を自動管理するためExport/Importが不要
・一括でデプロイできる
といったメリットがあります。
一方でクロススタックと比較した場合に
・個別更新ができない
・リソースが増えるにしたがって構造が複雑になる
・一部でも失敗すると全部ロールバックされるため影響範囲が大きい
・S3にテンプレ配置が必要(TemplateURL必須)
といったデメリットがあります。
ネストスタックに書き換えてみた
今回は「ルートスタック(root.yaml)」と「ネットワークスタック(network.yaml)」と「アプリスタック(app.yaml)」の3つで構成しました。
AWSTemplateFormatVersion: "2010-09-09"
Description: Root Stack
Resources:
NetworkStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://your-bucket.s3.amazonaws.com/network.yaml
AppStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://your-bucket.s3.amazonaws.com/app.yaml
Parameters:
SubnetId: !GetAtt NetworkStack.Outputs.SubnetId
SecurityGroupId: !GetAtt NetworkStack.Outputs.SecurityGroupId
AWSTemplateFormatVersion: "2010-09-09"
Description: Network Infrastructure
Resources:
myVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
- Key: Name
Value: test-vpc
myInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: test-igw
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref myVPC
InternetGatewayId: !Ref myInternetGateway
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref myVPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: ap-northeast-1a
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: public-subnet-a
PublicRouteTableA:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref myVPC
Tags:
- Key: Name
Value: public-rt-a
PublicRouteA:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTableA
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref myInternetGateway
PublicSubnetAssociationA:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetA
RouteTableId: !Ref PublicRouteTableA
PublicSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP from anywhere
VpcId: !Ref myVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: public-sg
Outputs:
SubnetId:
Value: !Ref PublicSubnetA
SecurityGroupId:
Value: !Ref PublicSecurityGroup
AWSTemplateFormatVersion: "2010-09-09"
Description: App Infrastructure
Parameters:
SubnetId:
Type: String
SecurityGroupId:
Type: String
InstanceTypeParameter:
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- t3.micro
- t3.small
Description: Select EC2 instance type
Mappings:
RegionMap:
ap-northeast-1:
AMI: ami-007ea17fb9422e93f
ap-northeast-2:
AMI: ami-0ada8527e6dc686a3
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", AMI]
InstanceType: !Ref InstanceTypeParameter
SubnetId: !Ref SubnetId
SecurityGroupIds:
- !Ref SecurityGroupId
UserData:
Fn::Base64: |
#!/bin/bash
dnf update -y
dnf install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello from EC2!!!!!</h1>" > /var/www/html/index.html
Tags:
- Key: Name
Value: test-ec2
デプロイする
まずは子スタックのテンプレートをs3バケットに格納します。
新しく専用のバケットを作成しアップロードすることが推奨されますが、今回は割愛します。
アップロードが完了したら、そのファイルのパスをルートスタックのテンプレートに入力します。
①CloudFormation > スタック に移動します。
②「スタックの作成」タブを開きます。
③新しいリソースを使用(標準)を押します。
①既存のテンプレートを選択を選択します。
②テンプレートファイルのアップロードを選択します
③ルートスタックのテンプレートファイルをアップロードします。
④次へを押します。
①「スタック名」を入力します。
②次へを押します。
「スタックオプションの設定」はすべてデフォルトのまま進みますが、「AWS::CloudFormation::Stack」を使用する場合は警告を確認する必要があります。
①警告にチェックを入れます。
②次へを押します。
「確認して作成」画面の内容を確認して、送信を押します。
しばらく待つと、ネストされたスタックも無事に作成されました。
作成されたEC2の「パブリック IPv4 アドレス」にアクセスすると、無事にWebサイトが表示されました!
ネストスタックを更新する場合
子スタックのみを更新したい場合は、更新した子スタックのテンプレートをs3にアップロードした後、ルートスタックのテンプレートを更新する必要があります。
ネストスタックを削除する
ネストスタックを削除する場合は、ルートスタックを削除するだけで完了します。





