CloudFormationの深淵:IaCの鉄則と「本番を破壊させない」ためのアーキテクチャ設計
CloudFormation(CFn)を単なる「YAMLを書くツール」だと思っているなら、今すぐその認識を改めるべきだ。CFnはAWS APIの薄いラッパーではない。これは、宣言的記述によってクラウドの状態を数学的に定義し、遷移させる「ステートマシン」そのものである。
本番環境のデプロイで心臓をバクバクさせるのは、設計の敗北だ。今回は、私が数千のスタックを運用してきた中で辿り着いた、「本番を絶対に壊さない」ための極限の管理術を叩き込む。
—
1. 変更セット(Change Set)を「通過儀礼」にする
CFnのデプロイコマンドを直接実行する人間は、プロではない。変更セット(Change Set)なしにスタックを更新することは、目隠しをして高速道路を走るに等しい。
CI/CDパイプラインにおいては、`aws cloudformation create-change-set` を発行し、その実行結果を人間(またはPolicy as Codeツール)が監査するプロセスを強制せよ。
究極の自動化:Change Setの解析スクリプト
単に作成するだけでは意味がない。リソースの「置換(Replacement)」を検知し、即座にSlackへ通知するフックを仕込むのが真のSREだ。
Change Setを作成し、リソース置換が発生するかを判定する簡易シェル
STACK_NAME=”prod-core-infra”
CHANGE_SET_NAME=”cs-$(date +%s)”
Change Set生成
aws cloudformation create-change-set –stack-name $STACK_NAME –change-set-name $CHANGE_SET_NAME \
–template-body file://template.yaml
生成を待機
aws cloudformation wait change-set-create-complete –stack-name $STACK_NAME –change-set-name $CHANGE_SET_NAME
置換(Replacement)が含まれているかJSONを解析
注意: ‘Replacement’ が ‘True’ のリソースを抽出
REPLACEMENT_COUNT=$(aws cloudformation describe-change-set –stack-name $STACK_NAME –change-set-name $CHANGE_SET_NAME \
–query “Changes[?ResourceChange.Replacement==’True’]” –output json | jq length)
if [ “$REPLACEMENT_COUNT” -gt 0 ]; then
echo “CRITICAL: $REPLACEMENT_COUNT resources will be REPLACED. Aborting.”
exit 1
fi
—
2. 意図しないリソース置換(Replacement)を防ぐテクニック
CFnがリソースを置換する最大の理由は「不変プロパティの変更」だ。RDSのDB識別子や、EC2のインスタンスタイプ(一部)、S3バケット名などを変更しようとすると、CFnは容赦なく既存リソースを削除(Delete)して再作成(Create)する。
これを防ぐための「守護神」が Stack Policy だ。
{
“Statement”: [
{
“Effect”: “Deny”,
“Action”: “Update:Replace”,
“Principal”: “”,
“Resource”: “”,
“Condition”: {
“StringEquals”: {
“ResourceType”: [“AWS::RDS::DBInstance”, “AWS::S3::Bucket”]
}
}
}
]
}
このポリシーを適用すれば、誤ったテンプレート変更による破壊的な置換を、APIレベルで拒絶できる。IaCの安全性を担保するのはコードだけでなく、こうした境界保護だ。
—
3. Termination Protection:最期の砦
「人間はミスをする」という前提に立て。どれほど優れたエンジニアでも、深夜のデプロイで `aws cloudformation delete-stack` を打つ可能性はゼロではない。
プロダクション環境のスタックには、必ず Termination Protection を有効化せよ。これはCFnの論理的な保護層であり、API経由の削除操作を完全にブロックする。
スタック保護を有効化(CI/CDのパイプライン初期化時に1回叩く)
aws cloudformation update-termination-protection \
–enable-termination-protection \
–stack-name prod-core-infra
これを有効にしておけば、スタックを削除しようとした瞬間にAPIは `400 Bad Request` を返し、あなたの夜間呼び出しを未然に防いでくれる。
—
4. 既存リソースの「無血開城」:インポートの極意
「すでに手動で作られたリソースをIaCに移行したい」という要望は、現場で最も血が流れる作業だ。ここでミスをすれば、既存の稼働中リソースが消滅する。
CFnの「インポート機能」を使う際の鉄則は以下の3つだ。
1. スタックを分ける: 既存インフラ全体を単一スタックに押し込もうとするな。インポートは最小単位(マイクロスタック)で行え。
2. ドリフト検知を先に走らせる: `aws cloudformation detect-stack-drift` を使い、既存リソースがすでに定義と乖離していないか確認してからインポートせよ。
3. テンプレートの完全一致: インポート用テンプレートは、既存リソースの属性(物理ID)を正確にマッピングする必要がある。まずは `ResourceImport` モードで慎重に突き合わせを行うこと。
—
伝説的エンジニアからの提言
IaCの本質は「自動化」ではなく「予測可能性(Predictability)」にある。
CloudFormationは、その堅牢なステート管理によって、他のツールにはない「安全性」という武器を提供している。デプロイを自動化するなら、パイプラインの途中に「人間が見るべき差分」と「APIが防ぐべき破壊」を組み込め。
コードを書くとき、私は常に「もしこのデプロイが明日午前3時に自動実行されたら、自分は安眠できるか?」と自問する。この問いにYesと答えられる状態こそが、エンジニアリングの到達点だ。
さあ、GUIから離れ、ステートをコードで支配せよ。インフラの未来は、君の書くテンプレートの中にこそある。