CloudFormationでできること、できないこと:実践的な中間まとめ
はじめに
CloudFormationの基本操作からテンプレート分割、そしてCDKとの比較まで学んできました。ここで一度立ち止まって、「CloudFormationは何が得意で、何が苦手なのか」を整理してみましょう。
この理解は単なる知識の整理ではありません。実際のプロジェクトでは、複数のツールを組み合わせてインフラを管理することが一般的です。CloudFormationの守備範囲を正しく把握することで、他のツールとの適切な使い分けができるようになります。
CloudFormationの得意分野:強力な機能
1. AWSリソースの包括的な管理
CloudFormationの最大の強みは、AWSのほぼ全てのサービスをカバーしていることです。
対応リソースの例:
- コンピューティング: EC2, Lambda, ECS, EKS, Fargate
- ストレージ: S3, EBS, EFS, FSx
- ネットワーク: VPC, ALB/NLB, CloudFront, Route53
- データベース: RDS, DynamoDB, ElastiCache, Neptune
- セキュリティ: IAM, KMS, Secrets Manager, Certificate Manager
- 監視: CloudWatch, X-Ray, CloudTrail
- その他: SNS, SQS, Step Functions, API Gateway
具体例:マイクロサービス基盤の一括構築
# 一つのテンプレートで以下を同時に構築可能
Resources:
# ネットワーク基盤
VPC: { Type: "AWS::EC2::VPC", ... }
# コンテナ基盤
ECSCluster: { Type: "AWS::ECS::Cluster", ... }
# データベース
RDSInstance: { Type: "AWS::RDS::DBInstance", ... }
DynamoTable: { Type: "AWS::DynamoDB::Table", ... }
# 負荷分散とセキュリティ
ApplicationLoadBalancer: { Type: "AWS::ElasticLoadBalancingV2::LoadBalancer", ... }
WAFWebACL: { Type: "AWS::WAFv2::WebACL", ... }
# 監視とアラート
CloudWatchDashboard: { Type: "AWS::CloudWatch::Dashboard", ... }
SNSAlarmTopic: { Type: "AWS::SNS::Topic", ... }
2. 変更管理の自動化
CloudFormationのChange Sets機能により、変更の影響を事前に確認できます。
# 変更内容を事前確認
aws cloudformation create-change-set \
--stack-name my-production-stack \
--template-body file://updated-template.yaml \
--change-set-name preview-update-20241127
# 変更内容のレビュー
aws cloudformation describe-change-set \
--change-set-name preview-update-20241127 \
--stack-name my-production-stack
# 安全であることを確認後に実行
aws cloudformation execute-change-set \
--change-set-name preview-update-20241127 \
--stack-name my-production-stack
3. 依存関係の自動解決
CloudFormationは、リソース間の依存関係を自動的に解析し、適切な順序でリソースを作成・削除します。
Resources:
# 1. 最初にVPCが作成される
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: "10.0.0.0/16"
# 2. VPC作成後にサブネットが作成される(自動的に依存関係を解決)
MySubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC # ← 依存関係の明示
CidrBlock: "10.0.1.0/24"
# 3. 最後にEC2インスタンスが作成される
MyInstance:
Type: AWS::EC2::Instance
Properties:
SubnetId: !Ref MySubnet # ← さらなる依存関係
InstanceType: t3.micro
4. ドリフト検出とコンプライアンス
実際の環境とテンプレートの差分(ドリフト)を検出できます。
# ドリフト検出の開始
aws cloudformation detect-stack-drift --stack-name my-stack
# ドリフトの詳細確認
aws cloudformation describe-stack-drift-detection-status \
--stack-drift-detection-id [検出ID]
# リソース別ドリフトの確認
aws cloudformation describe-stack-resource-drifts --stack-name my-stack
結果例:
リソース: MyS3Bucket
予想値: バージョニング無効
実際値: バージョニング有効
ステータス: MODIFIED (手動で変更された)
5. スタック間の連携(クロススタック参照)
前回学んだOutputs/ImportValue以外にも、NestedStacksを使った階層的な管理が可能です。
# 親スタック(main-stack.yaml)
Resources:
NetworkStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/my-templates/network.yaml
Parameters:
VpcCidr: "10.0.0.0/16"
ApplicationStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/my-templates/application.yaml
Parameters:
VpcId: !GetAtt NetworkStack.Outputs.VpcId
CloudFormationの苦手分野:限界と対策
1. リソース外の設定管理
苦手なこと:
- OSレベルの設定(ファイアウォール、カーネルパラメータ)
- アプリケーションのデプロイ
- データベースの初期データ投入
- SSL証明書のインストール(EC2内部)
実際の課題例:
# ❌ CloudFormationだけでは以下は実現困難
# - Nginxの詳細設定
# - Dockerコンテナの起動
# - アプリケーションコードのデプロイ
# - データベーススキーマの初期化
EC2Instance:
Type: AWS::EC2::Instance
Properties:
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum install -y nginx
# この先の詳細設定は限界がある...
✅ 解決策:
組み合わせパターン1: CloudFormation + Systems Manager
# CloudFormationでインスタンスを作成
EC2Instance:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref SSMInstanceProfile
UserData:
Fn::Base64: !Sub |
#!/bin/bash
# Systems Manager Agentが設定を取得・実行
aws ssm get-parameter --name "/myapp/nginx-config" --region ${AWS::Region}
組み合わせパターン2: CloudFormation + Ansible
# 1. CloudFormationでインフラ作成
aws cloudformation deploy --template-file infrastructure.yaml --stack-name my-stack
# 2. Ansibleで設定管理
ansible-playbook -i $(aws cloudformation describe-stacks \
--stack-name my-stack --query 'Stacks[0].Outputs[?OutputKey==`InstanceIP`].OutputValue' \
--output text), configure-servers.yml
2. 既存リソースのインポート制限
苦手なこと:
既存の手動作成リソースをCloudFormationで管理下に置くこと
2024年時点での改善状況:
# 最新のCloudFormationでは多くのリソースタイプでインポートが可能
aws cloudformation create-stack \
--stack-name imported-resources \
--template-body file://import-template.yaml \
--resources-to-import file://resources-to-import.json
resources-to-import.json例:
[
{
"ResourceType": "AWS::S3::Bucket",
"LogicalResourceId": "ExistingBucket",
"ResourceIdentifier": {
"BucketName": "my-existing-bucket-20241127"
}
}
]
✅ 対応可能なリソースタイプ(主要なもの):
- AWS::S3::Bucket
- AWS::EC2::Instance
- AWS::RDS::DBInstance
- AWS::DynamoDB::Table
- AWS::Lambda::Function
- AWS::IAM::Role
3. マルチクラウド・ハイブリッドクラウド
苦手なこと:
- Azure、GCP、オンプレミスリソースの管理
- 複数クラウド間のネットワーク構成
✅ 解決策:
Terraformとの比較例:
# Terraform: マルチクラウド対応
provider "aws" {
region = "us-west-2"
}
provider "azurerm" {
features {}
}
# AWSのS3バケット
resource "aws_s3_bucket" "main" {
bucket = "my-app-storage-aws"
}
# AzureのStorage Account
resource "azurerm_storage_account" "main" {
name = "myappstorageazure"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
}
4. 複雑な条件分岐とループ
苦手なこと:
# ❌ CloudFormationでは複雑な条件分岐が困難
Conditions:
CreateProdResources: !Equals [!Ref Environment, "production"]
CreateDevResources: !Equals [!Ref Environment, "development"]
CreateHighAvailabilitySetup: !And
- !Equals [!Ref Environment, "production"]
- !Equals [!Ref HighAvailability, "true"]
# ネストした条件や動的なリソース数の制御は難しい
✅ CDKでの解決例:
// 環境に応じて動的にリソース数を変更
const instanceCount = props.environment === 'production' ? 3 : 1;
const instances: ec2.Instance[] = [];
for (let i = 0; i < instanceCount; i++) {
instances.push(new ec2.Instance(this, `WebServer${i}`, {
vpc: vpc,
instanceType: props.environment === 'production'
? ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE)
: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
}));
}
実践的な使い分けガイド
ツール選択フローチャート
インフラ管理のニーズ
├── AWSのみ?
│ ├── Yes → CloudFormation or CDK
│ │ ├── 複雑なロジック必要?
│ │ │ ├── Yes → CDK
│ │ │ └── No → CloudFormation
│ │ └── チームのスキル
│ │ ├── プログラミング経験豊富 → CDK
│ │ └── インフラ中心 → CloudFormation
│ └── No → Terraform or Pulumi
└── 設定管理も含む?
├── Yes → CloudFormation + Ansible/Chef
└── No → CloudFormation単体でOK
実際のプロジェクトでの組み合わせ例
パターン1: スタートアップ(小規模)
CloudFormation
├── VPC、サブネット
├── ALB、EC2
├── RDS
└── S3、CloudFront
パターン2: 中規模企業
CDK (TypeScript)
├── 基盤インフラ
├── マイクロサービス群
└── CI/CDパイプライン
+ Systems Manager
├── OS設定
└── アプリケーション設定
パターン3: 大企業(マルチクラウド)
Terraform
├── AWS (70%)
├── Azure (20%)
└── GCP (10%)
+ Ansible
├── 共通設定管理
└── コンプライアンス対応
2024年における CloudFormation の最新動向
新機能・改善点
- Import機能の拡充:既存リソースのインポート対応リソースタイプが大幅増加
- CloudFormation Guard:ポリシーアズコードでテンプレートの事前検証
- Registry機能:サードパーティリソースタイプの拡充
- Hooks機能:デプロイ前後の自動処理実行
パフォーマンスの向上
# 並列処理の改善により、大規模スタックのデプロイ時間が短縮
# 例:100リソースのスタック
# 2022年: 15-20分 → 2024年: 8-12分
まとめ:CloudFormationとの正しい付き合い方
CloudFormationを選ぶべき状況
✅ 適している場面:
- AWS環境での標準的なインフラ構築
- コンプライアンス要件が厳しい企業環境
- インフラチーム中心の組織
- 長期的な安定運用が重視される案件
他のツールと組み合わせるべき状況
🔄 組み合わせが必要な場面:
- 複雑なアプリケーションデプロイメント → CloudFormation + CodeDeploy/Systems Manager
- マルチクラウド戦略 → Terraform + CloudFormation (AWS部分)
- 高度なプログラマブル制御 → CDK
- きめ細かい設定管理 → CloudFormation + Ansible
学習の次のステップ
継続学習の推奨順序:
- CloudFormation深化:NestedStacks、StackSets、Macrosの活用
- CDK実践:TypeScriptでの実装とテスト手法
- 他ツール理解:Terraform基礎、Ansible基礎
- 統合運用:CI/CDパイプラインでのIaC活用
実践プロジェクト提案:
- 個人ブログ基盤をCloudFormationで構築
- 同じ構成をCDKで書き直して比較
- Terraformで同等の機能を実装して差を実感
CloudFormationは「AWSインフラのプロビジョニング」において非常に強力なツールですが、モダンなインフラ管理では複数ツールの組み合わせが一般的です。各ツールの特性を理解し、適材適所で使い分けることが、効率的なインフラ運用の鍵となります。
次回からは、もう一つの主要なIaCツールであるTerraformの世界に入っていきます。CloudFormationとの比較を通じて、より深いIaCの理解を目指しましょう。お楽しみに!