はじめに
CloudFormationは、AWSが提供するInfrastructure as Code(IaC)サービスです
YAML または JSON でインフラ構成をテンプレートとして定義し、スタックとしてAWSリソースの作成・変更・削除ができます
AWS純正のサービスのため、追加のツールインストールが不要で、AWS CLIさえあればすぐに利用を開始できます
サードパーティ製のIaCツールとしてはTerraformが広く使われていますが、CloudFormationにはスタックの自動ロールバック機能やAWSサポートを直接受けられるといった強みがあります
一方、TerraformにはHCLによる簡潔な記述やマルチクラウド対応といった利点があります
両者の詳しい比較は記事末尾の比較表にまとめています
この記事では、CloudFormationの環境準備からテンプレート作成、実践的な使い方まで、実際のコマンド例を交えて解説します
この記事でわかること
- CloudFormationを使うための環境準備
- テンプレートの基本構造(YAML形式)
- スタックの作成・更新・削除
- VPCの作成
- セキュリティグループの作成
- EC2インスタンスの作成とSSH接続
- パラメータとOutputの活用
- 変更セット(Change Set)による安全な更新
- スタックのドリフト検知
前提条件
- AWSアカウントを持っている
- AWS CLIがインストール・設定済み(
aws configure完了済み) - 基本的なコマンドライン操作ができる
AWS CLIの設定がまだの方は以下の記事を参考にしてください
手順1: 環境準備
CloudFormationはAWSのマネージドサービスのため、Terraformのようなツールのインストールは不要です
必要なのはAWS CLIのみです
※以降のコマンドは PowerShell 環境で実行してください
AWS CLIの確認
aws --version
出力例:
aws-cli/2.15.0 Python/3.11.6 Windows/10 exe/AMD64 prompt/off
AWS認証の確認
aws sts get-caller-identity
出力例:
{
"UserId": "AIDAIOSFODNN7EXAMPLE",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/cfn-user"
}
IAMユーザーに必要な権限
CloudFormationを使用するには、以下の権限が必要です
-
AWSCloudFormationFullAccess(スタック操作用) - 作成するリソースに対応する権限(例:
AmazonEC2FullAccess,AmazonVPCFullAccess)
手順2: テンプレートの基本構造
CloudFormationではYAML(またはJSON)形式でテンプレートを記述します
この記事ではYAML形式を使用します
テンプレートの構成要素
AWSTemplateFormatVersion: "2010-09-09"
Description: テンプレートの説明
Parameters:
# 入力パラメータの定義
Resources:
# AWSリソースの定義(必須セクション)
Outputs:
# スタック作成後の出力値
各セクションの役割:
| セクション | 必須 | 説明 |
|---|---|---|
| AWSTemplateFormatVersion | × | テンプレートのバージョン(現在は "2010-09-09" のみ) |
| Description | × | テンプレートの説明文 |
| Parameters | × | スタック作成時に入力する値 |
| Resources | ○ | 作成するAWSリソースの定義 |
| Outputs | × | スタック作成後に出力する値 |
ファイル構成
cloudformation-ec2-demo/
├── vpc-stack.yaml # VPC・ネットワークのテンプレート
├── ec2-stack.yaml # EC2インスタンスのテンプレート
└── .gitignore # Git管理外ファイルの指定
プロジェクトディレクトリの作成
# ディレクトリ作成
New-Item -ItemType Directory -Path cloudformation-ec2-demo
# ディレクトリへ移動
Set-Location cloudformation-ec2-demo # cd でもOK
# ファイル作成
New-Item -ItemType File -Name "vpc-stack.yaml"
New-Item -ItemType File -Name "ec2-stack.yaml"
New-Item -ItemType File -Name ".gitignore"
.gitignoreの作成
# CloudFormation
*.bak
手順3: VPCとサブネットの作成
AWSのネットワーク基盤(VPC環境)をCloudFormationで作成します
VPC、パブリックサブネット、Internet Gateway、ルートテーブルを定義し、インターネットに接続可能なネットワークを構築します
これにより、後で作成するEC2インスタンスがインターネット通信できる環境を準備しています
vpc-stack.yamlの作成
AWSTemplateFormatVersion: "2010-09-09"
Description: VPC and network resources for CloudFormation demo
Parameters:
ProjectName:
Type: String
Default: cfn-demo
Description: Project name used for resource tags
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub "${ProjectName}-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: !Sub "${ProjectName}-public-subnet"
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub "${ProjectName}-igw"
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${ProjectName}-public-rt"
PublicRoute:
Type: AWS::EC2::Route
DependsOn: VPCGatewayAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
Outputs:
VPCId:
Description: VPC ID
Value: !Ref VPC
Export:
Name: !Sub "${ProjectName}-vpc-id"
PublicSubnetId:
Description: Public Subnet ID
Value: !Ref PublicSubnet
Export:
Name: !Sub "${ProjectName}-public-subnet-id"
テンプレートで使用している組み込み関数
| 関数 | 説明 | 使用例 |
|---|---|---|
| !Ref | リソースのIDやパラメータの値を参照 |
!Ref VPC → VPCのID |
| !Sub | 文字列内の変数を置換 | !Sub "${ProjectName}-vpc" |
| !Select | リストから指定位置の要素を取得 | !Select [0, !GetAZs ""] |
| !GetAZs | リージョンのAZ一覧を取得 | !GetAZs "" |
テンプレートの検証
スタックを作成する前に、テンプレートの構文を検証できます
aws cloudformation validate-template --template-body file://vpc-stack.yaml
出力例:
{
"Parameters": [
{
"ParameterKey": "ProjectName",
"DefaultValue": "cfn-demo",
"NoEcho": false,
"Description": "Project name used for resource tags"
}
],
"Description": "VPC and network resources for CloudFormation demo"
}
エラーがある場合はエラーメッセージが表示されます
手順4: スタックの作成と基本コマンド
CloudFormationの基本コマンドを使い、インフラの作成と状態管理を行います
スタック作成: テンプレートからAWSリソースを一括作成
スタック確認: 作成されたリソースの状態を確認
Output確認: VPC IDやサブネットIDなどの出力値を表示
スタックの作成(create-stack)
aws cloudformation create-stack `
--stack-name cfn-demo-vpc `
--template-body file://vpc-stack.yaml `
--parameters ParameterKey=ProjectName,ParameterValue=cfn-demo
出力例:
{
"StackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/cfn-demo-vpc/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
スタック作成の完了を待機
aws cloudformation wait stack-create-complete --stack-name cfn-demo-vpc
このコマンドはスタックの作成が完了するまでブロックします(通常1〜3分程度)
スタックの状態確認(describe-stacks)
aws cloudformation describe-stacks --stack-name cfn-demo-vpc
主なスタックステータス:
| ステータス | 説明 |
|---|---|
| CREATE_IN_PROGRESS | 作成中 |
| CREATE_COMPLETE | 作成完了 |
| CREATE_FAILED | 作成失敗(自動ロールバック) |
| ROLLBACK_COMPLETE | ロールバック完了 |
| UPDATE_COMPLETE | 更新完了 |
| DELETE_COMPLETE | 削除完了 |
スタックのイベント確認
作成の進捗やエラーの詳細を確認できます
aws cloudformation describe-stack-events --stack-name cfn-demo-vpc
作成されたリソースの確認
aws cloudformation describe-stack-resources --stack-name cfn-demo-vpc
Output値の確認
aws cloudformation describe-stacks `
--stack-name cfn-demo-vpc `
--query "Stacks[0].Outputs"
出力例:
[
{
"OutputKey": "VPCId",
"OutputValue": "vpc-0a1b2c3d4e5f6g7h8",
"Description": "VPC ID",
"ExportName": "cfn-demo-vpc-id"
},
{
"OutputKey": "PublicSubnetId",
"OutputValue": "subnet-0a1b2c3d4e5f6g7h8",
"Description": "Public Subnet ID",
"ExportName": "cfn-demo-public-subnet-id"
}
]
特定のOutput値のみ取得:
aws cloudformation describe-stacks `
--stack-name cfn-demo-vpc `
--query "Stacks[0].Outputs[?OutputKey==``VPCId``].OutputValue" `
--output text
手順5: セキュリティグループとEC2インスタンスの作成
ネットワーク内にサーバーを配置し、必要な通信を許可するための設定を行います
ここでは、VPCスタックのExport値を Fn::ImportValue で参照し、スタック間の連携を実現します
ec2-stack.yamlの作成
AWSTemplateFormatVersion: "2010-09-09"
Description: EC2 instance with security group for CloudFormation demo
Parameters:
ProjectName:
Type: String
Default: cfn-demo
Description: Project name used for resource tags
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: EC2 key pair name for SSH access
MyIP:
Type: String
Default: 0.0.0.0/0
Description: IP address allowed for SSH access (CIDR format)
AmiId:
Type: AWS::EC2::Image::Id
Default: <ami-id>
Description: AMI ID for EC2 instance (Amazon Linux 2023)
Resources:
EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for EC2 instance
GroupName: !Sub "${ProjectName}-ec2-sg"
VpcId: !ImportValue
Fn::Sub: "${ProjectName}-vpc-id"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Ref MyIP
Description: SSH
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: HTTP
SecurityGroupEgress:
- IpProtocol: "-1"
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: !Sub "${ProjectName}-ec2-sg"
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref AmiId
InstanceType: t3.micro
KeyName: !Ref KeyName
SubnetId: !ImportValue
Fn::Sub: "${ProjectName}-public-subnet-id"
SecurityGroupIds:
- !Ref EC2SecurityGroup
Tags:
- Key: Name
Value: !Sub "${ProjectName}-ec2"
Outputs:
InstanceId:
Description: EC2 Instance ID
Value: !Ref EC2Instance
PublicIP:
Description: EC2 Public IP Address
Value: !GetAtt EC2Instance.PublicIp
SecurityGroupId:
Description: Security Group ID
Value: !Ref EC2SecurityGroup
SSHCommand:
Description: SSH connection command
Value: !Sub "ssh -i ${KeyName}.pem ec2-user@${EC2Instance.PublicIp}"
AMI IDの取得
テンプレートの AmiId パラメータに設定するAMI IDを事前に取得します
aws ec2 describe-images `
--owners amazon `
--filters "Name=name,Values=al2023-ami-2023*" "Name=architecture,Values=x86_64" `
--query "Images | sort_by(@, &CreationDate) | [-1].[ImageId,Name]" `
--output text `
--region ap-northeast-1
出力例:
ami-088b486f20fab3f0e al2023-ami-2023.6.20241212.0-kernel-6.1-x86_64
取得した AMI ID を、スタック作成時のパラメータとして指定します
ec2-stack.yamlの<ami-id>の部分を、上記で取得した AMI ID (ami-088b486f20fab3f0e)に置き換えてください
キーペアの作成
SSH接続に必要なキーペアを作成します
aws ec2 create-key-pair --key-name test-ec2-key --query "KeyMaterial" --output text | Out-File -Encoding ascii test-ec2-key.pem
EC2スタックの作成
aws cloudformation create-stack `
--stack-name cfn-demo-ec2 `
--template-body file://ec2-stack.yaml `
--parameters `
ParameterKey=ProjectName,ParameterValue=cfn-demo `
ParameterKey=KeyName,ParameterValue=test-ec2-key `
ParameterKey=MyIP,ParameterValue=0.0.0.0/0 `
ParameterKey=AmiId,ParameterValue=ami-088b486f20fab3f0e
完了を待機:
aws cloudformation wait stack-create-complete --stack-name cfn-demo-ec2
SSH接続
Output値からSSH接続コマンドを取得します
aws cloudformation describe-stacks `
--stack-name cfn-demo-ec2 `
--query "Stacks[0].Outputs[?OutputKey==``SSHCommand``].OutputValue" `
--output text
出力例:
ssh -i test-ec2-key.pem ec2-user@54.250.245.176
鍵ファイルに対して「読み取り権限」の付与をします
# 1. 継承を無効化し、すべてのアクセス権を削除する
icacls.exe "test-ec2-key.pem" /inheritance:r
# 2. 現在のログインユーザーにのみ「読み取り権限」を付与する
icacls.exe "test-ec2-key.pem" /grant:r "$($env:USERNAME):(R)"
接続:
ssh -i test-ec2-key.pem ec2-user@54.250.245.176
手順6: 変更セット(Change Set)による安全な更新
CloudFormationでは、変更セットを使ってスタックの変更内容を事前に確認できます
これはTerraformの terraform plan に相当する機能です
テンプレートの変更
例として、EC2のインスタンスタイプを t3.micro → t3.small に変更します
ec2-stack.yaml の該当箇所を修正:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.small # t3.micro → t3.small に変更
変更セットの作成
aws cloudformation create-change-set `
--stack-name cfn-demo-ec2 `
--change-set-name update-instance-type `
--template-body file://ec2-stack.yaml `
--parameters `
ParameterKey=ProjectName,ParameterValue=cfn-demo `
ParameterKey=KeyName,ParameterValue=test-ec2-key `
ParameterKey=MyIP,ParameterValue=0.0.0.0/0 `
ParameterKey=AmiId,ParameterValue=ami-088b486f20fab3f0e
変更セットの確認
aws cloudformation describe-change-set `
--stack-name cfn-demo-ec2 `
--change-set-name update-instance-type
出力例(Changesセクション):
{
"Changes": [
{
"Type": "Resource",
"ResourceChange": {
"Action": "Modify",
"LogicalResourceId": "EC2Instance",
"ResourceType": "AWS::EC2::Instance",
"Replacement": "True"
}
}
]
}
Actionの種類:
| Action | 説明 |
|---|---|
| Add | 新規作成 |
| Modify | 変更(Replacement: True の場合は再作成) |
| Remove | 削除 |
変更セットの実行
内容を確認して問題なければ実行します
aws cloudformation execute-change-set `
--stack-name cfn-demo-ec2 `
--change-set-name update-instance-type
完了を待機:
aws cloudformation wait stack-update-complete --stack-name cfn-demo-ec2
変更セットを使わない直接更新
変更セットを使わずに直接更新することも可能です
aws cloudformation update-stack `
--stack-name cfn-demo-ec2 `
--template-body file://ec2-stack.yaml `
--parameters `
ParameterKey=ProjectName,ParameterValue=cfn-demo `
ParameterKey=KeyName,ParameterValue=test-ec2-key `
ParameterKey=MyIP,ParameterValue=0.0.0.0/0 `
ParameterKey=AmiId,ParameterValue=ami-088b486f20fab3f0e
※本番環境では変更セットの使用を推奨します
手順7: ドリフト検知
AWSコンソールから手動でリソースを変更した場合、テンプレートと実際のリソースの状態に差分(ドリフト)が発生します
CloudFormationにはこのドリフトを検知する機能があります
ドリフト検知の実行
aws cloudformation detect-stack-drift --stack-name cfn-demo-vpc
出力例:
{
"StackDriftDetectionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
ドリフト検知の結果確認
aws cloudformation describe-stack-drift-detection-status `
--stack-drift-detection-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
出力例:
{
"StackDriftDetectionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"StackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/cfn-demo-vpc/...",
"StackDriftStatus": "IN_SYNC",
"DetectionStatus": "DETECTION_COMPLETE"
}
StackDriftStatusの種類:
| ステータス | 説明 |
|---|---|
| IN_SYNC | テンプレートと一致 |
| DRIFTED | 差分あり |
| NOT_CHECKED | 未チェック |
リソースごとのドリフト詳細
aws cloudformation describe-stack-resource-drifts `
--stack-name cfn-demo-vpc `
--stack-resource-drift-status-filters MODIFIED DELETED
手順8: リソースの削除
EC2スタックの削除(先に削除)
依存関係があるため、EC2スタックを先に削除します
aws cloudformation delete-stack --stack-name cfn-demo-ec2
完了を待機:
aws cloudformation wait stack-delete-complete --stack-name cfn-demo-ec2
VPCスタックの削除
aws cloudformation delete-stack --stack-name cfn-demo-vpc
完了を待機:
aws cloudformation wait stack-delete-complete --stack-name cfn-demo-vpc
削除の確認
aws cloudformation list-stacks `
--stack-status-filter DELETE_COMPLETE `
--query "StackSummaries[?StackName==``cfn-demo-vpc`` || StackName==``cfn-demo-ec2``].[StackName,StackStatus]" `
--output table
削除保護の設定
誤削除を防ぐため、本番環境ではスタックの削除保護を有効にすることを推奨します
aws cloudformation update-termination-protection `
--enable-termination-protection `
--stack-name cfn-demo-vpc
削除保護を解除する場合:
aws cloudformation update-termination-protection `
--no-enable-termination-protection `
--stack-name cfn-demo-vpc
よく使うCloudFormationコマンド集
スタック操作
スタック作成:
aws cloudformation create-stack `
--stack-name my-stack `
--template-body file://template.yaml
スタック更新:
aws cloudformation update-stack `
--stack-name my-stack `
--template-body file://template.yaml
スタック削除:
aws cloudformation delete-stack --stack-name my-stack
スタック情報の確認
スタック一覧:
aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE
スタック詳細:
aws cloudformation describe-stacks --stack-name my-stack
スタックのリソース一覧:
aws cloudformation describe-stack-resources --stack-name my-stack
スタックのイベント:
aws cloudformation describe-stack-events --stack-name my-stack
Output値の取得:
aws cloudformation describe-stacks `
--stack-name my-stack `
--query "Stacks[0].Outputs"
テンプレート操作
テンプレートの検証:
aws cloudformation validate-template --template-body file://template.yaml
S3上のテンプレートを使用:
aws cloudformation create-stack `
--stack-name my-stack `
--template-url https://s3.amazonaws.com/my-bucket/template.yaml
既存スタックのテンプレート取得:
aws cloudformation get-template --stack-name my-stack
変更セット操作
変更セット作成:
aws cloudformation create-change-set `
--stack-name my-stack `
--change-set-name my-changes `
--template-body file://template.yaml
変更セット確認:
aws cloudformation describe-change-set `
--stack-name my-stack `
--change-set-name my-changes
変更セット実行:
aws cloudformation execute-change-set `
--stack-name my-stack `
--change-set-name my-changes
変更セット削除:
aws cloudformation delete-change-set `
--stack-name my-stack `
--change-set-name my-changes
待機コマンド
スタック作成完了を待機:
aws cloudformation wait stack-create-complete --stack-name my-stack
スタック更新完了を待機:
aws cloudformation wait stack-update-complete --stack-name my-stack
スタック削除完了を待機:
aws cloudformation wait stack-delete-complete --stack-name my-stack
ドリフト検知
ドリフト検知の実行:
aws cloudformation detect-stack-drift --stack-name my-stack
ドリフト検知の結果確認:
aws cloudformation describe-stack-drift-detection-status `
--stack-drift-detection-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
リソースごとのドリフト詳細:
aws cloudformation describe-stack-resource-drifts --stack-name my-stack
Export値の確認
全Export値の一覧:
aws cloudformation list-exports
特定のExport値を使用しているスタック:
aws cloudformation list-imports --export-name cfn-demo-vpc-id
トラブルシューティング
スタック作成が失敗してROLLBACK_COMPLETEになる場合
Stack [cfn-demo-ec2] already exists in ROLLBACK_COMPLETE state and can not be updated.
対処法:
- イベントでエラー原因を確認:
aws cloudformation describe-stack-events --stack-name cfn-demo-ec2 `
--query "StackEvents[?ResourceStatus==``CREATE_FAILED``].[LogicalResourceId,ResourceStatusReason]" `
--output table
- ROLLBACK_COMPLETE状態のスタックを削除してから再作成:
aws cloudformation delete-stack --stack-name cfn-demo-ec2
aws cloudformation wait stack-delete-complete --stack-name cfn-demo-ec2
テンプレートの検証エラー
An error occurred (ValidationError) when calling the CreateStack operation: Template format error
対処法:
- YAMLのインデントが正しいか確認
-
aws cloudformation validate-templateで事前検証 - リソースタイプ名が正しいか確認(例:
AWS::EC2::VPC)
Export値の参照エラー
No export named 'cfn-demo-vpc-id' found.
対処法:
- 参照先のスタックが作成済みか確認
- Export名が正しいか確認:
aws cloudformation list-exports
- スタックの作成順序を確認(VPCスタック → EC2スタック)
削除できない場合
Stack [cfn-demo-vpc] cannot be deleted while in use by stack [cfn-demo-ec2]
対処法:
- Export値を参照しているスタックを先に削除
- 依存関係を確認:
aws cloudformation list-imports --export-name cfn-demo-vpc-id
権限エラー
User: arn:aws:iam::123456789012:user/cfn-user is not authorized to perform: cloudformation:CreateStack
対処法:
- IAMユーザーに
AWSCloudFormationFullAccessポリシーがあるか確認 - 作成するリソースに対応する権限があるか確認
-
aws sts get-caller-identityで正しいユーザーか確認
AWS CLI・Terraform・CloudFormation の使い分け
AWS CLIは「今の状態を確認する」、Terraformは「あるべき状態を定義する」、CloudFormationは「AWSネイティブであるべき状態を定義する」という使い分けが効果的です
| 用途 | AWS CLI | Terraform | CloudFormation |
|---|---|---|---|
| 一時的な確認・調査 | ○ | △ | × |
| リソースの一覧取得 | ○ | △ | △ |
| インフラの構築・管理 | △ | ○ | ○ |
| 環境の再現 | △ | ○ | ○ |
| チーム開発 | △ | ○ | ○ |
| 変更履歴の管理 | × | ○(Git連携) | ○(Git連携) |
| ドリフト検知 | × | ○ | ○ |
| マルチクラウド対応 | × | ○ | × |
| AWS以外のツール不要 | ○ | × | ○ |
| スタックのロールバック | × | △ | ○(自動) |
| AWSサポート対象 | ○ | × | ○ |
まとめ
CloudFormationを使うことで、AWSインフラをテンプレートとして管理できます
この記事で紹介した内容:
- CloudFormationの環境準備(AWS CLIのみで利用可能)
- テンプレートの基本構造(YAML形式)
- VPC・サブネット・EC2の作成
- スタックの作成・更新・削除
- 変更セットによる安全な更新
- ドリフト検知
CloudFormationに慣れると、AWS純正の安心感のもとでインフラの構築・変更・削除がテンプレート一つで完結し、自動ロールバックやドリフト検知により安全な運用が実現できます
