インフラの「死」を設計せよ:Terraformで構築するTTL付きサンドボックスの完全自律廃棄アーキテクチャ
「検証環境」という名の墓場が、貴殿のクラウド環境に溢れてはいないか?
多くの企業で、検証用のインスタンスやRDSが一度作成されたまま忘れ去られ、月々のAWS請求書を肥大化させる「ゾンビ・リソース」と化している。
SREの真髄は「構築」ではなく「ライフサイクル管理」にある。特に、使い捨てのサンドボックスにおいて、「構築」と「廃棄」を対等な権利として設計できていないエンジニアは、インフラを管理しているのではなく、ただのゴミ拾いをしているに過ぎない。
本稿では、Terraformによるインフラ定義にTTL(Time-to-Live)の概念を注入し、ガベージコレクションを自律化させる「究極のクリーンアップ・パターン」を伝授する。
—
1. 概念設計:なぜTerraform単体で完結させてはいけないのか
Terraformは「State」を保持するツールであり、`terraform destroy` を実行するトリガーではない。無理に `local-exec` や `null_resource` で破棄ロジックを詰め込むのはアンチパターンだ。Stateの整合性が崩壊した際、環境が「消せもしない、更新もできない」状態に陥るリスクがある。
解法:
1. タグによるメタデータ管理: 全リソースに `TTL` (UNIX Epoch) を付与する。
2. イベント駆動の非同期掃除: Terraformから独立した「掃除屋(Janitor)」をLambdaとして配備し、EventBridgeで定時実行する。
これにより、Terraformの責務を「インフラ定義」に純化させ、ライフサイクル管理を「イベント駆動アーキテクチャ」に委譲する。
—
2. 実装:TTLタグを強制するTerraformモジュール
まずは、サンドボックス環境の全リソースにTTLを強制注入する仕組みを作る。
variable.tf
variable “ttl_hours” {
description = “環境の生存時間(デフォルト24時間)”
type = number
default = 24
}
locals.tf
locals {
# 現在時刻 + TTLから破棄予定時刻を計算
expiry_timestamp = timeadd(timestamp(), “${var.ttl_hours}h”)
default_tags = {
ManagedBy = “Terraform”
Environment = “Sandbox”
TTL = formatdate(“YYYY-MM-DD-hh”, local.expiry_timestamp)
}
}
provider.tf
provider “aws” {
default_tags {
tags = local.default_tags
}
}
この実装の肝は、`default_tags` を活用することだ。これにより、モジュール内のリソース一つ一つにタグを記述する手間を排除し、強制的にTTLを付与する。「人間が忘れても、コードが忘れない」状態を担保する。
—
3. 掃除屋(Janitor)のアーキテクチャ:EventBridge + Lambda
次に、このタグを監視し、`TTL` が現在時刻を過ぎたリソースを抹殺するLambdaを構築する。これをGolangで書くのがパフォーマンス上の最適解だ。Pythonよりも起動速度とメモリ消費効率で勝る。
// Janitorのコアロジック(抜粋)
func handler(ctx context.Context) error {
now := time.Now()
// 1. タグフィルタリングでTTLが切れたリソースを検索
// 2. 依存関係(Dependency Graph)を考慮した削除順序の制御
// – 注意: TerraformのStateを無視してAPI経由で消すため、
// リソースの削除順序(例: SecurityGroupより前にEC2)を
// 慎重に制御する必要がある。
return nil
}
高度なハック:削除順序の解決
単純なAPI削除(`TerminateInstances`等)は、依存関係がある場合にエラーを吐く。この問題を解決するため、我々は「優先度付きキュー」を用いる。
1. フェーズ1: コンピュートリソース(EC2, ECS Tasks)の削除
2. フェーズ2: ネットワークインターフェース(ENI)の切断
3. フェーズ3: DBやストレージのSnapshot取得(任意)と削除
4. フェーズ4: 最後に残ったSecurity GroupやIAM Roleのクリーンアップ
この順序を担保した「Janitor Lambda」を、EventBridgeで毎時実行する。
—
4. 運用の極意:Stateの「腐敗」を防ぐ
この自動削除環境において唯一の懸念点は、「Terraform Stateとの不整合」だ。自動削除された後のリソースをTerraformで `plan` すると、Terraformは「リソースが消失した」と検知してエラーを吐くか、再作成を試みる。
解決策:
`terraform state rm` を自動化するワークフローをパイプラインに組み込む。
Lambdaがリソースを削除した際、同時にDynamoDB等に「削除済みイベント」を記録し、CI/CDパイプライン側で `terraform refresh` を掛ける前に、Stateから当該リソースを除去するスクリプトを走らせるのだ。
クリーンアップ後のState整合性維持フロー
aws dynamodb scan –table-name SandboxCleanupEvent | jq -r ‘.Items[].ResourceId.S’ | xargs -I {} terraform state rm {}
—
5. 伝説のエンジニアからの提言
自動クリーンアップは単なるコスト削減ではない。それは「常にクリーンな状態からやり直せる」という、エンジニアにとって最強の精神的安定剤である。
- 冪等性を疑え: コードが冪等であることは前提条件。しかし、環境が汚染されていれば、その前提は崩れる。
- 観測可能性: どのリソースがいつ、なぜ消されたのか。CloudWatch Logsに全ての削除ログを構造化データ(JSON)として出力せよ。
- 例外管理: 本番環境への誤爆を避けるため、タグの `Environment` キーが `Sandbox` 以外であれば、いかなる理由があろうとも削除処理をブロックする「ガードレール・ロジック」をLambdaにハードコーディングせよ。
インフラは「育てるもの」ではなく、常に「再構築可能な消耗品」であるべきだ。この哲学を貫いた先にあるのは、障害を恐れず、何度でもゼロから環境を立ち上げられる、圧倒的な開発スピードだ。
さあ、貴殿の環境からゾンビを排除し、真に自動化されたクラウドの深淵へ踏み込め。