【AWS CloudFormation】DeletionPolicyとUpdateReplacePolicyの深淵:本番環境を「神の一手」で守り抜くリソース保護の全知識
テックリードの私たちが日々のインフラ開発で最も恐れる瞬間、それは何だろうか。
それは、CI/CDパイプラインの暴走でも、複雑なIAMポリシーの競合でもない。「スタック更新時の意図しないリソース置換(Replacement)」による、本番データベースやオブジェクトストレージの全消滅だ。
「えっ、プロパティを1文字変えただけで、RDSインスタンスが丸ごと作り直された?」
「スタックを削除したら、顧客データが入ったS3バケットまで綺麗に消え去った……」
こうしたヒューマンエラーやCloudFormationの仕様の罠で冷や汗をかいた経験を持つエンジニアは少なくないはずだ。
CloudFormationには、この破滅的な事故を防ぐための強力な防衛策が2つ用意されている。それが `DeletionPolicy` と `UpdateReplacePolicy` だ。
今回は、この2つのポリシーの決定的な挙動差異を解き明かし、主要リソースにおける鉄壁の保護構成を叩き込む。
—
1. 2大ポリシーの決定的な違い:なぜ2つ存在するのか?
まず、大前提としてこの2つの違いを正確に理解してほしい。多くのジュニアエンジニアがここで混同を起こす。
- `DeletionPolicy`: スタック自体が削除されるとき(`aws cloudformation delete-stack`)、またはリソースがテンプレートから宣言的に削除されるときの挙動を制御する。
- `UpdateReplacePolicy`: リソースのプロパティ変更に伴い、CloudFormationが「リソースの置換(Replacement=古いものを削除して新しいものを作り直す)」を必要と判断したときの挙動を制御する。
> ⚠️ 致命的な誤解の防止
> 「`DeletionPolicy`を設定しておけば、アップデート時の置換からも守ってくれるだろう」という思い込みは今すぐ捨ててくれ。アップデート時の置換からリソースを守るには、必ず `UpdateReplacePolicy` を個別に指定するか、両方に同じ値を設定する必要がある。
指定可能な3つの値とそれぞれの運命
両ポリシーには、以下の3つの値を指定できる。
1. `Retain`(保持)
- 対象リソースは削除・置換されず、AWS上に残る。ただし、CloudFormationの管理下からは外れる(孤立リソース / Orphaned Resourceとなる)。
2. `Snapshot`(スナップショット)※一部のリソースのみ
- リソースが削除・置換される直前に、最終スナップショット(RDSやRedshiftなど)を取得する。
3. `Delete`(削除)
- デフォルトの挙動。容赦なくリソースを消し去る。
—
2. リソースタイプ別・挙動マトリクス
すべてのリソースが同じ挙動をするわけではない。特に `Snapshot` は対応しているリソースが限られる。実務で頻出する主要リソースの挙動を頭に叩き込んでおこう。
| リソースタイプ (`AWS::…`) | `DeletionPolicy: Retain` の挙動 | `UpdateReplacePolicy: Retain` の挙動 | `Snapshot` 対応状況 |
| :— | :— | :— | :— |
| `S3::Bucket` | バケットが残る(データ保護) | バケットが残る(新旧並存に注意) | 不可 |
| `RDS::DBInstance` | インスタンスが残る | インスタンスが残る | 可 (最終スナップショット取得) |
| `DynamoDB::Table` | テーブルが残る | テーブルが残る | 不可 (Point-in-Time Recoveryで担保) |
| `EC2::Volume` | ボリュームが残る | ボリュームが残る | 不可 |
| `IAM::Role` | ロールが残る | ロールが残る | 不可 |
—
3. 【実践】プロダクション品質のCloudFormationテンプレート
理論はこれくらいにして、実際にチーム開発の現場でそのまま使える、極限まで安全性を高めたYAMLテンプレートのベストプラクティス構成例を提示する。
以下のコードは、「絶対にデータを失ってはならない本番用のS3バケットとRDS」を定義したものである。
AWSTemplateFormatVersion: ‘2010-09-09’
Description: >
Production-grade infrastructure template with strict resource protection policies.
Designed by Tech Lead for Zero-Data-Loss deployments.
Parameters:
EnvironmentType:
Type: String
Default: production
AllowedValues: [development, staging, production]
Description: Target environment for the stack.
Resources:
# =================================================================
# S3 Bucket Protection
# =================================================================
SecureDataBucket:
Type: AWS::S3::Bucket
# [DeletionPolicy] スタック削除時の誤爆から守る
DeletionPolicy: Retain
# [UpdateReplacePolicy] バケット名変更などの置換を伴う更新から守る
UpdateReplacePolicy: Retain
Properties:
BucketName: !Sub “company-mission-critical-data-${EnvironmentType}”
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
# =================================================================
# RDS Database Protection
# =================================================================
ProductionDatabase:
Type: AWS::RDS::DBInstance
# 削除時は必ずスナップショットを取得し、かつリソースを保持する
DeletionPolicy: Snapshot
UpdateReplacePolicy: Snapshot
Properties:
DBInstanceIdentifier: !Sub “company-db-${EnvironmentType}”
Engine: postgres
EngineVersion: “15.4”
DBInstanceClass: db.m6i.large
AllocatedStorage: 100
MasterUsername: dbadmin
# 本番環境ではSecrets Manager等から取得すべきだが簡略化
MasterUserPassword: “{{resolve:secretsmanager:prod/db/password:SecretString:password}}”
BackupRetentionPeriod: 7
MultiAZ: true
StorageEncrypted: true
この構成のポイント
- S3バケット: `Retain` を指定しているため、万が一スタックごと消去するコマンドが走っても、S3バケットと中のオブジェクトはAWS上に生き残り、人災による全滅を防げる。
- RDS: `Snapshot` を指定。万が一、インスタンスクラスの変更などで置換が発生した場合でも、Amazon RDSが自動的に最終スナップショット(Final DBSnapshot)を切り離し前に取得するため、数世代前の状態に即座にロールバック・復旧が可能になる。
—
4. チーム開発生産性を爆上げするプラクティス&ツールチェーン
ここからは、テックリードとしてチーム全体の品質を底上げし、レビューコストをゼロにするための実践的アプローチを伝授する。
① 必須VSCodeプラグイン:人為的ミスの自動排除
コードレビューだけに頼るな。ツールに強制させろ。
- [AWS CloudFormation Linter (cfn-lint)](https://github.com/aws-cloudformation/cfn-python-lint)
- VSCodeの拡張機能として導入し、保存時にテンプレートの構文エラーだけでなく、ベストプラクティス違反を検知させる。
- [YAML Support by Red Hat](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml)
- JSON Schema Storeと連携し、CloudFormationのスキーマ補完を効かせることで記述ミスを激減させる。
② チーム共有設定:`cfn-lint` のカスタムルール(`.cfnlintrc`)
プロジェクトルートに以下の設定ファイルを置き、リポジトリ全体でポリシー未設定の危険なリソースをCI/CD(GitHub Actions等)で弾く仕組みを作れ。
.cfnlintrc
—
本番環境テンプレートにおいて、S3やRDSには必ずDeletionPolicyを強制するカスタム設定のベース
platforms:
- aws
除外するチェックID(必要に応じて)
exclude-checks:
- W2506 # 例: 特定の警告を無視する場合
テンプレート内のリソースで必須プロパティの検証を強化
strict: true
③ 開発スピードを加速するキーボードショートカット(VSCode)
IaCのコーディング速度を極限まで高めるためのショートカットの組み合わせだ。
- マルチカーソル編集 (`Ctrl + Alt + 下矢印` / `Cmd + Option + Down`): 複数のリソースブロックに `DeletionPolicy: Retain` を一括挿入する。
- コードの折り畳み/展開 (`Ctrl + Shift + [` / `Cmd + Option + [`): 巨大なYAMLファイル構造を俯瞰し、リソース単位でのブロック移動をノーマウスで行う。
- シンボルのクイックオープン (`Ctrl + T` / `Cmd + T`): `ProductionDatabase` などの論理IDへ一瞬でジャンプする。
—
5. 孤立リソース(Retainされた資源)の末路とデバッグの極意
最後に、`DeletionPolicy: Retain` を使ったあとに待ち受ける「現実」について話しておこう。
リソースが `Retain` された場合、スタックは正常に削除(あるいは更新)完了するが、AWS上にはリソースが残ったままになる。
そのまま同じスタック名で再デプロイしようとすると、CloudFormationはこう叫ぶ。
> `Resource with the name […] already exists.`
このエラーに直面したときのスマートな解決手順は以下の通りだ。
1. 手動でリソースを削除する場合: AWSコンソールやAWS CLIでリソースを直接削除する(S3なら中身を空にしてからバケット削除)。
2. 既存リソースを再度CloudFormationの管理下に置く場合: AWS CloudFormation 変更セット(Change Set)の「インポート(Import existing resources)」機能を使用する。これにより、野良リソースを再び安全にIaCの管理下に引き戻すことができる。
—
結び:インフラエンジニアの誇りをコードに宿せ
`DeletionPolicy` と `UpdateReplacePolicy` は、単なる設定パラメータではない。それは、「ビジネスの継続性を守るエンジニアの防壁」である。
「動けばいい」という次元を脱し、破壊的な変更からもシステムを守り抜く堅牢なテンプレートを書くこと。それこそが、現代の卓越したSRE・インフラエンジニアの仕事だ。
明日のデプロイから、すべての重要リソースにこのポリシーが記述されていることを確認してほしい。君のコードが、チームの夜間呼び出しを防ぐ最高のお守りになるはずだ。