Feature Description
Every stage that sets contacts declares essential_contacts as a plain string (default null) — 0-bootstrap/variables.tf:117, 2-networking-a-fedramp-high:67, 2-networking-b-il5-ngfw:59, 3-security:42 — and configures it as { (var.essential_contacts) = ["ALL"] }. This permits exactly one contact email, pinned to the ALL notification category, per resource. Retype it to the map the underlying modules already support.
Use Case
The organization, folder, and project modules already type contacts as map(EMAIL => list(NOTIFICATION_TYPES)) (valid types ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES) and for_each over it — the capability exists but is throttled by the stage variable. There is currently no way to register multiple contacts, or a contact scoped to a category (e.g. a billing address on BILLING/SUSPENSION only), without editing stage source. Any realistic contacts posture (separate SOC / billing / legal addresses) requires a code edit. Separately, the org-level organization-se call in 0-bootstrap passes no contacts at all, so the one place that would cascade org-wide is unused.
Proposed Solution
Retype essential_contacts to map(list(string)) (default {}) in each stage and pass it straight to the module contacts argument; add a contacts argument to the org-level call so an org-wide map can cascade. Backward-compatible shim:
contacts = try(tomap(var.essential_contacts), var.essential_contacts == null ? {} : { (var.essential_contacts) = ["ALL"] })
Compliance & Deployment Context
- Target Deployment Type(s):
- Relevant NIST 800-53r5 Controls: SI-5 (security alerts/advisories), IR-6 (incident reporting) — category-scoped contacts let notifications reach the right teams.
Reusability Check
Stellar Engine prioritizes reusability.
Alternatives Considered
Editing stage source per deployment (current workaround); documenting the limitation. Both leave a module capability inexpressible through tfvars.
Additional Context
Verified at main @ 3728fc98. Attempting the map form today fails with a type error since the variable is a string. A clean example of a stage variable discarding a richer module capability.
Feature Description
Every stage that sets contacts declares
essential_contactsas a plainstring(defaultnull) —0-bootstrap/variables.tf:117,2-networking-a-fedramp-high:67,2-networking-b-il5-ngfw:59,3-security:42— and configures it as{ (var.essential_contacts) = ["ALL"] }. This permits exactly one contact email, pinned to theALLnotification category, per resource. Retype it to the map the underlying modules already support.Use Case
The
organization,folder, andprojectmodules already typecontactsasmap(EMAIL => list(NOTIFICATION_TYPES))(valid typesALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES) andfor_eachover it — the capability exists but is throttled by the stage variable. There is currently no way to register multiple contacts, or a contact scoped to a category (e.g. a billing address onBILLING/SUSPENSIONonly), without editing stage source. Any realistic contacts posture (separate SOC / billing / legal addresses) requires a code edit. Separately, the org-levelorganization-secall in 0-bootstrap passes nocontactsat all, so the one place that would cascade org-wide is unused.Proposed Solution
Retype
essential_contactstomap(list(string))(default{}) in each stage and pass it straight to the modulecontactsargument; add acontactsargument to the org-level call so an org-wide map can cascade. Backward-compatible shim:Compliance & Deployment Context
Reusability Check
Stellar Engine prioritizes reusability.
Alternatives Considered
Editing stage source per deployment (current workaround); documenting the limitation. Both leave a module capability inexpressible through tfvars.
Additional Context
Verified at
main@3728fc98. Attempting the map form today fails with a type error since the variable is astring. A clean example of a stage variable discarding a richer module capability.