【実務・中級編】CloudFormationマッピング(Mappings)と条件付き評価(Conditions)を駆使した環境非依存型テンプレートの極意 – インフラ構成管理(IaC)活用バイブル

恐怖の「環境別コピペ地獄」からの脱却:MappingsとConditionsが生み出す真の「環境非依存型」CloudFormation設計の極意

テックリードの私たちが日々頭を悩ませるインフラ構成管理の悪夢。それは、「開発環境(dev)、検証環境(stg)、本番環境(prd)で、なぜか微妙にパラメータやリソース構成が違うために、テンプレートが環境の数だけ分裂していく現象」だ。

「本番だけインスタンスタイプを大きくしたい」「stgとprdだけマルチAZにしたい」「サブネットのCIDR設計が環境ごとに違う」。
これを力技で解決しようとして、環境ごとにテンプレートをコピー&ペーストし始めたり、シェルスクリプトで無理やり置換(sed職人)し始めた瞬間、そのプロジェクトのIaCは「Technical Debt(技術的負債)」の沼へと沈んでいく。

今回は、AWS CloudFormationが標準で備えている `Mappings`(マッピング) と `Conditions`(条件付き評価) を極限まで組み合わせ、「マジックナンバーを完全排除し、単一のコードベースであらゆる環境を完全制圧する環境非依存型テンプレート設計」 の極意を伝授しよう。

—

1. 開発スピードを劇的に高めるツール&環境設定

プロのSREとして、まずあなたの手元を最高効率の環境にチューニングする。CloudFormationを扱う上で、以下のツールと設定は「空気を吸うこと」と同義だ。

必須の神プラグイン(VS Code)

1. AWS Toolkit for Visual Studio Code

  • これなしでのCloudFormation記述は目隠しして高速道路を走るようなもの。テンプレートのバリデーション、リソースの補完、スタックの状態監視がIDE内で完結する。

2. YAML / CloudFormation Support

  • 構文エラーをリアルタイムで検知し、インデントの崩壊を防ぐ。

隠れたキーボードショートカット(VS Code)

  • `Ctrl + Space` (Windows/Linux) / `Cmd + Space` (Mac): リソースプロパティの補完。Mappingsのキーを忘れた時もこれですべて引き出せる。
  • `Alt + Shift + F` (Windows) / `Option + Shift + F` (Mac): ドキュメントのフォーマット。YAMLのインデントズレによる構文エラーを1秒で撲滅する。

チーム開発のための共有化ルール

  • パラメータ直書きの禁止: リソース定義ブロック(`Resources:`)の中に直接数値を書くことは「死刑宣告」と心得よ。すべての環境依存値は必ず `Parameters` か `Mappings` に逃がす。
  • 論理IDの命名規則: リソースの論理IDには環境名を含めない(例:`ProdDatabase` ではなく `Database`)。環境非依存の原則を守るためだ。

—

2. 徹底解説:MappingsとConditionsのシナジー

環境非依存型テンプレートを構築するエンジンとなるのが、`Mappings` と `Conditions` だ。それぞれの役割を明確に定義する。

  • `Mappings`: 「静的なルックアップテーブル」。環境名(Key)をインデックスとして、インスタンスタイプやAMI ID、ログの保持期間などの「値」を引く。
  • `Conditions`: 「動的な論理判定」。環境が本番であるか、特定のフラグが真であるかに応じて、リソースの作成有無やプロパティの挙動を `true / false` で制御する。

これらを組み合わせることで、「環境名をキーにして設定値を引き、その値や環境属性に基づいてリソースのデプロイ挙動を制御する」 という極めてクリーンなパイプラインが完成する。

—

3. 実践:DRY原則を極めたベストプラクティス構成例

百聞は一見にしかず。dev、stg、prdの3環境をたった1つのテンプレートで完全にコントロールする、実戦投入レベルのYAMLコードを公開する。

このテンプレートは以下の要件を満たしている。
1. インスタンスタイプとルートボリュームサイズを環境ごとにMappingsで切り替え
2. 本番環境(prd)でのみ、マルチAZ用の追加セキュリティグループや冗長設定をConditionsで有効化
3. マジックナンバーの完全排除

AWSTemplateFormatVersion: ‘2010-09-09’
Description: >
Ultimate Environment-Agnostic Infrastructure Template.
Demonstrating advanced Mappings and Conditions patterns.

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

  • dev
  • stg
  • prd

Description: Select the deployment environment.

=====================================================================
Mappings: 環境ごとの静的パラメータマトリクス
=====================================================================
Mappings:
EnvironmentConfig:
dev:
InstanceType: t3.micro
RootVolumeSize: ’20’
EnableDetailedMonitoring: ‘false’
stg:
InstanceType: t3.small
RootVolumeSize: ’50’
EnableDetailedMonitoring: ‘false’
prd:
InstanceType: c6i.xlarge
RootVolumeSize: ‘100’
EnableDetailedMonitoring: ‘true’

=====================================================================
Conditions: 環境に応じた動的フラグ判定
=====================================================================
Conditions:
# 本番環境であるかどうかを判定
IsProduction: !Equals [ !Ref EnvironmentType, ‘prd’ ]

# 開発環境以外(stg & prd)であるかどうかを判定
IsStgOrPrd: !Not [ !Equals [ !Ref EnvironmentType, ‘dev’ ] ]

Resources:
# —————————————————————–
# EC2 Instance: Mappingsからスペックを動的取得
# —————————————————————–
AppServer:
Type: AWS::EC2::Instance
Properties:
# Mappingsを使った環境別インスタンスタイプの動的解決
InstanceType: !FindInMap [EnvironmentConfig, !Ref EnvironmentType, InstanceType]
ImageId: ami-0c55b159cbfafe1f0 # 実際にはSSM Parameter Store等と組み合わせるのがベスト
Monitoring: !FindInMap [EnvironmentConfig, !Ref EnvironmentType, EnableDetailedMonitoring]
BlockDeviceMappings:

  • DeviceName: /dev/xvda

Ebs:
VolumeSize: !FindInMap [EnvironmentConfig, !Ref EnvironmentType, RootVolumeSize]
VolumeType: gp3
Tags:

  • Key: Environment

Value: !Ref EnvironmentType

  • Key: Name

Value: !Sub ‘app-server-${EnvironmentType}’

# —————————————————————–
# Production Only Security Group: Conditionsで作成を制御
# —————————————————————–
ProductionAlertSecurityGroup:
Type: AWS::EC2::SecurityGroup
Condition: IsProduction # prdの時だけリソースを実体化する
Properties:
GroupDescription: Strict security group for production alerting
SecurityGroupIngress:

  • IpProtocol: tcp

FromPort: 443
ToPort: 443
CidrIp: 10.0.0.0/8 # 社内網からのアクセスのみ許可

# —————————————————————–
# Stg/Prd Only S3 Bucket: 複数条件による制御
# —————————————————————–
SecureAuditBucket:
Type: AWS::S3::Bucket
Condition: IsStgOrPrd # stgまたはprdの時のみ作成
Properties:
BucketName: !Sub ‘my-company-audit-logs-${EnvironmentType}-${AWS::AccountId}’
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
VersioningConfiguration:
Status: Enabled # 本番・ステージングのみバージョニング有効化

Outputs:
ServerInstanceId:
Description: The ID of the application server
Value: !Ref AppServer
Export:
Name: !Sub ‘${AWS::StackName}-InstanceId’

AssignedInstanceType:
Description: Dynamically resolved instance type
Value: !FindInMap [EnvironmentConfig, !Ref EnvironmentType, InstanceType]

—

4. プロの現場で使える「さらなる実践テクニック」

上記のコードだけでも十分強靭だが、本番の現場でさらにこれをスケールさせるための「プロの裏技」を授けよう。

1. Mappingsの限界をSSM Parameter Storeで補う

Mappingsの弱点は、「AMI IDのように頻繁に変わる値や、セキュアな文字列をハードコードせざるを得ない点」にある。
これを解決するには、AMI IDや外部連携URLはAWS Systems Manager (SSM) のパラメータストアに逃がし、テンプレート内では `!Sub` や動的参照を組み合わせるか、あるいはCI/CDパイプライン(AWS CodePipelineやGitHub Actionsなど)のビルドフェーズでMappingsの値を動的に書き換えるプレプロセッサを挟む手法が有効だ。

2. 環境ごとのデプロイはパラメーターファイルで行う

テンプレート本体は1つにし、環境ごとの入力値はJSON/YAMLのパラメーターファイル(`parameters-dev.json` 等)として完全に分離する。

[
{
“ParameterKey”: “EnvironmentType”,
“ParameterValue”: “dev”
}
]

デプロイコマンドは環境ごとにこれを選択するだけだ。

aws cloudformation deploy \
–template-file template.yaml \
–stack-name myapp-stack-dev \
–parameter-overrides file://parameters-dev.json \
–capabilities CAPABILITY_IAM

—

5. まとめ

インフラのコード化(IaC)において最大の敵は、「複雑性」と「重複(Dry原則の違反)」だ。
環境ごとにテンプレートを乱立させるアプローチは、将来的に必ず変更漏れや環境差異による障害(「なぜか本番だけ動かない」)を引き起こす。

今回紹介した `Mappings` による静的パラメータの抽象化 と `Conditions` による動的リソース制御 を完璧にマスターすれば、あなたとあなたのチームのインフラ管理工数は劇的に削減される。

テンプレートは常に一つ。パラメータと条件で未来を分岐させる。
この境地に到達したとき、あなたのクラウドインフラは真の「美しさ」と「堅牢性」を手に入れるのだ。

タイトルとURLをコピーしました