Google Cloud上で新しいインフラを設計・開発していると、つい色々なリソースを試したくなるものです。その結果、プロジェクト内は雑然とし、放置されたリソースが動き続けることでコストもかさんでいきます。
手作業で削除することもできますが、Compute、Containers、AppEngine、Cloud SQLなど、GCPの数多くのサービスを横断してリソースを洗い出すのは簡単ではありません。
そこで、この作業を手軽に、そして安全に行えるオープンソースツールSafe Scrubを開発しました。

何よりもまず安全性
Safe Scrubは安全性を最優先に設計されています。
Safe Scrubはリソースを直接削除することはありません。あくまで、削除のためのスクリプトを生成するツールです。
中身の見える削除スクリプト
生成される削除スクリプトは中身が一目瞭然です。gcloud delete文が並んでいるだけなので、どのリソースに何が行われるかをすぐに把握できます。スクリプトを生成したら、まず一行ずつ確認して削除対象を正確に把握し、納得した上で実行してください。
これが最も重要な安全機能ですが、ほかにも工夫があります。
アカウントとプロジェクトの明示的な指定
Safe Scrubでは、ログイン中のユーザーアカウントではなく、サービスアカウントの認証情報を含むJSONキーファイルを使用します。これは、ロールの選択を意識的に行わせるための仕組みです。スクリプト生成処理に書き込み権限は不要なため、サービスアカウントにはProject Viewerなど、書き込み権限を持たないロールを割り当ててください。
さらに、特定のリソースタイプだけを一覧化したい場合は、より制限の強いロールを設定しても構いません。権限不足によるエラーが発生しても問題はありません。ロールが厳しすぎる場合(あるいはGCP APIがまだ有効化されていない場合)でも、Safe Scrubは利用できないリソースを一覧化できないだけで、処理自体は問題なく続行します。エラーメッセージを表示し、そのまま処理を進めます。
gcloud本体とは異なり、Safe Scrubはプロジェクトを明示的に指定するよう要求します。これは、デフォルトプロジェクトが使われてしまい、削除対象に含めるつもりのなかったリソースが誤って一覧化されるのを防ぐためです。生成される削除スクリプトでも、すべての削除コマンドにプロジェクトが明示されるため、現在のデフォルトプロジェクトに対して誤って削除が実行されることはありません。
フィルタリング
Safe Scrubは2種類のフィルタリングに対応しています。
1つ目は、コマンドラインオプションで対象リソースを絞り込む方法です。gcloudのフィルタリング機能をフル活用して、ラベル、名前、作成日など、さまざまな条件で絞り込めます。(gcloudではなくgsutilを使うCloud Storageバケットについては、単一キーのラベル等価フィルタ(key=value1)のみが有効で、それ以外のフィルタは無視されます。)
2つ目は、exclusions.txtによる削除除外リストです。URIにここで指定した文字列を含むリソースは、削除スクリプトに含まれません。使い方としては、まずSafe Scrubを実行し、今後も残しておきたい項目を見つけたら、そのURIまたはURIの一部をexclusions.txtに追加します。(Cloud Functionsについては、gcloudのバグのため、URIではなく名前を使用します。)
たとえば、次のような行が記述されている場合:
networks/default firewalls/default
デフォルトネットワークと、デフォルトファイアウォール(URIはhttps://www.googleapis.com/compute/v1/projects/my-project/global/firewalls/default-allow-httpsのような形式)は削除対象から外れます。
削除プロセスのモニタリング
削除スクリプトを初めて実行する際は、進行状況をしっかり見届けたいものです。Safe Scrubは削除スクリプトの先頭にset -xを付加するため、デバッグ出力を確認できます。
削除中の追跡をしやすくするため、Safe Scrubは通常の逐次実行スクリプトを生成します。一方、-bスイッチを使えばバックグラウンド(非同期)コマンドを生成することも可能で、複数リソースの削除を並列で進められます。処理は速くなりますが、追跡は難しくなり、同時呼び出しが多すぎてシステムに負荷がかかるリスクもあります。
次のステップ:レビューと実行
最初のステップで得られるのは削除スクリプトだけです。次に、その内容を確認し、残しておきたいリソースに該当する行を削除します。あわせて、今後のフィルタリング用にexclusions.txtへ項目を追記しておくのもよいでしょう。
実際にリソースを削除する
削除の準備が整ったら、Project Editorなど該当する書き込み権限を持つアカウントで削除スクリプトを実行します。
危険モード
クラウドの自動化は便利ですが、大量削除を伴う場面では特に慎重になり、すべてのステップを手動で確認すべきです。とはいえ、開発・QAプロジェクトであれば、Safe Scrubの設定を十分に煮詰めた段階で、削除スクリプトの生成と実行を一気通貫で自動化しても安心、というレベルに達するかもしれません。その場合は、dangerous-usage-example.shに示されているとおり、出力をbashにパイプするだけで実行できます。この場合、サービスアカウントにはProject Editorのような読み書き両方の権限が必要です。
ユースケース
開発・QA環境と本番環境
Safe Scrubは、一日の終わりや新しいテスト実行の前にまっさらな状態から始めたい開発・QAプロジェクトを想定しています。本番プロジェクトでは、削除前にコンポーネント間の依存関係を見極める必要があるため、本ツールはあまり適していません。
依存関係によるブロックの解消
不要な依存関係が他リソースの削除を妨げているケースでも役立ちます。たとえば、ロードバランサーで実際には使われていないバックエンドであっても、それが指しているGoogle Kubernetes Engineクラスタは削除できません。Safe Scrubで全リソースの削除コマンドを生成し、その中からバックエンドを削除するコマンドを選んで実行すれば、クラスタのロックを解除できます。
現在の対応範囲と今後の展望
対応・非対応サービス
Google Cloudには90以上の製品がありますが、Safe Scrubはそのすべてをカバーしているわけではありません。一般的な開発・QAでセットアップと破棄が繰り返される、重要かつよく使われるサービスに焦点を絞っています。具体的には、GCE、PubSub、App Engine、Cloud SQL、Cloud Storage、Functions、GKEのリソースタイプに対応しています。一方、Composer、Data Catalog、Data Procなど、未対応のサービスも多数あります。対応・非対応サービスの全リストは使用方法のテキストに記載されています(./generate-deletion-script.shを実行してください)。
対応・非対応リソースタイプ
各サービスのリソースタイプすべてに対応しているわけではありませんが、重要なものは押さえているつもりです。特に、削除リスクが非常に高いリソースタイプは意図的に対象から外しています。たとえばApp Engineでは、サービス、バージョン、インスタンス、ファイアウォールルールには対応していますが、SSL証明書には対応していません。対応APIやリソースタイプの追加をご希望の場合は、GitHubでpull requestを送るか、issueを起票してください。
今後の実装の可能性
将来のSafe Scrubでは、すべてのリソースを網羅的に取得するためにgcloud resources listコマンド(2020年6月時点でアルファ版)の利用を検討するかもしれません。ただし、この方向に進むかは未確定です。リソースの中には削除に向かないもの(IAM、Secrets、SSL証明書など、重要なものを誤って削除しかねないもの)もあります。また、リソースタイプによって削除コマンドが異なる場合もあります(たとえばCloud Storageにはgcloudではなくgsutilを使用し、BigQueryにはbqを使用する予定です)。
はじめ方
オープンソースのSafe Scrubはこちらからダウンロードできます。
解凍後、./generate-deletion-script.shを実行すると使用方法が表示されます。usage-example.shファイルにサンプルが用意されています。
最もシンプルなクイックスタート手順は次のとおりです。
- Project Viewerロールを持つサービスアカウントのキーをダウンロードし、Safe Scriptディレクトリに
project-viewer-credentials.jsonという名前で保存します。 - 続いて、
./generate-deletion-script.sh -p <YOUR_PROJECT_NAME>を実行します。