はじめに
既存の CloudFormation スタックに CloudWatch アラームなどを追記して、**変更セット(Change Set)**で安全に適用しようとしました。
create-change-set を実行 → できた変更セットを見ると、中身はすべて「追加(Add)・置き換えなし」。「よし、これを適用すれば OK」と思ったら、ステータスが…
FAILED。理由はこれだけ:
The following hook(s)/validation failed: [AWS::EarlyValidation::ResourceExistenceCheck].
中身は問題なさそうなのに、なぜか作成自体が失敗。
犯人は、セッションの最初に“手動(コンソール)で作ったアラーム”との名前かぶりでした😅
環境
- AWS CloudFormation(変更セット / Change Set)
- 既存スタックへの更新(
create-change-set→execute-change-set) - AWS CLI
起きたこと
変更セットの「中身」は健全でした(全リソース Add・Replacement: None):
| Action | LogicalId | Replacement |
| Add | CpuAlarm | None |
| Add | StatusAlarm | None |
| ... | ... | ... |
なのに、変更セットのステータスが FAILED:
Status: FAILED
StatusReason: The following hook(s)/validation failed: [AWS::EarlyValidation::ResourceExistenceCheck].
今回の表示では、「どのリソースが原因か」までは分からず、最初は途方に暮れました。
原因
エラー名 AWS::EarlyValidation::ResourceExistenceCheck を手がかりに確認したところ、今回はアカウント内にすでに存在する同名リソースとの衝突が原因でした。
思い当たりました。このセッションの最初に、同じアラームを“手動(コンソール)”で作っていたのです。そこへ、CloudFormation が同じ名前でアラームを作ろうとして衝突していました。
| 作った経路 | アラーム名 |
|---|---|
| 手動(コンソールで先に作成) |
app-ec2-cpu-high(既存) |
| CloudFormation(今回テンプレで作成) |
app-ec2-cpu-high(同名!) |
衝突しているアラームは、実際に存在していました:
aws cloudwatch describe-alarms \
--alarm-names app-ec2-cpu-high app-ec2-status \
--query 'MetricAlarms[].AlarmName' --region ap-northeast-1
# → 手動で作った同名アラームが返ってくる=衝突の正体
対処
「手動で作ったもの」と「CloudFormation で作るもの」が二重管理で名前衝突していたので、学習用の環境だったため手動分を削除して IaC に一本化しました。
aws cloudwatch delete-alarms \
--alarm-names app-ec2-cpu-high app-ec2-status --region ap-northeast-1
そのうえで変更セットを作り直すと、今度は通りました:
Status: CREATE_COMPLETE
ExecutionStatus: AVAILABLE
あとは execute-change-set で適用 → 同じアラームが、今度はCloudFormation 管理として作成されました。
※ 本番や運用中のリソースでは、いきなり削除せず、影響範囲を確認してから CloudFormation へのインポートや、テンプレート側の名前変更を検討するのが安全です(既存リソースを残したい場合の選択肢になります)。
学び
-
AWS::EarlyValidation::ResourceExistenceCheckは、既存リソースとの衝突など、作成前にリソースの存在関係を確認する検証で止まったサインでした。早期検証(バリデーション)は「適用前」に問題を教えてくれる味方。 - 原因が表示に出てこないときは、エラー名(フック名)で検索。AWS のエラーは名前が具体的なので、調べると当たりが早い。
- 手動(コンソール)と IaC(CloudFormation)を混ぜると名前衝突しやすい。IaC で管理するなら、同じものを2つの方法で作らない(先に手動で作ったものは整理する)。
- 変更セットの「中身(Add か Replace か)」が健全でも、作成ステータスが FAILED なら別の検証で止まっている。中身とステータスは分けて見る。
おわりに
「中身は正しいのに作れない」ときは、自分の手で先に作ったものとぶつかっていないかを疑うと早いかもしれません😅 手動とコードが混ざりがちな学習中の人の参考になれば嬉しいです🙌