Skip to content

Latest commit

Β 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

☁️ Google Cloud Chronicle Retrohunt Terraform Module

Provisions a Google SecOps (Chronicle) retrohunt, targeting hashicorp/google ~> 7.0.

Terraform Provider Module Type Resources Posture


🧩 Overview

  • Creates exactly one google_chronicle_retrohunt resource β€” a one-time execution of a terraform-google-chronicle-rule over a specified past time range.
  • rule takes the SHORT rule ID, identical reference pattern to terraform-google-chronicle-rule-deployment's own rule argument β€” confirmed via the resource's own live doc example.
  • This resource is effectively create-only β€” its own timeouts block confirms only create/delete are supported, no update.
  • A documented discrepancy: the resource's own prose docs mention a deletion_policy argument, but the live schema-JSON (ground truth) confirms it does not exist on this resource at this provider version.

πŸ’‘ Why it matters: Retrohunts let a SOC validate a new or changed detection rule against historical data before trusting it against live traffic β€” modeling the retrohunt request as code keeps that validation step reviewable and repeatable.


❀️ Support this project

If these Terraform modules have been helpful to you or your organization, I'd appreciate your support in any of the following ways:

Whether it's a star, a professional connection, or a coffee, every gesture helps keep these modules actively maintained and continually improving. Thank you for being part of the community!


πŸ—ΊοΈ Where this fits

flowchart LR
 RULE["terraform-google-chronicle-rule<br/>(same batch, required)"]:::keystone
 THIS["terraform-google-chronicle-retrohunt<br/>(this module β€” standalone)"]:::thismodule

 RULE -.->|"basename(name) -> rule"| THIS

 classDef thismodule fill:#4285F4,color:#FFFFFF,stroke:#174EA6,stroke-width:1px;
 classDef keystone fill:#174EA6,color:#FFFFFF,stroke:#174EA6,stroke-width:1px;
Loading

Validated via the Mermaid Chart MCP (valid: true).


🧬 What this builds

flowchart TB
 subgraph Inputs
 RULEV["var.rule"]
 PI["var.process_interval<br/>(start_time / end_time)"]
 RID["var.retrohunt_id"]
 end

 KEYSTONE["google_chronicle_retrohunt.this"]:::keystone

 subgraph Outputs
 ID["id / name"]
 STATE["state / progress_percentage"]
 EI["execution_interval"]
 end

 RULEV --> KEYSTONE
 PI --> KEYSTONE
 RID --> KEYSTONE

 KEYSTONE --> ID
 KEYSTONE --> STATE
 KEYSTONE --> EI

 classDef keystone fill:#174EA6,color:#FFFFFF,stroke:#174EA6,stroke-width:1px;
Loading

Validated via the Mermaid Chart MCP (valid: true).

Resource inventory: google_chronicle_retrohunt.this (1 resource).


βœ… Provider / Versions

Component Requirement
Terraform >= 1.12.0
hashicorp/google ~> 7.0 (resolved v7.39.0 during authoring)
Provider block None β€” the caller configures google

Schema notes that bite:

  • rule wants the SHORT rule ID β€” confirmed via the resource's own live doc example, identical pattern to terraform-google-chronicle-rule-deployment.
  • No update timeout β€” confirmed this resource is effectively create-only; changing process_interval or rule forces a new resource.
  • deletion_policy doc/schema mismatch β€” confirmed no such argument exists in the live schema-JSON despite prose docs referencing it. This module does not model it.
  • No labels, no self_link β€” family-wide facts.

πŸ”‘ Required IAM Roles

  • roles/chronicle.admin β€” same family-wide role as every other Chronicle module.

☁️ GCP Prerequisites

  • chronicle.googleapis.com enabled.
  • A Chronicle (Google SecOps) instance must already be activated for the target project.
  • The referenced rule must already exist.

πŸ“ Module Structure

terraform-google-chronicle-retrohunt/
β”œβ”€β”€ providers.tf
β”œβ”€β”€ variables.tf # instance, location, rule, retrohunt_id, process_interval, timeouts
β”œβ”€β”€ main.tf # google_chronicle_retrohunt.this
β”œβ”€β”€ outputs.tf # id, name, retrohunt_id, state, progress_percentage, execution_interval
β”œβ”€β”€ README.md
β”œβ”€β”€ SCOPE.md
└── examples/
 └── basic/

βš™οΈ Quick Start

module "excessive_login_failures" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-rule.git?ref=v1.0.0"

  instance = "00000000-0000-0000-0000-000000000000"
  location = "us"

  text = <<-EOT
 rule excessive_login_failures {
 meta:
 author = "casey-secops"
 events:
 $e.metadata.event_type = "USER_LOGIN"
 $e.security_result.action = "BLOCK"
 $userid = $e.principal.user.userid
 match:
 $userid over 10m
 condition:
 #e > 10
 }
 EOT
}

module "excessive_login_failures_retrohunt" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-retrohunt.git?ref=v1.0.0"

  instance = "00000000-0000-0000-0000-000000000000"
  location = "us"
  rule     = basename(module.excessive_login_failures.name)

  process_interval = {
    start_time = "2026-01-01T00:00:00Z"
    end_time   = "2026-02-01T00:00:00Z"
  }
}

πŸ”Œ Cross-Module Contract

Consumes:

Input Type Source module
rule string (short rule ID) terraform-google-chronicle-rule (required)

Emits:

Output Description Consumed by
id Terraform-internal id None
name Resource name of the retrohunt None
retrohunt_id Echoes the resource's own retrohunt argument None
state Computed: RUNNING, DONE, CANCELLED, or FAILED None
progress_percentage Computed percent progress, 0.00 to 100.00 None
execution_interval Computed actual executed time interval None

No self_link row.


πŸ“š Example Library

1 Β· Minimal one-month retrohunt
module "excessive_login_failures_retrohunt" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-retrohunt.git?ref=v1.0.0"

  instance = "00000000-0000-0000-0000-000000000000"
  location = "us"
  rule     = "ru_a1b2c3d4"

  process_interval = {
    start_time = "2026-01-01T00:00:00Z"
    end_time   = "2026-02-01T00:00:00Z"
  }
}
2 Β· One-week window
module "recent_week_retrohunt" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-retrohunt.git?ref=v1.0.0"

  instance = "00000000-0000-0000-0000-000000000000"
  location = "us"
  rule     = "ru_b2c3d4e5"

  process_interval = {
    start_time = "2026-07-01T00:00:00Z"
    end_time   = "2026-07-08T00:00:00Z"
  }
}
3 Β· Full-quarter historical validation
module "quarter_validation_retrohunt" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-retrohunt.git?ref=v1.0.0"

  instance = "00000000-0000-0000-0000-000000000000"
  location = "us"
  rule     = "ru_c3d4e5f6"

  process_interval = {
    start_time = "2026-01-01T00:00:00Z"
    end_time   = "2026-04-01T00:00:00Z"
  }
}

⚠️ Longer windows take proportionally longer to complete β€” check state/progress_percentage before assuming the retrohunt has finished.

4 Β· Explicit retrohunt_id
module "named_retrohunt" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-retrohunt.git?ref=v1.0.0"

  instance     = "00000000-0000-0000-0000-000000000000"
  location     = "us"
  rule         = "ru_d4e5f6a7"
  retrohunt_id = "jan-2026-validation"

  process_interval = {
    start_time = "2026-01-01T00:00:00Z"
    end_time   = "2026-02-01T00:00:00Z"
  }
}
5 Β· Custom create timeout for a long historical window
module "year_long_retrohunt" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-retrohunt.git?ref=v1.0.0"

  instance = "00000000-0000-0000-0000-000000000000"
  location = "us"
  rule     = "ru_e5f6a7b8"

  process_interval = {
    start_time = "2025-01-01T00:00:00Z"
    end_time   = "2026-01-01T00:00:00Z"
  }

  timeouts = {
    create = "60m"
  }
}

ℹ️ This resource's timeouts block only supports create/delete β€” there is no update timeout, since the resource is effectively create-only.

6 Β· πŸ—οΈ End-to-end composition
module "excessive_login_failures" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-rule.git?ref=v1.0.0"

  instance = "00000000-0000-0000-0000-000000000000"
  location = "us"

  text = <<-EOT
 rule excessive_login_failures {
 meta:
 author = "casey-secops"
 severity = "Medium"
 events:
 $e.metadata.event_type = "USER_LOGIN"
 $e.security_result.action = "BLOCK"
 $userid = $e.principal.user.userid
 match:
 $userid over 10m
 condition:
 #e > 10
 }
 EOT
}

module "excessive_login_failures_retrohunt" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-retrohunt.git?ref=v1.0.0"

  instance = "00000000-0000-0000-0000-000000000000"
  location = "us"
  rule     = basename(module.excessive_login_failures.name)

  process_interval = {
    start_time = "2026-01-01T00:00:00Z"
    end_time   = "2026-02-01T00:00:00Z"
  }
}

πŸ”— Wires terraform-google-chronicle-rule's name output through basename into this module's rule β€” the confirmed short-ID reference form, identical to the rule-deployment module's pattern.


πŸ“₯ Inputs

Variable Type Default Notes
instance string β€” (required) Caller-supplied literal
location string β€” (required) e.g. "us"
rule string β€” (required) Short rule ID; source via basename
retrohunt_id string null Optional+computed; force-new
process_interval object({ start_time, end_time }) β€” (required) RFC3339 UTC timestamps
timeouts object({ create, delete }) null No update β€” confirmed absent

No labels variable. No deletion_policy variable (see Architecture Notes).


🧾 Outputs

Output Description
id Terraform-internal id
name Resource name of the retrohunt
retrohunt_id Echoes the resource's own retrohunt argument
state Computed: RUNNING, DONE, CANCELLED, or FAILED
progress_percentage Computed percent progress, 0.00 to 100.00
execution_interval Computed actual executed time interval

No self_link, no labels-related outputs.


🧠 Architecture Notes

  • rule is the short rule ID, not the full resource name β€” confirmed via the resource's own live doc example, identical to terraform-google-chronicle-rule-deployment's own pattern.
  • This resource is effectively create-only β€” no update timeout exists; any change to process_interval or rule forces replacement, not an in-place update.
  • deletion_policy doc/schema discrepancy, confirmed and documented: this resource's published prose documentation references a deletion_policy argument, but the live schema-JSON dump (ground truth per house standard) confirms it does not exist at this provider version. This module intentionally omits it β€” do not add a deletion_policy variable without first re-verifying against a fresh terraform providers schema -json dump.
  • No labels, no self_link β€” family-wide facts.

🧱 Design Principles

Concern Secure default Opt-out (explicit)
Malformed time range reaching apply This module's own validation{} requires both start_time and end_time to be non-empty N/A β€” this is a hard requirement

No deletion_policy-based secure default applies to this resource β€” see Architecture Notes.


πŸš€ Runbook

cd terraform-google-chronicle-retrohunt
terraform init -backend=false
terraform validate
terraform fmt -check

πŸ§ͺ Testing

validate/fmt confirm process_interval's non-empty timestamp requirement and internal type consistency, but cannot validate that start_time/end_time are well-formed RFC3339 values, that start_time precedes end_time, or that the referenced rule actually exists β€” those are API-level rejections only apply can surface.


πŸ’¬ Example Output

$ terraform output
id = "projects/casey-prod/locations/us/instances/00000000-0000-0000-0000-000000000000/rules/ru_a1b2c3d4/retrohunts/rh_a1b2c3d4"
name = "projects/casey-prod/locations/us/instances/00000000-0000-0000-0000-000000000000/rules/ru_a1b2c3d4/retrohunts/rh_a1b2c3d4"
retrohunt_id = "rh_a1b2c3d4"
state = "RUNNING"
progress_percentage = 42.5
execution_interval = [
 {
 "start_time" = "2026-01-01T00:00:00Z"
 "end_time" = "2026-02-01T00:00:00Z"
 },
]

πŸ” Troubleshooting

Symptom Cause Fix
Apply hangs waiting for completion Retrohunt over a long historical window still RUNNING Increase timeouts.create, or poll state/progress_percentage separately
state shows FAILED Malformed rule text, or a backend processing error Confirm the referenced rule compiles successfully (terraform-google-chronicle-rule's compilation_state output)
Apply fails: process_interval invalid start_time is after end_time, or timestamps are not valid RFC3339 Correct the interval; start_time must be ≀ end_time
A change to process_interval triggers a full replace Confirmed β€” this resource is create-only; there is no in-place update path Expected behavior; a new retrohunt resource is the correct outcome

πŸ”— Related Docs

About

Terraform module: terraform-google-chronicle-retrohunt

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages