はじめに
どーも!shihopowerです!
AWS SAPの対策をしていると、DeletionPolicy という聞き慣ないポリシーが出てきて「…なんだこれ?」となりました。調べてみるとCloudFormationのリソース属性の一種でした。
そこで、CloudFormationに関連するポリシー・制御機能を網羅的に調べ、それぞれの役割と違いを整理しました。本記事はAWS公式ドキュメントをもとに作成しています。
忙しい人向け要約
CloudFormationには「ポリシー」と名のつくものや、制御機能が複数あって混乱しがちです。一言でいうと、設定場所・発動タイミング・何を制御するかがそれぞれ違います。
| 機能 | 設定場所 | 発動タイミング | 目的 |
|---|---|---|---|
| IAMポリシー | IAMユーザー/ロール | すべてのAPI呼び出し時 | 「誰が」CloudFormation操作をできるか制御 |
| スタックポリシー | スタックに対して別途設定 | スタック更新時 | リソースへの更新アクション自体を許可/拒否 |
| 終了保護 | スタックオプション | スタック削除試行時 | スタック自体の削除を防ぐ |
| DeletionPolicy | テンプレート内(リソース単位) | スタック削除時・リソース削除時 | 削除されたリソースをどう扱うか |
| UpdateReplacePolicy | テンプレート内(リソース単位) | 更新でリソースが置き換えられた時 | 古いリソースをどう扱うか |
目次
- なぜ混乱するのか
- ① IAMポリシー(アクセス制御)
- ② スタックポリシー(更新操作のガード)
- ③ 終了保護(削除のガード)
- ④ DeletionPolicy属性(削除時のリソースの扱い)
- ⑤ UpdateReplacePolicy属性(置き換え時のリソースの扱い)
- コラム:他にもあるリソース属性
- 全機能の比較まとめ
- おわりに
1. なぜ混乱するのか
CloudFormationには「ポリシー」や「制御機能」が複数あり、名前が似ていたり目的が重複して見えたりします。混乱の主な原因は以下の2点です。
- 設定場所がバラバラ:テンプレートの中に書くもの、スタックに対して設定するもの、IAMに設定するものが混在している
- どのタイミングで発動するかが違う:削除時だけ、更新時だけ、など発動条件がそれぞれ異なる
この2軸(「どこに設定するか」「いつ発動するか」)を意識すると、各機能の役割がスッキリ整理できます。
2. ① IAMポリシー(アクセス制御)
一言でいうと
「誰が」「何のCloudFormation操作を」できるかを制御するもの
概要
IAMポリシーは、CloudFormation固有の概念ではなくAWS全体のアクセス制御の仕組みです。
CloudFormationへのアクセスを許可するには、IAMアイデンティティ(ユーザーやロール)が必要なAPIアクションを呼び出す権限を付与するIAMポリシーを作成・割り当てる必要があります。IAMアイデンティティベースポリシーでは、アクションやリソースの許可・拒否と、それらが許可・拒否される条件を指定できます。
参考:Control CloudFormation access with AWS Identity and Access Management
記述場所
IAMポリシー(テンプレートの外)
アクションの指定方法
IAMポリシーステートメントの Action 要素には、CloudFormationが提供するAPIアクションを指定できます。アクション名の前に小文字の cloudformation: プレフィックスが必要です。
"Action": [
"cloudformation:CreateStack",
"cloudformation:UpdateStack"
]
ワイルドカードで複数のアクションを一括指定することもできます。
"Action": "cloudformation:Get*"
ポリシー例:特定スタックの削除・更新を拒否
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"cloudformation:DeleteStack",
"cloudformation:UpdateStack"
],
"Resource": "arn:aws:cloudformation:us-east-1:111122223333:stack/MyProductionStack/*"
}
]
}
注意点
aws:SourceIp のAWS共通条件は使用しないでください。CloudFormationはリクエスト元のIPアドレスではなく、CloudFormation自身のIPアドレスを使用してリソースをプロビジョニングするためです。
3. ② スタックポリシー(更新操作のガード)
一言でいうと
スタック更新時に「このリソースだけは触らせない」というガードを設けるもの
概要
スタックポリシーは、指定されたリソースに対して実行できる更新アクションを定義するJSONドキュメントです。スタックポリシーを設定すると、スタック内のすべてのリソースがデフォルトで保護されます。特定のリソースへの更新を許可するには、スタックポリシーにそれらのリソースの明示的な Allow ステートメントを指定します。
スタックポリシーはスタックの更新時にのみ適用されます。IAMポリシーのようなアクセス制御を提供するものではありません。スタックポリシーは、特定のスタックリソースへの誤った更新を防ぐためのフェイルセーフ機構としてのみ使用してください。AWSリソースやアクションへのアクセス制御にはIAMを使用してください。
記述場所
スタックに対して別途設定するJSONドキュメント(テンプレートの外)
ポリシーの5つの要素
| 要素 | 説明 |
|---|---|
Effect |
Allow または Deny を指定。Deny は常に Allow より優先される |
Action |
更新アクションを指定 |
Principal |
ポリシーの適用対象(ワイルドカード * のみサポート) |
Resource |
適用するリソースの論理ID |
Condition |
適用するリソースタイプ |
Action に指定できる更新アクション
| アクション | 説明 |
|---|---|
Update:Modify |
リソースが中断なし、または一部中断しながら変更される更新。物理IDは維持される |
Update:Replace |
リソースが再作成される更新。物理IDが変わる場合がある |
Update:Delete |
リソースが削除される更新 |
Update:* |
すべての更新アクション(ワイルドカード) |
ポリシー例:本番DBへの更新を拒否
{
"Statement" : [
{
"Effect" : "Allow",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "*"
},
{
"Effect" : "Deny",
"Action" : "Update:*",
"Principal": "*",
"Resource" : "LogicalResourceId/ProductionDatabase"
}
]
}
Allow ステートメントはすべてのリソースへのすべての更新を許可しますが、明示的な Deny ステートメントが ProductionDatabase の論理IDを持つリソースに対してそれを上書きします。
制限事項
- スタックごとに設定できるスタックポリシーは1つのみ
- 一度設定したスタックポリシーは削除不可(内容の変更はAWS CLIで可能)
- 保護されたリソースを更新するには
cloudformation:SetStackPolicy権限が必要
4. ③ 終了保護(Termination Protection)
一言でいうと
スタック自体が誤って削除されるのを防ぐスイッチ
概要
終了保護は、スタックそのものの削除試行をブロックするシンプルな機能です。有効にすると、削除リクエストを送ってもエラーになり、スタックは削除されません。
終了保護はスタックの削除試行にのみ適用されます。スタック更新時の挙動には影響しません。
記述場所
スタックオプション(コンソールの「スタックの作成」→「詳細オプション」→「終了保護」)
必要なIAM権限
終了保護を有効または無効にするには、cloudformation:UpdateTerminationProtection アクションへの権限が必要です。
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["cloudformation:UpdateTerminationProtection"],
"Resource": "*"
}]
}
5. ④ DeletionPolicy属性(削除時のリソースの扱い)
一言でいうと
スタック削除やリソース削除時に、そのリソースをどう扱うかをテンプレートに宣言するもの
概要
DeletionPolicy 属性を使うと、スタックが削除されたときにリソースを保持したり、場合によってはバックアップしたりできます。制御したいリソースごとに DeletionPolicy 属性を指定します。DeletionPolicy 属性がないリソースは、CloudFormationがデフォルトで削除します。
この機能はスタック更新操作中に物理インスタンスが置き換えられるリソースには適用されません。置き換え時の挙動は UpdateReplacePolicy で制御します。
記述場所
テンプレート内の各リソース定義(テンプレートの中)
指定できるオプション
| オプション | 説明 |
|---|---|
Delete(デフォルト) |
スタック削除時にリソースとその内容を削除する |
Retain |
スタックが削除されてもリソースを残す。削除後も課金が継続する点に注意 |
RetainExceptOnCreate |
作成時のロールバックを除き Retain と同様。新規で空のリソースは削除し、使用中のリソースは保持する |
Snapshot |
スナップショットをサポートするリソースに対して、削除前にスナップショットを作成する |
デフォルトが Snapshot になる例外
AWS::RDS::DBCluster-
DBClusterIdentifierプロパティを指定しないAWS::RDS::DBInstance
Snapshot をサポートするリソース
AWS::DocDB::DBClusterAWS::EC2::VolumeAWS::ElastiCache::CacheClusterAWS::ElastiCache::ReplicationGroupAWS::Neptune::DBClusterAWS::RDS::DBClusterAWS::RDS::DBInstanceAWS::Redshift::Cluster
テンプレート記述例
AWSTemplateFormatVersion: '2010-09-09'
Resources:
MyBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain # スタック削除後もバケットを残す
6. ⑤ UpdateReplacePolicy属性(置き換え時のリソースの扱い)
一言でいうと
スタック更新でリソースが置き換えられる際に、古いリソースをどう扱うかをテンプレートに宣言するもの
概要
スタックを更新すると、CloudFormationは変更内容に基づいてリソースを更新します。物理的な置き換え(Replacement)が必要なプロパティを変更した場合、CloudFormationは新しいリソースを作成してから古いリソースを削除します。UpdateReplacePolicy はこの「古いリソースの扱い」を制御します。
デフォルトでは、CloudFormationは古いリソースを削除します。UpdateReplacePolicy を使うと、古いリソースを保持したり、スナップショットを作成したりできます。
記述場所
テンプレート内の各リソース定義(テンプレートの中)
DeletionPolicy との違い(公式による明記)
UpdateReplacePolicy は DeletionPolicy 属性と異なり、スタック更新中に置き換えられたリソースにのみ適用されます。スタックが削除されたとき、またはスタック更新の一部としてテンプレートからリソース定義自体が削除されたときに削除されるリソースには DeletionPolicy を使用してください。
指定できるオプション
| オプション | 説明 |
|---|---|
Delete(デフォルト) |
置き換え時に古いリソースとその内容を削除する |
Retain |
置き換え後も古いリソースを残す。CloudFormationの管理スコープからは外れる |
Snapshot |
スナップショットをサポートするリソースに対して、削除前にスナップショットを作成する |
Snapshot をサポートしないリソースに Snapshot を指定すると、CloudFormationはデフォルトの Delete に戻ります。
テンプレート記述例
RDSの Engine プロパティを変更するとリソースの置き換えが発生します。古いDBインスタンスを誤って失わないよう、両方のポリシーを設定するのが安全です。
AWSTemplateFormatVersion: '2010-09-09'
Resources:
myDB:
Type: AWS::RDS::DBInstance
DeletionPolicy: Retain # スタック削除時に古いDBを残す
UpdateReplacePolicy: Retain # 更新で置き換わった場合も古いDBを残す
Properties: {}
7. コラム:他にもあるリソース属性
ここまで DeletionPolicy と UpdateReplacePolicy を詳しく見てきましたが、公式ドキュメントの「Resource attribute reference」によると、テンプレートのリソースに設定できる属性はこの2つだけではありません。
全7種のリソース属性が定義されています。以下に残りの5つを紹介します。
リソース属性の全一覧
| 属性名 | 一言で言うと | 発動タイミング |
|---|---|---|
CreationPolicy |
リソース作成完了の条件を定義する | リソース作成時 |
Condition |
条件次第でリソースの作成自体をスキップする | テンプレート評価時 |
DependsOn |
リソースの作成順序を明示的に指定する | スタック作成・更新・削除時 |
Metadata |
リソースに任意のメタデータを付与する | (直接の動作制御なし) |
UpdatePolicy |
特定リソースの更新方法を細かく制御する | スタック更新時 |
DeletionPolicy |
削除時のリソースの扱いを定義する | スタック削除時など |
UpdateReplacePolicy |
置き換え時の古いリソースの扱いを定義する | 更新で置き換え発生時 |
CreationPolicy — 作成完了を「シグナル」で確認する
CreationPolicy 属性をリソースに関連付けると、CloudFormationが指定された数の成功シグナルを受け取るか、タイムアウト期間が超過するまで、リソースのステータスが「作成完了」に達するのを防ぐことができます。リソースにシグナルを送るには、cfn-signal ヘルパースクリプトまたは SignalResource APIを使用します。
たとえばEC2インスタンス上でアプリケーションのインストールと設定が完了してから次の処理に進みたい場合に使います。
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MinSize: '1'
MaxSize: '4'
# ...
CreationPolicy:
ResourceSignal:
Count: '3' # 3つのインスタンスからの成功シグナルを待つ
Timeout: PT15M # 最大15分待機
CreationPolicy をサポートするリソースは限定的で、AWS::AutoScaling::AutoScalingGroup、AWS::EC2::Instance、AWS::CloudFormation::WaitCondition、AWS::AppStream::Fleet のみです。
Condition — 環境によってリソース作成をスキップする
CloudFormationで条件に基づいてリソースを作成するには、まずテンプレートの Conditions セクションで条件を宣言します。次に、Condition キーと条件の論理IDをリソースの属性として使用します。CloudFormationは条件が true と評価された場合にのみリソースを作成します。
例えば本番環境のみCloudWatchアラームを作成し、開発環境では作成しない、といった制御ができます。
Parameters:
EnvType:
Type: String
AllowedValues: [prod, dev]
Conditions:
CreateBucket: !Equals [!Ref EnvType, prod]
Resources:
MyBucket:
Type: AWS::S3::Bucket
Condition: CreateBucket # prodのときだけ作成される
DependsOn — 作成順序を明示的に指定する
DependsOn 属性を使うと、特定のリソースの作成が別のリソースの後に続くよう指定できます。リソースに DependsOn 属性を追加すると、そのリソースは DependsOn 属性で指定されたリソースの作成が完了した後にのみ作成されます。
CloudFormationはデフォルトで可能な限り並列にリソースを作成しますが、依存関係がある場合は DependsOn で明示します。
Resources:
MyDB:
Type: AWS::RDS::DBInstance
# ...
MyEC2:
Type: AWS::EC2::Instance
DependsOn: MyDB # DBが作成完了してからEC2を作成する
# ...
UpdatePolicy — 特定リソースの更新方法を細かく制御する
UpdatePolicy 属性は、スタック更新操作中に特定のリソースの更新をCloudFormationがどのように処理するかを指定するために使用します。
UpdateReplacePolicy(置き換え後の古いリソースの扱い)とは異なり、UpdatePolicy は更新の実行方法そのものを制御します。対象リソースは以下の通りです。
| 対象リソース | 制御できる内容 |
|---|---|
AWS::AutoScaling::AutoScalingGroup |
ローリング更新・グループ置き換え更新の方法を細かく制御 |
AWS::ElastiCache::ReplicationGroup |
シャードをオンラインのまま追加・削除する |
AWS::OpenSearchService::Domain |
ダウンタイムなしでバージョンアップグレード |
AWS::Lambda::Alias |
CodeDeployを使ったデプロイを実行 |
AWS::AppStream::Fleet |
更新前にフリートを停止し、更新後に再起動 |
UpdatePolicy と UpdateReplacePolicy は名前が似ていますが役割が異なります。
-
UpdatePolicy→ 更新を「どうやって」実行するかの方法を指定(特定リソースのみ) -
UpdateReplacePolicy→ 置き換えで生じた古いリソースを「どう扱うか」を指定(全リソース対象)
Metadata — リソースにメタデータを付与する
Metadata 属性は、リソースに任意の構造化データを付与するための属性です。直接リソースの動作を制御するものではなく、cfn-init ヘルパースクリプトの設定情報を埋め込んだり、ツールやシステムがテンプレートを処理する際に使う補足情報を格納したりする用途で使われます。
8. 全機能の比較まとめ
機能の位置づけ一覧
| 機能 | 設定場所 | 発動タイミング | 制御の粒度 |
|---|---|---|---|
| IAMポリシー | IAMユーザー/ロール | すべてのAPI呼び出し時 | ユーザー/ロール単位 |
| スタックポリシー | スタックに対して別途設定 | スタック更新時 | リソースの論理ID単位 |
| 終了保護 | スタックオプション | スタック削除試行時 | スタック単位 |
| DeletionPolicy | テンプレート内リソース定義 | スタック削除時・テンプレートからリソース削除時 | リソース単位 |
| UpdateReplacePolicy | テンプレート内リソース定義 | 更新でリソースが置き換えられた時 | リソース単位 |
「どれを使えばよいか」の考え方
Q. 「誰が」CloudFormation操作をできるか制御したい
→ IAMポリシー
Q. スタック更新中に特定リソースへの変更を防ぎたい
→ スタックポリシー
Q. スタック自体が誤って削除されるのを防ぎたい
→ 終了保護
Q. スタック削除後もリソースを残したい or バックアップを取りたい
→ DeletionPolicy
Q. スタック更新でリソースが置き換わる際に古いリソースを残したい or バックアップを取りたい
→ UpdateReplacePolicy
保護の三層構造(実運用での考え方)
実運用では以下の三層で組み合わせて使うのが効果的です。
Layer 1(入口) : IAMポリシー → 操作権限そのものを制限
Layer 2(ガード): スタックポリシー → 更新操作を制限
Layer 3(保険) : DeletionPolicy / → 万一の削除・置き換え時のデータ保護
UpdateReplacePolicy
+ 終了保護 → スタック本体の誤削除防止
9. おわりに
今回はCloudFormationに関連するポリシー・制御機能と、リソース属性の全種類を整理しました。
以下の2軸を意識すると各機能の役割が整理しやすくなります。
- 「設定場所がどこか」(テンプレートの中 vs. 外)
- 「いつ発動するか」(削除時 / 更新時 / API呼び出し時)
この記事がお役に立てれば幸いです。最後まで読んでいただきありがとうございました!
参考:AWS公式ドキュメント
- Control CloudFormation access with AWS Identity and Access Management
- Prevent updates to stack resources (Stack Policy)
- Protect CloudFormation stacks from being deleted (Termination Protection)
- Resource attribute reference(全リソース属性一覧)
- CreationPolicy attribute
- Condition attribute
- DependsOn attribute
- Metadata attribute
- UpdatePolicy attribute
- DeletionPolicy attribute
- UpdateReplacePolicy attribute