Provisions a Google SecOps (Chronicle) watchlist, targeting
hashicorp/google ~> 7.0.
- Creates exactly one
google_chronicle_watchlistresource — a named collection of entities (assets/users) subject to a risk-score multiplier and prioritized monitoring. entity_population_mechanismis 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_idis 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.
If these Terraform modules have been helpful to you or your organization, I'd appreciate your support in any of the following ways:
- ⭐ Star this repository to help others discover this Terraform module.
- 🤝 Connect with me on LinkedIn: linkedin.com/in/microsoftexpert
- ☕ Buy me a coffee: buymeacoffee.com/microsoftexpert
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!
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;
Validated via the Mermaid Chart MCP (valid: true).
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;
Validated via the Mermaid Chart MCP (valid: true).
Resource inventory: google_chronicle_watchlist.this (1 resource).
| 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_mechanismonly supportsmanualtoday — 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 closedobject({ manual = bool }).watchlist_idis optional+computed — settable but auto-generated if omitted, distinct fromcustom_list_id(computed-only),data_access_scope_id/reference_list_id(required), andfindings_refinement(no settable ID attribute at all).deletion_policyIS present — unlikefindings_refinement/reference_listearlier in this same batch, which genuinely lack it.- No
labels, noself_link— family-wide facts.
roles/chronicle.admin— same family-wide role as every other Chronicle module.
chronicle.googleapis.comenabled.- A Chronicle (Google SecOps) instance must already be activated for the target project.
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/
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
}
}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.
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_idis 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_factordefaults to1.0if unset — values above1.0amplify 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_policyset — 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 sharedlocalnaming prefix keeps a batch of watchlists organized in the Chronicle console.
| 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.
| 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.
- Entity membership is not modeled by this module — the schema only exposes a boolean-shaped
manualpopulation toggle; entities themselves are added via the Chronicle console/API, out of Terraform's scope entirely. watchlist_idis optional+computed — a fifth distinct ID pattern confirmed across this Chronicle batch (alongsidecustom_list_id,data_access_scope_id/reference_list_id,findings_refinement's complete absence of a settable ID, andfeed's identical optional+computed shape).deletion_policyIS present on this resource — do not assume thefindings_refinement/reference_listexception generalizes to every Chronicle resource.- No
labels, noself_link— family-wide facts.
| 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 |
cd terraform-google-chronicle-watchlist
terraform init -backend=false
terraform validate
terraform fmt -checkvalidate/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.
$ 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
},
]
| 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 |
google_chronicle_watchlistprovider docs- This module's
SCOPE.md

