Hikaru's notes

A collection of notes and resources

View the Project on GitHub HikaruMizoe/notes

CloudFormationのMappingsとConditionsの違いについて、公式ドキュメントで確認します。それでは、CloudFormationのMappingsとConditionsの違いを詳しく説明します。

📊 CloudFormation: Mappings vs Conditions の違い

🎯 基本的な違いの概要

項目 Mappings Conditions
目的 静的な値の参照テーブル リソースやプロパティの条件付き制御
データ型 キー・バリューペアの辞書 真偽値(True/False)
使用場所 リソースのプロパティ値 リソースの作成有無、プロパティ値の選択
評価タイミング 値の参照時 スタック作成/更新時
主な用途 環境・リージョン別の値管理 リソースの条件付き作成

📖 1. Mappings(マッピング)

定義と目的

Mappingsセクションは、特定の条件や依存関係に基づいて値を指定するために使用できるキー・バリューペアを作成します。Mappingsの一般的な使用例は、スタックがデプロイされるAWSリージョンに基づいて値を設定することです。これは、AWS::Region擬似パラメータを使用することで実現できます。

構文

Mappings:
  MappingName:
    Key1:
      SubKey1: Value1
      SubKey2: Value2
    Key2:
      SubKey1: Value3
      SubKey2: Value4

実例1: リージョン別AMI ID

AWSTemplateFormatVersion: "2010-09-09"
Description: Mappings example - AMI IDs by region

Parameters:
  EnvironmentType:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - prod

Mappings:
  # リージョンごとのAMI IDマッピング
  RegionMap:
    us-east-1:
      AMI: ami-0c55b159cbfafe1f0
      InstanceType: t2.micro
    us-west-2:
      AMI: ami-0d1cd67c26f5fca19
      InstanceType: t2.micro
    ap-northeast-1:
      AMI: ami-0f9ae750e8274075b
      InstanceType: t2.micro

  # 環境ごとのインスタンスタイプマッピング
  EnvironmentMap:
    dev:
      InstanceType: t2.micro
      MinSize: 1
      MaxSize: 2
    prod:
      InstanceType: m5.large
      MinSize: 2
      MaxSize: 10

Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      # リージョンからAMI IDを取得
      ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", AMI]
      # 環境からインスタンスタイプを取得
      InstanceType: !FindInMap [EnvironmentMap, !Ref EnvironmentType, InstanceType]
      Tags:
        - Key: Name
          Value: MappingExample

実例2: 環境別設定値

Mappings:
  EnvironmentConfig:
    dev:
      DBInstanceClass: db.t3.micro
      DBAllocatedStorage: 20
      BackupRetentionPeriod: 1
      MultiAZ: false
    staging:
      DBInstanceClass: db.t3.small
      DBAllocatedStorage: 50
      BackupRetentionPeriod: 7
      MultiAZ: false
    prod:
      DBInstanceClass: db.r5.large
      DBAllocatedStorage: 100
      BackupRetentionPeriod: 30
      MultiAZ: true

Resources:
  Database:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceClass: !FindInMap [EnvironmentConfig, !Ref EnvironmentType, DBInstanceClass]
      AllocatedStorage: !FindInMap [EnvironmentConfig, !Ref EnvironmentType, DBAllocatedStorage]
      BackupRetentionPeriod: !FindInMap [EnvironmentConfig, !Ref EnvironmentType, BackupRetentionPeriod]
      MultiAZ: !FindInMap [EnvironmentConfig, !Ref EnvironmentType, MultiAZ]

🔀 2. Conditions(条件)

定義と目的

Conditionsセクションには、エンティティが作成または設定される状況を定義するステートメントが含まれます。たとえば、条件を作成してリソースまたは出力に関連付けることで、条件がtrueの場合にのみCloudFormationがリソースまたは出力を作成するようにできます。同様に、条件がtrueの場合にのみCloudFormationがプロパティを特定の値に設定するように、条件をプロパティに関連付けることができます。

構文

Conditions:
  ConditionName: !Equals [value1, value2]
  # または他の条件関数

実例1: 環境に基づくリソースの条件付き作成

AWSTemplateFormatVersion: "2010-09-09"
Description: Conditions example - conditional resource creation

Parameters:
  EnvironmentType:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - staging
      - prod

Conditions:
  # 本番環境かどうかの判定
  IsProduction: !Equals [!Ref EnvironmentType, prod]

  # 開発環境かどうかの判定
  IsDevelopment: !Equals [!Ref EnvironmentType, dev]

  # 本番またはステージングかどうか
  IsProductionOrStaging: !Or
    - !Equals [!Ref EnvironmentType, prod]
    - !Equals [!Ref EnvironmentType, staging]

Resources:
  # 本番環境のみでELBを作成
  ProductionLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Condition: IsProduction
    Properties:
      Name: prod-alb
      Type: application
      Subnets:
        - !Ref Subnet1
        - !Ref Subnet2

  # 開発環境ではSSHキーを設定
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-12345678
      InstanceType: t2.micro
      # 開発環境の場合のみキーペアを設定
      KeyName: !If [IsDevelopment, my-dev-key, !Ref "AWS::NoValue"]

  # 本番・ステージングでマルチAZ RDSを作成
  Database:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceClass: db.t3.micro
      AllocatedStorage: 20
      # 条件に基づいてMultiAZを設定
      MultiAZ: !If [IsProductionOrStaging, true, false]
      # 本番環境でのみバックアップ保持期間を長く
      BackupRetentionPeriod: !If [IsProduction, 30, 7]

実例2: 複雑な条件ロジック

Parameters:
  Environment:
    Type: String
    AllowedValues: [dev, qa, staging, prod]

  EnableMonitoring:
    Type: String
    Default: "false"
    AllowedValues: ["true", "false"]

Conditions:
  IsProduction: !Equals [!Ref Environment, prod]
  IsNotProduction: !Not [!Equals [!Ref Environment, prod]]

  # モニタリングが有効かつ本番環境
  EnableProdMonitoring: !And
    - !Equals [!Ref EnableMonitoring, "true"]
    - !Equals [!Ref Environment, prod]

  # QAまたはステージング環境
  IsTestEnvironment: !Or
    - !Equals [!Ref Environment, qa]
    - !Equals [!Ref Environment, staging]

Resources:
  # 本番環境でのみCloudWatch Alarmを作成
  CPUAlarm:
    Type: AWS::CloudWatch::Alarm
    Condition: EnableProdMonitoring # trueだとCPUAlarmが作成される
    Properties:
      AlarmName: !Sub ${AWS::StackName}-cpu-alarm
      ComparisonOperator: GreaterThanThreshold
      EvaluationPeriods: 2
      MetricName: CPUUtilization
      Namespace: AWS/EC2
      Period: 300
      Statistic: Average
      Threshold: 80

🔄 3. MappingsとConditionsの組み合わせ

MappingsとConditionsは組み合わせて使用することで、より柔軟なテンプレートを作成できます。

Parameters:
  EnvironmentType:
    Type: String
    AllowedValues: [dev, qa, prod]

Mappings:
  EnvironmentConfig:
    dev:
      InstanceType: t2.micro
      MinSize: 1
      MaxSize: 2
    qa:
      InstanceType: t3.small
      MinSize: 2
      MaxSize: 4
    prod:
      InstanceType: m5.large
      MinSize: 3
      MaxSize: 10

Conditions:
  IsProduction: !Equals [!Ref EnvironmentType, prod]
  IsQA: !Equals [!Ref EnvironmentType, qa]

Resources:
  # Mappingsからインスタンスタイプを取得
  LaunchConfiguration:
    Type: AWS::AutoScaling::LaunchConfiguration
    Properties:
      ImageId: ami-12345678
      InstanceType: !FindInMap [EnvironmentConfig, !Ref EnvironmentType, InstanceType]
      # QA環境のみ特殊な設定を追加
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          echo "Standard setup"
          !If
            - IsQA
            - |
              echo "QA-specific configuration"
              /opt/install-qa-tools.sh
            - !Ref "AWS::NoValue"

  AutoScalingGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      LaunchConfigurationName: !Ref LaunchConfiguration
      MinSize: !FindInMap [EnvironmentConfig, !Ref EnvironmentType, MinSize]
      MaxSize: !FindInMap [EnvironmentConfig, !Ref EnvironmentType, MaxSize]
      # 本番環境のみELBを設定
      LoadBalancerNames: !If
        - IsProduction
        - [!Ref ProductionELB]
        - !Ref "AWS::NoValue"

💡 使い分けのベストプラクティス

Mappingsを使うべき場合

✅ リージョン別のAMI ID ✅ 環境ごとの固定設定値(インスタンスタイプ、ストレージサイズ等) ✅ 複数の値をセットで管理したい場合 ✅ 静的なルックアップテーブルが必要な場合

Conditionsを使うべき場合

✅ リソースの作成/非作成を制御 ✅ 真偽値に基づく動的な判断 ✅ プロパティの有無を制御(AWS::NoValueの使用) ✅ 複雑な論理演算が必要な場合(And, Or, Not)

両方を組み合わせる場合

✅ 環境ごとに異なる設定値を持ちつつ、特定環境でのみリソースを作成 ✅ Mappingsで基本設定を管理し、Conditionsで細かい制御


⚠️ 制限事項と注意点

MappingsブロックではConditionステートメントを使用できません。

回避策: Mappingsの構造を調整するか、Conditionsで代替

# ❌ これはできない
Mappings:
  RegionConfig:
    us-east-1:
      AMI: !If [IsProduction, ami-prod, ami-dev]  # エラー

# ✅ 代わりにこうする
Mappings:
  RegionConfig:
    us-east-1:
      ProdAMI: ami-prod123
      DevAMI: ami-dev456

Resources:
  Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !If
        - IsProduction
        - !FindInMap [RegionConfig, !Ref "AWS::Region", ProdAMI]
        - !FindInMap [RegionConfig, !Ref "AWS::Region", DevAMI]

📝 まとめ

Mappings:

Conditions:

両者を適切に組み合わせることで、保守性が高く、再利用可能なCloudFormationテンプレートを作成できます。