Skip to content

About

Terraform module: terraform-google-chronicle-watchlist

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

☁️ Google Cloud Chronicle Watchlist Terraform Module

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

Terraform Provider Module Type Resources Posture


🧩 Overview

  • Creates exactly one google_chronicle_watchlist resource — a named collection of entities (assets/users) subject to a risk-score multiplier and prioritized monitoring.
  • entity_population_mechanism is Required with exactly one supported variant, manual — entity membership itself is populated outside this resource's own schema (via the Chronicle console/API), not through Terraform.
  • watchlist_id is optional+computed — a settable-but-auto-generatable ID pattern, distinct from the four other ID patterns already confirmed elsewhere in this Chronicle batch.

💡 Why it matters: Watchlists let a SOC prioritize monitoring for specific high-risk entities — modeling the watchlist container and its risk weighting as code keeps that prioritization auditable, even though entity membership itself stays a manual, console-driven workflow.


❤️ 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
 THIS["terraform-google-chronicle-watchlist<br/>(this module — standalone)"]:::thismodule
 EXT["Chronicle console/API<br/>(manual entity population, out-of-band)"]:::ext

 EXT -.->|"entities added manually, not via Terraform"| THIS

 classDef thismodule fill:#4285F4,color:#FFFFFF,stroke:#174EA6,stroke-width:1px;
 classDef ext fill:#F1F3F4,color:#202124,stroke:#5F6368,stroke-width:1px;
Loading

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


🧬 What this builds

flowchart TB
 subgraph Inputs
 WLID["var.watchlist_id"]
 DN["var.display_name"]
 MF["var.multiplying_factor"]
 EPM["var.entity_population_mechanism"]
 DP["var.deletion_policy"]
 end

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

 subgraph Outputs
 ID["id / name"]
 WID["watchlist_id"]
 EC["entity_count"]
 end

 WLID --> KEYSTONE
 DN --> KEYSTONE
 MF --> KEYSTONE
 EPM --> KEYSTONE
 DP --> KEYSTONE

 KEYSTONE --> ID
 KEYSTONE --> WID
 KEYSTONE --> EC

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

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

Resource inventory: google_chronicle_watchlist.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:

  • entity_population_mechanism only supports manual today — an empty nested block; a future provider-added mechanism (e.g. rule-based population) would be a schema change, not a silent behavior change, since this module models it as a closed object({ manual = bool }).
  • watchlist_id is optional+computed — settable but auto-generated if omitted, distinct from custom_list_id (computed-only), data_access_scope_id/reference_list_id (required), and findings_refinement (no settable ID attribute at all).
  • deletion_policy IS present — unlike findings_refinement/reference_list earlier in this same batch, which genuinely lack 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.

📁 Module Structure

terraform-google-chronicle-watchlist/
├── providers.tf
├── variables.tf # instance, location, watchlist_id, display_name, description,
│ # multiplying_factor, deletion_policy, entity_population_mechanism,
│ # watchlist_user_preferences, timeouts
├── main.tf # google_chronicle_watchlist.this
├── outputs.tf # id, name, watchlist_id, entity_count, create_time, update_time
├── README.md
├── SCOPE.md
└── examples/
 └── basic/

⚙️ Quick Start

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

  instance     = "00000000-0000-0000-0000-000000000000"
  location     = "us"
  display_name = "High-Risk Executives"

  entity_population_mechanism = {
    manual = true
  }
}

🔌 Cross-Module Contract

Consumes: None — leaf module, no cross-module input dependencies.

Emits:

Output Description Consumed by
id Terraform-internal id None
name Resource name of the watchlist None
watchlist_id Echoes the resource's own watchlist_id (API-generated if omitted) None
entity_count Computed count of entities by type (asset/user) None
create_time Computed creation timestamp None
update_time Computed last-update timestamp None

No self_link row.


📚 Example Library

1 · Minimal watchlist
module "high_risk_executives" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-watchlist.git?ref=v1.0.0"

  instance     = "00000000-0000-0000-0000-000000000000"
  location     = "us"
  display_name = "High-Risk Executives"

  entity_population_mechanism = {
    manual = true
  }
}
2 · Explicit watchlist_id
module "named_watchlist" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-watchlist.git?ref=v1.0.0"

  instance     = "00000000-0000-0000-0000-000000000000"
  location     = "us"
  watchlist_id = "high-risk-execs"
  display_name = "High-Risk Executives"

  entity_population_mechanism = {
    manual = true
  }
}

ℹ️ watchlist_id is optional+computed — omit it to let GCP auto-generate one, or supply your own for a predictable resource name.

3 · With a description
module "high_risk_executives" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-watchlist.git?ref=v1.0.0"

  instance     = "00000000-0000-0000-0000-000000000000"
  location     = "us"
  display_name = "High-Risk Executives"
  description  = "C-suite and board members subject to elevated monitoring"

  entity_population_mechanism = {
    manual = true
  }
}
4 · Custom multiplying_factor
module "elevated_risk_watchlist" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-watchlist.git?ref=v1.0.0"

  instance           = "00000000-0000-0000-0000-000000000000"
  location           = "us"
  display_name       = "Elevated Risk Contractors"
  multiplying_factor = 2.5

  entity_population_mechanism = {
    manual = true
  }
}

💡 multiplying_factor defaults to 1.0 if unset — values above 1.0 amplify the risk score contribution of entities in this watchlist.

5 · Pinned to the dashboard
module "pinned_watchlist" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-watchlist.git?ref=v1.0.0"

  instance     = "00000000-0000-0000-0000-000000000000"
  location     = "us"
  display_name = "High-Risk Executives"

  entity_population_mechanism = {
    manual = true
  }

  watchlist_user_preferences = {
    pinned = true
  }
}
6 · Relying on the default deletion_policy = "PREVENT"
module "high_risk_executives" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-watchlist.git?ref=v1.0.0"

  instance     = "00000000-0000-0000-0000-000000000000"
  location     = "us"
  display_name = "High-Risk Executives"

  entity_population_mechanism = {
    manual = true
  }
}

ℹ️ No deletion_policy set — the module default of "PREVENT" applies.

7 · deletion_policy = "DELETE" opt-out
module "scratch_watchlist" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-watchlist.git?ref=v1.0.0"

  instance        = "00000000-0000-0000-0000-000000000000"
  location        = "us"
  display_name    = "Scratch Test Watchlist"
  deletion_policy = "DELETE"

  entity_population_mechanism = {
    manual = true
  }
}
8 · Custom timeouts
module "high_risk_executives" {
  source = "git::https://github.com/microsoftexpert/terraform-google-chronicle-watchlist.git?ref=v1.0.0"

  instance     = "00000000-0000-0000-0000-000000000000"
  location     = "us"
  display_name = "High-Risk Executives"

  entity_population_mechanism = {
    manual = true
  }

  timeouts = {
    create = "10m"
    delete = "10m"
  }
}
9 · 🏗️ Multiple watchlists sharing a naming convention
locals {
  soc_watchlist_prefix = "SOC Priority"
}

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

  instance           = "00000000-0000-0000-0000-000000000000"
  location           = "us"
  display_name       = "${local.soc_watchlist_prefix}: High-Risk Executives"
  multiplying_factor = 2.0

  entity_population_mechanism = {
    manual = true
  }

  watchlist_user_preferences = {
    pinned = true
  }
}

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

  instance           = "00000000-0000-0000-0000-000000000000"
  location           = "us"
  display_name       = "${local.soc_watchlist_prefix}: Recently Offboarded"
  multiplying_factor = 1.5

  entity_population_mechanism = {
    manual = true
  }
}

🔗 As with findings_refinement, this resource has no natural sibling module to wire into — a shared local naming prefix keeps a batch of watchlists organized in the Chronicle console.


📥 Inputs

Variable Type Default Notes
instance string — (required) Caller-supplied literal
location string — (required) e.g. "us"
watchlist_id string null Optional+computed; force-new
display_name string — (required) 1-62 characters
description string null
multiplying_factor number null Provider defaults to 1.0 if unset
deletion_policy string "PREVENT" Closed enum; house extension over provider default
entity_population_mechanism object({ manual = bool }) — (required) manual must be true — the only supported mechanism
watchlist_user_preferences object({ pinned = optional(bool) }) null
timeouts object({...}) null create/update/delete

No labels variable.


🧾 Outputs

Output Description
id Terraform-internal id
name Resource name of the watchlist
watchlist_id Echoes the resource's own watchlist_id
entity_count Computed count of entities by type (asset/user)
create_time Computed creation timestamp
update_time Computed last-update timestamp

No self_link, no labels-related outputs.


🧠 Architecture Notes

  • Entity membership is not modeled by this module — the schema only exposes a boolean-shaped manual population toggle; entities themselves are added via the Chronicle console/API, out of Terraform's scope entirely.
  • watchlist_id is optional+computed — a fifth distinct ID pattern confirmed across this Chronicle batch (alongside custom_list_id, data_access_scope_id/reference_list_id, findings_refinement's complete absence of a settable ID, and feed's identical optional+computed shape).
  • deletion_policy IS present on this resource — do not assume the findings_refinement/ reference_list exception generalizes to every Chronicle resource.
  • No labels, no self_link — family-wide facts.

🧱 Design Principles

Concern Secure default Opt-out (explicit)
Accidental destroy of a live watchlist deletion_policy = "PREVENT" (house extension over the provider's native "DELETE" default) Caller sets "DELETE" or "ABANDON" explicitly
Unsupported entity population mechanism reaching plan entity_population_mechanism.manual must be true via this module's own validation{} N/A — this is a hard requirement matching the only mechanism this provider version supports

🚀 Runbook

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

🧪 Testing

validate/fmt confirm display_name's length constraint, entity_population_mechanism.manual's required-true constraint, and internal type consistency, but cannot confirm the watchlist's actual entity population (which happens entirely outside this module's schema) or its effect on real risk scoring — those are only observable after apply against a live instance, via the Chronicle console.


💬 Example Output

$ terraform output
id = "projects/casey-prod/locations/us/instances/00000000-0000-0000-0000-000000000000/watchlists/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
name = "projects/casey-prod/locations/us/instances/00000000-0000-0000-0000-000000000000/watchlists/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
watchlist_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
entity_count = [
 {
 "asset" = 0
 "user" = 0
 },
]

🔍 Troubleshooting

Symptom Cause Fix
Plan fails: entity_population_mechanism.manual must be true A value other than true was supplied Set entity_population_mechanism = { manual = true }
entity_count stays at zero after apply Entities have not yet been added via the Chronicle console/API — this module only creates the container Add entities out-of-band; this is expected, not a bug
Resource destroyed unexpectedly deletion_policy left at "DELETE" Confirm deletion_policy = "PREVENT" (the module default) is in effect

🔗 Related Docs

About

Terraform module: terraform-google-chronicle-watchlist

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages