0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Terraform】terraform destroy したのに課金が止まらなかった話(state の外にいたリソース)

0
Posted at

はじめに

個人開発で AWS を触っていて、検証が終わったので terraform destroy で一式まとめて片付けました。「これで課金ゼロに戻ったはず」と安心していたのですが、後日コンソールを見たら、消したはずの ALB と WAF がまだ残っていて課金が続いていました😨

原因は単純で、それらは **Terraform で作っていなかった(=state の外にいた)**リソースでした。

先に結論:terraform destroy が消すのは Terraform が state で管理しているものだけ。コンソールや CLI で手作業で作ったリソースは、destroy しても残ります。

環境

  • Terraform(AWS プロバイダ)
  • Application Load Balancer(ALB)
  • AWS WAF(WAFv2・REGIONAL)
  • デフォルト VPC 上に手作業で作っていた検証リソース
  • リージョン: ap-northeast-1(東京)

起きたこと

メインの構成は Terraform で作っていたので、片付けはこれ一発のつもりでした。

terraform destroy

destroy 自体は正常に完了しました。ところが後日、コンソールと請求まわりを見ると、ALB と WAF の Web ACL が残ったまま。ALB は稼働時間や LCU に応じた料金がかかり、WAF も Web ACL やルール、リクエスト数に応じて料金が発生します。どちらも「使っていないつもり」でも、残っていれば請求要因になります。

「destroy は成功したのに、なんで残ってる…?」というのが最初の混乱です。

原因:手で作ったものは state に載っていなかった

思い出すと、その ALB と WAF は 以前 WAF の挙動を手で試したときに、コンソール/CLI で作ったものでした。Terraform のコードには書いていません。

確認すると、やはり管理対象に入っていませんでした。

terraform state list | grep -i "lb\|waf"
# → 何も出てこない(=Terraform は管理していない)

terraform destroystate に載っているリソースを消すコマンドなので、state に無い=手作業で作ったものは、当然そのまま残ります。「IaC で作った構成だから destroy すれば全部消える」と思い込んでいたのが落とし穴でした。実際には、同じアカウントの中に “Terraform 管理” と “手作業” が混在していて、後者だけ取り残されていたわけです。

対処:依存順に手で外してから、再発防止

残骸は依存関係があるので、順番に外す必要がありました。今回は不要な Web ACL だったので、関連付けを外したあとに Web ACL 自体も削除しています(WAF は、関連付けさえ外せば Web ACL を削除できます)。

WAF の関連付け(association)を外す
  → Web ACL を削除(今回は不要なので削除。残す運用もある)
    → ALB を削除
      → (消えるまで待つ)
        → ALB 用のセキュリティグループを削除

この順で削除し、最後に CLI で「対象が残っていないか」を確認しました。

aws wafv2 list-web-acls --scope REGIONAL --region ap-northeast-1
aws elbv2 describe-load-balancers --region ap-northeast-1
# → 対象の ALB / Web ACL が一覧から消えていれば、少なくとも今回確認した課金要因は削除できた

(アカウント全体の請求が止まったとは限りません。NAT Gateway・EIP・EBS・スナップショット・CloudWatch Logs など、別の残骸があれば別途確認が要ります。)

そのうえで再発防止として、手で作っていたこの検証構成を、独立した Terraform コードに起こし直しました。SG・ALB・リスナー・WAFv2(REGIONAL)・関連付けを 1 ファイルにまとめ、

  • terraform applyいつでも同じ構成を再現できる
  • terraform destroy関連付けごと一括で消せる

という形にしておきました。こうしておけば、次からは「手作業で作って消し忘れる」がそもそも起きません。

# 復旧・検証用に独立させた構成(抜粋)
resource "aws_lb" "demo"            { /* ... */ }
resource "aws_wafv2_web_acl" "demo" { /* ... */ }
resource "aws_wafv2_web_acl_association" "demo" {
  resource_arn = aws_lb.demo.arn
  web_acl_arn  = aws_wafv2_web_acl.demo.arn
}

なお、すでに手作業で作ったものを「今後も残したい」場合は、削除ではなく Terraform 管理へ移す手もあります。その場合は まず Terraform コードにそのリソースを定義し、その後 terraform import で state に取り込む、という順番になります(import は「コードに書いてから取り込む」のが前提)。今回は不要な検証環境だったので、削除して作り直せる形に寄せました。

学び

  • terraform destroy が消すのは state にあるものだけ。手作業で作ったリソースは残る。
  • 片付けたら、コードだけでなく コンソール/CLI でも「本当に消えたか」を確認する。特に ALB・WAF・NAT Gateway など “残っているだけで料金がかかる” 系は要注意。
  • 既存リソースを Terraform 管理へ移すなら、コード定義 → terraform import の順。不要なら削除して終わらせる。
  • 「IaC で作ったから destroy で全部消える」は、同じアカウントに手作業リソースが混じっていると成り立たない

おわりに

「destroy は成功、でも請求は止まっていない」というのは、慣れていないと気づきにくいところでした😅 IaC を使っていても、手で作ったものは別管理になる——という当たり前を、課金で痛感した一件です。同じく「消したつもり」の人の確認のきっかけになれば嬉しいです🙌

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?