テンプレート

セクション

セクション説明
AWSTemplateFormatVersionバージョン指定
Description説明
Metadata追加情報
Parameters入力パラメータ
Mappings固定値マッピング
Conditions条件分岐
Transform特殊変換
Resourcesリソース定義
Outputs出力値
AWSTemplateFormatVersion セクション
AWSTemplateFormatVersion: '2010-09-09'
Description セクション
Description: 'Web サーバー環境構築テンプレート (VPC + EC2 + RDS)'

# 複数行の場合
Description: |
  本番環境用 Web アプリケーション
  - VPC (10.0.0.0/16)
  - EC2 Auto Scaling
  - RDS MySQL
Metadata セクション
# パラメータのグループ化
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: '環境設定'
        Parameters:
          - EnvironmentType
          - ProjectName
      - Label:
          default: 'ネットワーク設定'
        Parameters:
          - VpcCIDR
          - SubnetCIDR
    
    ParameterLabels:
      EnvironmentType:
        default: '環境 (dev/stg/prd)'
      VpcCIDR:
        default: 'VPC CIDR ブロック'
Parameters セクション
Parameters:
  # 環境タイプ
  EnvironmentType:
    Type: String
    Default: dev
    AllowedValues: [dev, stg, prd]
    Description: '環境を選択'
  
  # プロジェクト名
  ProjectName:
    Type: String
    Default: myapp
    MinLength: 3
    MaxLength: 20
    AllowedPattern: '^[a-z0-9-]+$'
    Description: 'プロジェクト名(小文字英数字とハイフン)'
  
  # VPC CIDR
  VpcCIDR:
    Type: String
    Default: 10.0.0.0/16
    AllowedPattern: '^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$'
    Description: 'VPC CIDR (例: 10.0.0.0/16)'
  
  # EC2 キーペア
  KeyName:
    Type: AWS::EC2::KeyPair::KeyName
    Description: 'EC2 接続用キーペア'
  
  # DB パスワード
  DBPassword:
    Type: String
    NoEcho: true
    MinLength: 8
    MaxLength: 41
    Description: 'DB パスワード (8文字以上)'
  
  # インスタンス数
  InstanceCount:
    Type: Number
    Default: 2
    MinValue: 1
    MaxValue: 10
    Description: 'EC2 台数 (1-10)'
Mappings セクション
Mappings:
  EnvironmentMap:
    dev:
      InstanceType: t3.micro
      DBInstanceClass: db.t3.micro
      MultiAZ: false
    stg:
      InstanceType: t3.small
      DBInstanceClass: db.t3.small
      MultiAZ: false
    prd:
      InstanceType: t3.large
      DBInstanceClass: db.t3.large
      MultiAZ: true

Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !FindInMap [EnvironmentMap, !Ref EnvironmentType, InstanceType]
Conditions セクション
Parameters:
  EnvironmentType:
    Type: String
    AllowedValues: [dev, stg, prd]

Conditions:
  IsProduction: !Equals [!Ref EnvironmentType, prd]
  IsNotProduction: !Not [!Equals [!Ref EnvironmentType, prd]]

Resources:
  # 本番のみ作成
  ProductionInstance:
    Type: AWS::EC2::Instance
    Condition: IsProduction
    Properties:
      InstanceType: t3.large
  
  # リソースのプロパティで条件適用
  Database:
    Type: AWS::RDS::DBInstance
    Properties:
      MultiAZ: !If [IsProduction, true, false]
      BackupRetentionPeriod: !If [IsProduction, 7, 1]
Transform セクション
Transform: AWS::Serverless-2016-10-31

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: python3.9
      CodeUri: s3://my-bucket/code.zip
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /hello
            Method: get
Resources セクション
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: my-vpc
  
  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: public-subnet
  
  InternetGateway:
    Type: AWS::EC2::InternetGateway
  
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  
  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
  
  Route:
    Type: AWS::EC2::Route
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  
  SubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref RouteTable
Outputs セクション
Outputs:
  # VPC ID(エクスポート付き)
  VPCId:
    Description: 'VPC ID'
    Value: !Ref VPC
    Export:
      Name: !Sub '${AWS::StackName}-VpcId'
  
  # サブネット ID
  PublicSubnetId:
    Description: 'Public Subnet ID'
    Value: !Ref PublicSubnet
    Export:
      Name: !Sub '${AWS::StackName}-PublicSubnetId'
  
  # EC2 パブリック IP
  WebServerPublicIP:
    Description: 'Web Server Public IP'
    Value: !GetAtt WebServer.PublicIp
  
  # Web サーバー URL
  WebServerURL:
    Description: 'Web Server URL'
    Value: !Sub 'http://${WebServer.PublicIp}'
  
  # DB エンドポイント
  DBEndpoint:
    Description: 'Database Endpoint'
    Value: !GetAtt Database.Endpoint.Address
  
  # S3 バケット名
  BucketName:
    Description: 'S3 Bucket Name'
    Value: !Ref DataBucket
  
  # ALB DNS
  LoadBalancerDNS:
    Description: 'Load Balancer DNS'
    Value: !GetAtt ALB.DNSName
  
  # スタック情報
  StackRegion:
    Description: 'Stack Region'
    Value: !Ref 'AWS::Region'

変数のスコープ

スコープ定義適用範囲
テンプレートセクションParameters セクション
Mappings セクション
Conditions セクション
同一テンプレートファイル内
リソースプロパティProperties ブロックProperties ブロック内のみ
ネストスタック【親テンプレート】
ネストスタックリソースのParameters プロパティ
【子テンプレート】
Parameters セクション
各テンプレートで独立

ネストスタック(ParametersとOutputsの受け渡し)

サンプルコードのディレクトリ構造
project-root/
  |
  +- environments/
  |  |
  |  +- prd/
  |  |   |
  |  |   +- main.yaml              # 親テンプレート
  |  |   +- parameters.json        # パラメータファイル
  |  |
  +- templates/
      |
      +- storage/
          |
          +- s3.yaml               # 子テンプレート

親テンプレート

environments/prd/main.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Main Stack'

# 親テンプレートのパラメータ
Parameters:
  ProjectName:
    Type: String
    Description: Project name

Resources:
  # ネストスタック1: ログ用バケット
  LogBucket:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/my-templates/templates/storage/s3.yaml
      Parameters:
        BucketName: !Sub '${ProjectName}-logs'
        EnableVersioning: 'false'
  
  # ネストスタック2: データ用バケット
  DataBucket:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/my-templates/templates/storage/s3.yaml
      Parameters:
        BucketName: !Sub '${ProjectName}-data'
        EnableVersioning: 'true'

# 子スタックの出力を集約
Outputs:
  LogBucketName:
    Description: Log Bucket Name
    Value: !GetAtt LogBucket.Outputs.BucketName
  
  LogBucketArn:
    Description: Log Bucket ARN
    Value: !GetAtt LogBucket.Outputs.BucketArn
  
  DataBucketName:
    Description: Data Bucket Name
    Value: !GetAtt DataBucket.Outputs.BucketName
  
  DataBucketArn:
    Description: Data Bucket ARN
    Value: !GetAtt DataBucket.Outputs.BucketArn
environments/prd/parameters.json
[
  {
    "ParameterKey": "ProjectName",
    "ParameterValue": "myapp"
  }
]

子テンプレート

templates/storage/s3.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'S3 Bucket Template'

# 親から受け取るパラメータ
Parameters:
  BucketName:
    Type: String
    Description: S3 bucket name
  
  EnableVersioning:
    Type: String
    Description: Enable versioning
    Default: 'false'
    AllowedValues:
      - 'true'
      - 'false'

# リソース定義
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
      VersioningConfiguration:
        Status: !If
          - !Equals [!Ref EnableVersioning, 'true']
          - Enabled
          - Suspended

# 親に返す出力
Outputs:
  BucketName:
    Description: Bucket Name
    Value: !Ref S3Bucket
  
  BucketArn:
    Description: Bucket ARN
    Value: !GetAtt S3Bucket.Arn