ビルド成果物の削除設計 — 何をいつ消すか、どこまで手元に置くかの判断

ビルド成果物の削除設計で行き詰まるチームに共通するのは、消してよいものと消してはいけないものの境界線が事前に設計されていない点にある。保持期限・削除判断軸・アーカイブ基準を構築段階から設計に組み込むことで、誤削除とストレージ肥大を同時に防げる。本記事では、リポジトリ種別ごとの期限設計から、自動クリーンアップの確認ステップ設計、よくある設計ミスの落とし穴まで整理する。

成果物の保持期限をリポジトリの種類ごとに設定すべき理由

アーティファクトの種類が混在すると期限設計が破綻する

コンテナイメージ、Helmチャート、バイナリパッケージ、テストカバレッジレポートを同一ルールで管理しようとすると、用途・参照頻度・ロールバック要件の違いから「どれを消しても問題ないか」の判断が常に曖昧になる。手動削除を躊躇したまま放置するチームは多く、ストレージが数ヶ月で数十GBを超えるケースが現場では珍しくない。種類ごとに期限を分けることが設計の出発点になる。

リポジトリの特性から保持期限を逆算する

コンテナイメージレジストリは、本番デプロイ頻度と直近何世代までロールバックを許容するかで保持期限が決まる。週1回リリースのシステムなら直近4〜6世代(約1〜1.5ヶ月分)を保持することが判断基準の目安になる。バイナリパッケージのリポジトリは依存ビルドキャッシュとしての役割が大きく、主要バージョンは6ヶ月〜1年単位で残しつつ中間ビルドは2週間程度で削除する二段構えが適切なことが多い。テストレポートはデプロイ物でないため、90日を上限とした自動削除で問題になることは少ない。

保持期限を統一しようとするリスク

10環境以上を抱えるプロジェクトで「全成果物を30日保持」とルールを統一したあと、本番インシデントで60日前のバージョンへのロールバックが必要になった事例が現場では報告されている。統一ルールはオペレーションをシンプルにする反面、例外への対応力を削ぐ。リポジトリ種別ごとに「通常保持」と「長期保持フラグ」の二段階を設けることで、例外処理をルールの外に追い出せる。

タグ付きイメージと未タグのビルドキャッシュの削除判断軸比較

タグなしイメージが際限なく蓄積する仕組み

コンテナイメージに新しいタグを付与してプッシュすると、旧イメージのタグは外れてもダイジェストはレジストリに残り続ける。CI/CDパイプラインが1日10回ビルドを実行する環境では、1ヶ月で300枚前後のタグなしイメージが積み上がる計算になる。これらは参照されることがないにもかかわらず削除対象として認識されにくく、気づいたときにはレジストリストレージが数百GBを圧迫していることがある。

比較表でみる削除判断軸の違い

成果物の種類 削除判断の主軸 推奨保持期間の目安 削除前の確認ポイント
タグ付きコンテナイメージ(本番) デプロイ済み世代数とロールバック要件 直近4〜8世代または90日 現在デプロイ中のダイジェストと一致していないか
タグなしイメージ(untagged) 最終プッシュからの経過時間 7〜14日 実行中コンテナが参照していないか
ビルドキャッシュレイヤー 使用頻度とビルド時間への影響 30日(未使用) 削除後にビルド時間が急増しないか
Helmチャートアーカイブ 対応するアプリバージョンの本番稼働状況 アプリ廃止後90日 依存するリリースが存在しないか
テスト・カバレッジレポート 監査要件・障害時の証跡保持期間 60〜90日 コンプライアンス保持要件に引っかからないか

ビルドキャッシュをどこで管理するかが判断を左右する

ビルドキャッシュをレジストリに保存するか、CI/CDランナーのローカルボリュームに置くかで、削除の主体と手順が大きく変わる。レジストリ側に保存すれば一元管理できる反面、キャッシュの削除ポリシーが本番イメージと混在しやすい。5台以上のランナーを運用する環境では、キャッシュ専用のストレージを分離して削除ポリシーを独立させる設計が、後の混乱を防ぐ判断として有効に機能する。

本番デプロイ済みのバージョンをいつまで保持するかの設計

直近Nバージョンを手元に置くルールの設計

「直近N世代を保持する」というルールは単純に見えるが、Nの値をどう決めるかが設計の核心になる。ロールバックが業務上許容される最大回数から逆算することが出発点で、週1リリースで「最悪3世代前まで戻せること」を要件とするなら直近4世代の保持が必要になる。リリース頻度が上がるほど世代数管理はストレージを圧迫しやすいため、世代数と日数の両方を条件に設定し、どちらか早い方で削除するアプローチが現場では広く取られている。

リリースサイクルと保持期間を連動させる

デプロイ頻度が高いサービスほど成果物の蓄積スピードも速くなる。1日3回デプロイを行うサービスで30日分を保持すると、単純計算で90バージョン分のイメージが手元に残る。この規模になるとストレージコストだけでなく、削除対象の特定にかかる計算コストも無視できなくなる。リリースサイクルが月次から週次へと短縮された段階で、保持ルールも同時に見直す設計レビューを挟む習慣が障害の温床になりにくい。

ロールバック用のバージョンを別枠で扱う

通常の保持ルールとは別に「ロールバック専用の保持枠」を設ける設計がある。通常ルールで削除対象になったバージョンでも、ロールバック候補として明示的にフラグを立てたものは別ポリシーで保持する仕組みだ。フラグをデプロイ時に自動付与し、新バージョンが本番で安定稼働する期間(例として2週間)を過ぎたら自動的にフラグが解除される設計にすると、別枠の管理負荷を最小限に抑えられる。

削除とアーカイブのどちらで扱うかの判断基準

監査・コンプライアンス要件が判断を分ける

削除とアーカイブの選択で迷う場面の多くは「本当に消してよいか」という確信が持てないときに起きる。その確信を与えるのが監査要件とコンプライアンス要件だ。金融・医療・官公庁向けシステムでは、ビルド成果物の保持義務が5年以上になることもある。こうした要件がある場合は削除がそもそも選択肢から外れるため、要件定義の段階で確認し、設計に織り込んでおく必要がある。

アーカイブ先の設計とコスト特性

アーカイブ先としてよく使われるのはオブジェクトストレージのコールドティアだ。保存コストを大幅に抑えられるが、取り出し時の料金とレイテンシが高くなる特性がある。アーカイブ後のリストア頻度が年に数回以下と見込まれるなら、コールドティアへの移行はコスト面で合理的な設計になりやすい。月に数回以上のアクセスが見込まれる場合は、アーカイブティアへの移行がかえってコストを押し上げることがある。

削除かアーカイブかを判断するチェックリスト

  • コンプライアンス・監査要件で保持期間が明示されているか(Yes → アーカイブ対象)
  • ロールバックやインシデント調査で参照する可能性が3ヶ月以上あるか(Yes → アーカイブ対象)
  • 同等のビルドがソースコードとビルドスクリプトから再現可能か(Yes → 削除可)
  • アーカイブ先のリストアコストが継続保持コストを下回るか(Yes → アーカイブ移行)
  • 削除後に依存する他の成果物やデプロイリリースが存在しないか(No → 削除不可)

自動クリーンアップのスクリプト設計 — 削除前の確認をどこに挟むか

dry-runフェーズを設計に組み込む

自動クリーンアップスクリプトで重要な設計判断の一つが、dry-runを必須フェーズとして組み込むかどうかだ。本番運用ではdry-runをデフォルト動作にし、削除を実行するフラグを明示的に指定しない限り削除処理が走らない設計が安全側に倒れている。dry-runの結果を通知チャンネルに投稿し、担当者が確認してから本番削除を走らせる運用フローは、複数の環境を横断する削除作業で特に有効に機能する。

削除前の通知・承認のステップ設計

削除スクリプトに「通知→承認→実行」のステップを組み込む設計は、誤削除の防止と組織内のコミュニケーションコスト削減を両立する。削除対象リストをチャットツールに投稿し、担当者の承認リアクションを受けてから削除コマンドが実行される設計パターンが広く使われている。承認待ちのタイムアウト設定も設計に含める必要があり、24時間以内に承認がなければ削除を延期する設定が多い。延期が繰り返されてクリーンアップが形骸化するリスクがあるため、延期回数の上限も設計段階で決めておくことが重要だ。

自動化の判断境界 — 何を人間に委ねるか

自動クリーンアップで完全自動化してよい対象と、人間の確認を必須とすべき対象を設計段階で分けておく必要がある。完全自動化に向くのは「タグなしイメージの7日超過分」「テストレポートの90日超過分」など、誤削除リスクが低く影響範囲が限定的なものだ。本番デプロイ済みイメージや長期保持フラグ付きの成果物については、人間の承認なしに自動削除しない設計が原則になる。この境界を設計書に明文化しておかないと、スクリプトが改修されるたびに自動化の意図が失われていく。

ストレージコストの増加に気づくための監視設計

アラートのしきい値設定

ストレージ増加への気づきを遅らせる主な原因は、しきい値が「容量の絶対値」でしか設定されていない点にある。絶対値によるアラートは、気づいたときにはすでに上限の90%を超えているケースが多い。前日比や前週比の増加率でアラートを設定すると、異常な積み上がりを早期に検知できる。「前日比で15%以上増加した場合にアラート」という設定にすると、CI/CDパイプラインの設定ミスで大量のキャッシュが生成され始めたタイミングを数日以内に検知しやすくなる。

ストレージ増加の傾向監視

アラートだけでなく、増加傾向を可視化するダッシュボードを設計に含めることで、削除ルールの再設計タイミングを適切に判断できるようになる。リポジトリ種別ごとのストレージ使用量を時系列で並べ、削除ジョブの実行タイミングも重ねて表示する構成が理想的だ。削除ジョブ実行後も使用量がほとんど減らない場合は、削除ルールが実態に合っていないシグナルとして捉え、保持期限や対象範囲の見直し検討につなげられる。

コスト監視を設計判断にフィードバックする

ストレージ監視の情報が削除設計の判断にフィードバックされる仕組みが整っているチームは少ない。多くの場合、監視は「上限を超えないか見る」受動的な用途にとどまっている。月次でストレージ使用量のレポートを削除ルールのレビューと組み合わせる設計にすると、「直近3ヶ月でHelmチャートが全体の40%を占めるようになった」といった傾向の変化を設計判断にフィードバックしやすくなる。このサイクルがない環境では、削除ルールが構築当初のまま放置され、実態と乖離し続ける。

落とし穴 — 誤削除とロールバック不能を防ぐ保持ルールの設計ミス

保持ルールの設計ミスが生む典型的な障害

現場でよく聞かれる設計ミスの典型は「世代数ルールと日数ルールを別々に設定し、どちらが優先するかを明文化しなかった」ケースだ。直近5世代を保持するルールと30日以内を保持するルールが共存した場合、実装によっては5世代以内でも30日超のものが削除されたり、逆に30日以内であれば6世代目以降も残り続けたりする。どちらが優先かが設計書に書かれていないと、スクリプトの実装担当者の解釈によって動作が変わり、意図しない削除の温床になる。

削除フラグとロック機構の設計

成果物に「削除禁止ロック」を付与できる仕組みを持たないレジストリでは、削除スクリプトが特定バージョンをスキップするロジックをスクリプト側に持たせるしかない。この方式は、スクリプトが改修されるたびにロック対象リストが失われるリスクを持つ。ロック情報をリポジトリ外部のKVストアやラベルとして管理し、スクリプトが削除前に参照する設計にすると、スクリプトのリファクタリングをまたいでロック設定を維持しやすくなる。本番稼働中のイメージに対して少なくとも1つのロック機構を持つことが、ロールバック不能を防ぐ最低限の設計要件といえる。

設計ミスを事前に防ぐチェックリスト

  • 保持ルールに「世代数」と「日数」が混在する場合、優先順位が設計書に明文化されているか
  • 現在本番にデプロイ中の成果物が削除対象に含まれないことをdry-runで確認しているか
  • ロールバック候補に指定した成果物が通常の保持ルールから除外されているか
  • 削除スクリプトを改修した際に、ロック・スキップ対象リストが引き継がれているか
  • コンプライアンス保持要件のある成果物がアーカイブポリシーの対象になっているか
  • 自動削除の実行ログが残っており、誤削除を事後追跡できる状態になっているか
  • ストレージアラートのしきい値が絶対値だけでなく増加率でも設定されているか

▶ 手を動かして本番まで到達する

脱属人化の第一歩は「読める・書けるスクリプト」から始まります

ここまでの設計判断は、読めば腹に落ちます。ですが「自分の手で本番まで通しきる自信」は、それとは別の話になります。

自動化の設計を、手を動かして身につける2日間です。手順書に閉じ込めた構築を、他人が読めて再現できる形へ変えていきます。

成果物の削除スクリプトを設計するシェルスクリプト実践コースへ →

シェルスクリプトマスターセミナー|自動化の設計を手で身につける2日間