何が起きたか
検証目的でGKEクラスタをデプロイし、ingressでいくつかのサービスを公開したのち、マニフェストを削除せずにクラスタを削除した。その結果、ネットワーク関係のリソースがあちこちに残ってしまい、VPCとサブネットを削除できなくなった
どう起こしたか
GKEおよびネットワークリソースをterraformで作成していた。その後、GKEクラスタ上にingressやgatewayリソース、およびdeploymentやserviceリソースをデプロイした。このとき、GKEのingressコントローラなどによってGoogleCloud上にロードバランサなどのネットワークリソースが作成された。
本来なら用済みになったリソースを削除するとき、まずGKEクラスタ上のリソースを削除することで、コントローラが削除したGoogleCloudのリソースを削除し、その後terraformでネットワークやGKEクラスタを削除する必要があった。しかしこの手順を失念し、いきなりterraformからGKEクラスタとVPCを削除しようとした。
その結果、まずGKEクラスタが削除され、その後VPCを削除する段でエラーが発生した。
google_compute_network.my_network: Destroying... [id=projects/project/global/networks/my-network]
google_compute_network.my_network: Still destroying... [id=projects/project/global/networks/my-network, 10s elapsed]
╷
│ Error: Error waiting for Deleting Network: The network resource 'projects/project/global/networks/my-network' is already being used by 'projects/project/global/firewalls/gkegw1-wlur-l7-my-network-global'
│
GKEクラスタが削除された際にクラスタ上のリソースも削除されたが、コントローラごと一度に削除されたため、本来実行されるべきコントローラが作成したリソースの削除が行われなかった。結果として、ロードバランサやファイアウォールルールなどのネットワークリソースが残ったままとなり、terraformがVPCを削除できなくなってしまった。
どう解決したか
関連するネットワークリソースを一つ一つ手動で削除した。削除したリソースは以下のとおり。
- ファイアウォールルール
- ロードバランサ
- ロードバランサのバックエンド
- ネットワークエンドポイントグループ
今この記事では列挙できているが、実際のところ一つ消してはterraform destroy
を実行し、VPCを使用中のリソースを確認しては削除し、という手順を踏んだので非常に面倒だった。
どうするべきだったか
そもそもGKEクラスタを削除する前に、クラスタ上のリソースを全て削除しておけばよかった。本来コントローラが作成したリソースだから、コントローラに削除させればこの面倒はなかった。
また、リソースのタグ付けを行うことも有効だと感じた。実際のところファイアウォールルールなどは全てのリソースが列挙される上に、リソース名からGKEクラスタ名を手繰ることができない。特にロードバランサは完全にランダムな文字列で名付けられている。このため、どのリソースを削除するべきかの判断に困った。どのリソースが何の作業で作成したものか、タグ付けをしていればフィルタリングが容易だったと思う。