0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS CloudFormation】ネストスタックデプロイしてみた

0
Posted at

はじめに

今回は、以下の記事で作成した「単一スタック」のテンプレートを、「ネストスタック」に書き換えてデプロイしてみました。

「クロススタック」の記事もぜひご参照ください。

ネストスタックとは

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

スタック間の値の受け渡しは、親を仲介するようなかたちになります。

親 → 子(Parametersとして渡します)
Properties:
  Parameters:
    VpcId: !GetAtt NetworkStack.Outputs.VpcId
子 → 親(Outputsとして渡します)
Outputs:
  VpcId:
    Value: !Ref myVPC

クロススタックとの違い

項目 ネストスタック クロススタック
関係 親子(強い) 独立(弱い)
デプロイ 一括 個別
依存管理 自動 手動
再利用性
柔軟性

ネストスタックには
・テンプレートを分割することにより可読性があがる
・テンプレート間の依存関係がわかりやすい
・依存関係を自動管理するためExport/Importが不要
・一括でデプロイできる
といったメリットがあります。

一方でクロススタックと比較した場合に
・個別更新ができない
・リソースが増えるにしたがって構造が複雑になる
・一部でも失敗すると全部ロールバックされるため影響範囲が大きい
・S3にテンプレ配置が必要(TemplateURL必須)
といったデメリットがあります。

ネストスタックに書き換えてみた

今回は「ルートスタック(root.yaml)」と「ネットワークスタック(network.yaml)」と「アプリスタック(app.yaml)」の3つで構成しました。

root.yaml
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
network.yaml
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
app.yaml
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 > スタック に移動します。
②「スタックの作成」タブを開きます。
新しいリソースを使用(標準)を押します。

SCR-20260413-bngz.png

既存のテンプレートを選択を選択します。
テンプレートファイルのアップロードを選択します
③ルートスタックのテンプレートファイルをアップロードします。
次へを押します。

SCR-20260413-bnve.png

①「スタック名」を入力します。
次へを押します。

SCR-20260413-bosg.png

「スタックオプションの設定」はすべてデフォルトのまま進みますが、「AWS::CloudFormation::Stack」を使用する場合は警告を確認する必要があります。
①警告にチェックを入れます。
次へを押します。

SCR-20260413-bpli.png

「確認して作成」画面の内容を確認して、送信を押します。

しばらく待つと、ネストされたスタックも無事に作成されました。

SCR-20260413-bqsr.png

作成されたEC2の「パブリック IPv4 アドレス」にアクセスすると、無事にWebサイトが表示されました!

SCR-20260412-ulbj.png

ネストスタックを更新する場合

子スタックのみを更新したい場合は、更新した子スタックのテンプレートをs3にアップロードした後、ルートスタックのテンプレートを更新する必要があります。

ネストスタックを削除する

ネストスタックを削除する場合は、ルートスタックを削除するだけで完了します。

0
2
0

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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?