【実務・中級編】【実務で使える】CloudFormationスタックの変更管理と安全なアップデート手順 – インフラ構成管理(IaC)活用バイブル

【実務で使える】CloudFormationスタックの変更管理と安全なアップデート手順

こんにちは。テックリードの私だ。

日々のインフラ運用の現場において、AWS CloudFormationはなくてはならない存在だ。しかし、規模が拡大するにつれて、こんな恐怖に直面したことはないだろうか。

「`aws cloudformation update-stack` を叩いた瞬間、本番のRDSインスタンスが置換(Replacement)され、データが消えかけた」

……冷や汗が出る光景だな。マニュアル通りのコードを書くだけでは、プロダクション環境の「破壊」を防ぐことはできない。IaC(Infrastructure as Code)において、コードの記述量以上に重要なのは「変更の安全性をいかに担保するか」というプロセス設計だ。

今回は、数々の修羅場を潜り抜けたSREチームが実践している、CloudFormationの変更管理と安全なアップデートの極意を余すところなく伝授する。明日からのデプロイの質が劇的に変わるはずだ。

—

1. 変更セット(Change Set)を活用した事前プレビューの鉄則

「とりあえず `update-stack` を実行して、エラーが出たらロールバックを待つ」——そんなギャンブル運用の時代は終わった。本番環境への変更は、必ず変更セット(Change Set)を介して実行すべきだ。

変更セットは、既存のスタックに対してテンプレートを適用した場合に、「AWSリソースがどのように作成・変更・削除されるか」を事前に予測(シミュレーション)するための機能である。

変更セット運用のベストプラクティス(AWS CLI)

CI/CDパイプラインや手動デプロイのスクリプトでは、以下の3ステップを厳格に踏む。

1. 変更セットの作成(名前を一意にするためにタイムスタンプ等を付与)
aws cloudformation create-change-set \
–stack-name production-vpc-stack \
–template-body file://template.yaml \
–parameters ParameterKey=Environment,ParameterValue=production \
–change-set-name changeset-$(date +%s) \
–capabilities CAPABILITY_NAMED_IAM

2. 変更内容のレビュー(CLIやコンソールで確認。特に「REPLACE」の有無を目視点検)
※ コンソールで変更セットのグラフィカルなプレビューを見るのが最も確実。

3. 変更セットの実行
aws cloudformation execute-change-set \
–stack-name production-vpc-stack \
–change-set-name changeset-<作成された変更セット名>

このフローを強制することで、「意図しない変更」をデプロイ前に100%検知できる。

—

2. 意図しないリソース置換(Replacement)を防ぐテクニック

CloudFormationのアップデート時、最も恐ろしいのが `Replacement: True`(リソースの削除&再作成) を伴う変更だ。例えば、RDSの識別子(DBInstanceIdentifier)や、S3バケット名など、一部のプロパティは変更するとリソースが丸ごと作り直される。

これを見落として本番環境を吹っ飛ばさないための、プロの防衛術を公開する。

テクニック①:`DeformationPolicy` と `UpdateReplacePolicy` の明示

リソースが誤って削除・置換されるのを防ぐため、必ず以下のポリシーをコードに埋め込む。

Resources:
SecureDataBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: my-super-secret-data-bucket-prod
# スタック削除時だけでなく、アップデート時の置換による削除からも保護
DeletionPolicy: Retain
UpdateReplacePolicy: Retain

`UpdateReplacePolicy: Retain` を指定しておけば、万が一テンプレートの変更によってバケットが置換対象になったとしても、古いバケットはAWS側に残ったままになり、データロスを防げる。

テクニック②:IDEプラグインで「変更の予兆」を視覚化する

VSCodeを使用しているなら、以下の拡張機能は必須だ。

  • AWS Toolkit for Visual Studio Code
  • テンプレートのバリデーションや、リソースの補完だけでなく、構文エラーをリアルタイムで検知できる。
  • CloudFormation Linter (cfn-lint)
  • 静的解析ツール。CI/CDパイプラインの初期段階でこれを走らせることで、非推奨なプロパティや危険な設定を弾く。

cfn-lint の設定例 (.cfnlintrc.yaml)
platforms:

  • aws::us-east-1
  • aws::ap-northeast-1

ignore_checks:

  • E2530 # 特定の警告を無視する場合

—

3. Termination Protection(削除保護)の設定方法

スタック自体の誤削除(`aws cloudformation delete-stack` の暴発など)は、SREにとって悪夢だ。これを物理的に防ぐのが Termination Protection(削除保護) である。

本番環境のスタックを作成した直後、あるいは初期構築のスクリプト内に、必ず以下の設定を組み込む。

AWS CLIでの有効化

aws cloudformation update-termination-protection \
–enable-termination-protection \
–stack-name production-vpc-stack

> ⚠️ 現場の知見:
> 削除保護が有効なスタックを削除しようとすると、AWS側でエラーが返され、リソースは完全に保護される。スタックを本当に削除する必要が生じた場合は、事前にこの保護を明示的に無効化(`–no-enable-termination-protection`)する必要があるため、心理的・物理的な安全装置として機能する。

—

4. 既存リソースをCloudFormationにインポートする方法

「すでに手動や別ツールで構築してしまった既存のAWSリソースを、CloudFormationの管理下に置きたい」
これは実務で頻繁に直面する課題だ。リソースを作り直すことなく、安全にCloudFormationへ取り込むリソースインポート機能の手順を解説する。

ステップ1:既存リソース定義をテンプレートに追加

インポートしたいリソースの定義をテンプレートに記述する。この際、リソースの物理ID(例: S3バケット名やVPC ID)をプロパティにハードコード(またはパラメータ化)しておく。

Resources:
# すでに手動で存在しているVPCをインポートする例
ExistingVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:

  • Key: Name

Name: legacy-production-vpc

ステップ2:リソースマッピングファイル(ResourcesToImport)の作成

どの論理IDに、どの物理IDを紐付けるかをJSON形式で定義する。

[
{
“ResourceType”: “AWS::EC2::VPC”,
“LogicalResourceId”: “ExistingVPC”,
“ResourceIdentifier”: {
“VpcId”: “vpc-0123456789abcdef0”
}
}
]

ステップ3:インポート変更セットの実行

aws cloudformation create-change-set \
–stack-name imported-vpc-stack \
–template-body file://template.yaml \
–change-set-name import-changeset \
–change-set-type IMPORT \
–resources-to-import file://resources-to-import.json \
–capabilities CAPABILITY_NAMED_IAM

変更セットの内容を検証後、実行すれば、既存のライフサイクルを壊すことなくCloudFormationのスタック管理下にシームレスに統合できる。

—

【総仕上げ】実務で使えるベストプラクティス構成例

最後に、これらすべての知見を内包した、実務でそのまま流用できるディレクトリ構成とテンプレートの黄金パターンを提示する。

推薦ディレクトリ構成

infrastructure/
├── .cfnlintrc.yaml # cfn-lint 静的解析設定
├── Makefile # デプロイ・変更セット作成の定型化
└── cfn/
├── params/
│ └── production.json # パラメータファイル
└── templates/
└── network.yaml # メインテンプレート

1. `Makefile` によるオペレーションの標準化

手動コマンドの打率はヒューマンエラーの元だ。Makefileでオペレーションをコード化せよ。

STACK_NAME = production-network-stack
TEMPLATE_FILE = cfn/templates/network.yaml
PARAMS_FILE = cfn/params/production.json
CS_NAME = changeset-$(shell date +%s)

.PHONY: lint preview deploy

lint:
cfn-lint $(TEMPLATE_FILE)

preview: lint
aws cloudformation create-change-set \
–stack-name $(STACK_NAME) \
–template-body file://$(TEMPLATE_FILE) \
–parameters file://$(PARAMS_FILE) \
–change-set-name $(CS_NAME) \
–capabilities CAPABILITY_NAMED_IAM
@echo “Change Set ‘$(CS_NAME)’ created. Please review on AWS Console.”

deploy:
aws cloudformation execute-change-set \
–stack-name $(STACK_NAME) \
–change-set-name $(CS_NAME)

2. 堅牢なテンプレートのサンプル (`network.yaml`)

AWSTemplateFormatVersion: ‘2010-09-09’
Description: ‘Production Network Stack with Safety Guards’

Parameters:
Environment:
Type: String
Default: production
AllowedValues: [staging, production]

Resources:
# 削除保護・置換保護を考慮したVPC
ProductionVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.100.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:

  • Key: Environment

Value: !Ref Environment

  • Key: ManagedBy

Value: CloudFormation
# アップデート時の意図しない置換から保護
UpdateReplacePolicy: Retain
DeletionPolicy: Retain

Outputs:
VpcId:
Description: The VPC ID
Value: !Ref ProductionVPC
Export:
Name: !Sub “${AWS::StackName}-VpcId”

—

まとめ

CloudFormationの運用において、「スピード」と「安全性」はトレードオフではない。
変更セットによるプレビューの義務化、ポリシーによる破壊的変更の防止、そしてMakefile等によるオペレーションの自動化を徹底することで、むしろデプロイ速度は加速し、精神的な負荷は劇的に軽減される。

「祈りながらエンターキーを押す」ようなインフラ運用の泥臭いスタイルとは今日で決別しよう。君の手で、チームのデプロイパイプラインを鉄壁のものにしてくれ。

タイトルとURLをコピーしました