Upgrade to Pro — share decks privately, control downloads, hide ads and more …

2026-11-11 Tamachi.sre#7 PaCにインフラリソースの命を救われました。...

2026-11-11 Tamachi.sre#7 PaCにインフラリソースの命を救われました。 / PaC saves the infra resource life

[Tamachi.sre#7 - connpass](https://tamachi-sre.connpass.com/event/408227/) で話す内容

TerraformでPolicy as Codeを入れてインフラの命を救った話。

Avatar for SUZUKI Masashi

SUZUKI Masashi

November 11, 2026

More Decks by SUZUKI Masashi

Other Decks in Technology

Transcript

  1. おまえだれよ • • • すずきまさし/masasuzu/@masasuz 株式会社スリーシェイクSreake事業部シニアアーキテクト クラウドインフラなんでも屋さんをしてます ◦ お客様の外部から ▪

    設計、運用、構築等の技術支援を行います。 ◦ お客様の内部から ▪ インフラチームの一員として内製化支援も行います。 • 得意領域 ◦ AWS ▪ AWS Community Builder Cloud Operation Since 2024~2026 ▪ 2026 Japan All AWS Certifications Engineers ◦ Google Cloud ▪ Google Cloud Partner Top Engineer 2026 ◦ Terraform Copyright © 3-shake, Inc. All Rights Reserved. 3
  2. この 1 行見えていましたか ? ... (ここまでに おびただしいリソースの update や create

    が続く) # google_secret_manager_secret.api_key must be replaced -/+ resource "google_secret_manager_secret" "api_key" { ~ create_time = "2026-01-01T00:00:00Z" -> (known after apply) ~ effective_annotations = {} -> (known after apply) + expire_time = (known after apply) ~ id = "projects/my-project/secrets/api-key" -> (known after apply) ~ name = "projects/123456789012/secrets/api-key" -> (known after apply) # (7 unchanged attributes hidden) ~ replication { - auto { # forces replacement } + user_managed { # forces replacement + replicas { # forces replacement + location = "asia-northeast1" # forces replacement } } } } ... (この先も おびただしいリソースの update や create が続く) Plan: 3 to add, 42 to change, 1 to destroy. • • # forces replacement は消してから作り直しのしるし。 何百行も変更があると見逃しがち。 ◦ 見逃すことで意図しないリソース削除を招き大事故に。 Copyright © 3-shake, Inc. All Rights Reserved. 8
  3. どんなに気をつけても人間は信頼できない • • • 大量の結果があると見逃すことは起きがち ◦ 特にAI駆動で大量の変更を行ってる現場は目が滑りがち ◦ 熟練のエンジニアの目 grepも疲労と老化には勝てない

    1 to destroy を拾えば良いという話もあるが、正規に複数リソースを削除したいときに紛れ込む可能性 人が気をつけることには限界があるので、仕組みでふせぎたい ◦ AIは非決定論なので見逃すことはありうるので、決定論的に防ぎたい Copyright © 3-shake, Inc. All Rights Reserved. 9
  4. Terraform側で削除を防ぐ仕組みはないの • • lifecycle.prevent_destroy ◦ plan時にreplaceがあるとき止まる。 ◦ ただし、リテラルしか書けず、環境ごとに変えられない。 ▪ devなど特定環境だけ作り直しを許容したいとき困る

    ◦ resourceやmoduleを丸ごと消したときは止められない ◦ つけ忘れたら遠慮なく消される providerのdelete_protection ◦ planは通過して、applyで落ちる ◦ applyする前に早期に気づきたい ◦ これもつけ忘れたら遠慮なく消される Copyright © 3-shake, Inc. All Rights Reserved. 10
  5. 静的解析ツールでどうにかできない? • • TFLint ◦ 書き方・命名の規約、provider 固有の誤り検出 Trivy(trivy config、旧tfsec)、Chekov ◦

    セキュリティ周りの設定ミス (暗号化なし、公開設定など) • • • 静的解析ツールはどう設定されているかを見るもの 消えるかどうかはtfstate (今あるもの) と設定 (あるべき姿) の差分で決まります Trivy と Checkov は plan JSON も読めますが、目的は設定ミスの検出 • インフラの信頼性を高めるツールではあるが、目的には沿わない Copyright © 3-shake, Inc. All Rights Reserved. 13
  6. OPA(Open Policy Agent) • OPA・Rego・conftest の関係 ◦ OPA(Open Policy Agent):

    ポリシーエンジン ◦ Rego: ポリシー記述言語 ◦ conftest: ポリシー検査用 CLIツール Copyright © 3-shake, Inc. All Rights Reserved. 16
  7. 実行例 terraform init terraform plan -out=tfplan # plan file出力 terraform

    show -json tfplan > tfplan.json # plan fileをjsonに変換 conftest test --policy policy tfplan.json # policy ディレクトリに定義されたポリシーを検証 Copyright © 3-shake, Inc. All Rights Reserved. 18
  8. 余談: Terraform Policy • • • 最近リリースされました。 Terraform 1.17.0 ◦

    Introducing tfpolicy: A declarative policy workflow built for Terraform HCP Terraform前提なので残念ながらどこでも使えない HashicorpはSentinelというPolicyフレームワークもあったはずですが、どういう棲み分けになるのか Copyright © 3-shake, Inc. All Rights Reserved. 19
  9. plan fileの例 { } "format_version": "1.2", "terraform_version": "1.16.5", "resource_changes": [

    { "address": "google_secret_manager_secret.api_key", "type": "google_secret_manager_secret", "change": { "actions": ["delete", "create"], "before": { "secret_id": "api-key", "replication": [{ "auto": [{ ... }], "user_managed": [] }], ... }, "after": { "secret_id": "api-key", "replication": [{ "auto": [], "user_managed": [{ ... }] }], ... }, "replace_paths": [["replication", 0, "auto"], ["replication", 0, "user_managed"], ...] }, "action_reason": "replace_because_cannot_update" } ], "prior_state": { ... }, "configuration": { ... }, "planned_values": { ... }, ... 見るところは resource_changes[].change ここに変更予定の情報がある Copyright © 3-shake, Inc. All Rights Reserved. 21
  10. PaCでどの条件を拾えばいいか plan表示 plan JSON (resource_changes[].change.actions) will be destroyed ["delete"] -/+

    destroy and then create replacement ["delete", "create"] +/- create replacement and then destroy ["create", "delete"] plan のJSONのresource_changes[].change.actionsに”delete” が含まれているものをチェックできると良さそ う。 Copyright © 3-shake, Inc. All Rights Reserved. 22
  11. Regoをどう書くか package destroy import rego.v1 protected_envs := {"stg", "prd"} protected_types

    := { "google_sql_database_instance", "google_storage_bucket", "google_artifact_registry_repository", "google_service_account", "google_cloud_run_v2_job", "google_secret_manager_secret", } deny contains msg if { data.env in protected_envs some rc in input.resource_changes "delete" in rc.change.actions # 削除と 2 種類の replace rc.type in protected_types not excepted(rc.address) # exceptions.yaml と照合。例外をここに定義する。 msg := sprintf("[DESTROY-001] %s を削除 / 置き換えしようとしています", [rc.address]) } 雰囲気を感じてください。 Copyright © 3-shake, Inc. All Rights Reserved. 23
  12. まとめ • • • • • • planを目grepするのには限界がある。見逃す。 Terraform側で削除保護はできるが、限界はある。 リソース削除どうかは

    Terraformのファイルに書かれていないので、静的解析ツールでは拾えない。 PaC(conftest)でdeleteを拾うことで削除してはいけないリソースを拾うことができる CIに組み込むことで意図しないリソース削除を CDに持ち込まないようにできる とはいえ、PaCでも保護対象にいれていないリソースは漏れうるので多層的に対処することが大事 Copyright © 3-shake, Inc. All Rights Reserved. 28