From 2d9d81e0616e3d7f0dd248c403637ad9575b78c0 Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Wed, 24 Feb 2021 18:34:17 +0100 Subject: [PATCH] Add support for essential contacts --- modules/folder/README.md | 1 + modules/folder/main.tf | 21 +++++++++++++++------ modules/folder/variables.tf | 6 ++++++ modules/folder/versions.tf | 3 +++ modules/organization/README.md | 1 + modules/organization/main.tf | 23 ++++++++++++++++------- modules/organization/variables.tf | 6 ++++++ modules/organization/versions.tf | 3 +++ modules/project/README.md | 1 + modules/project/main.tf | 21 +++++++++++++++------ modules/project/variables.tf | 7 +++++++ modules/project/versions.tf | 3 +++ 12 files changed, 77 insertions(+), 19 deletions(-) diff --git a/modules/folder/README.md b/modules/folder/README.md index 3e7e6597..98bbde94 100644 --- a/modules/folder/README.md +++ b/modules/folder/README.md @@ -144,6 +144,7 @@ module "folder2" { | name | description | type | required | default | |---|---|:---: |:---:|:---:| +| *contacts* | List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES | map(list(string)) | | {} | | *firewall_policies* | Hierarchical firewall policies to *create* in this folder. | map(map(object({...}))) | | {} | | *firewall_policy_attachments* | List of hierarchical firewall policy IDs to *attach* to this folder. | map(string) | | {} | | *folder_create* | Create folder. When set to false, uses id to reference an existing folder. | bool | | true | diff --git a/modules/folder/main.tf b/modules/folder/main.tf index af44df1f..154c8c3b 100644 --- a/modules/folder/main.tf +++ b/modules/folder/main.tf @@ -71,7 +71,7 @@ resource "google_folder_organization_policy" "boolean" { folder = local.folder.name constraint = each.key - dynamic boolean_policy { + dynamic "boolean_policy" { for_each = each.value == null ? [] : [each.value] iterator = policy content { @@ -79,7 +79,7 @@ resource "google_folder_organization_policy" "boolean" { } } - dynamic restore_policy { + dynamic "restore_policy" { for_each = each.value == null ? [""] : [] content { default = true @@ -92,13 +92,13 @@ resource "google_folder_organization_policy" "list" { folder = local.folder.name constraint = each.key - dynamic list_policy { + dynamic "list_policy" { for_each = each.value.status == null ? [] : [each.value] iterator = policy content { inherit_from_parent = policy.value.inherit_from_parent suggested_value = policy.value.suggested_value - dynamic allow { + dynamic "allow" { for_each = policy.value.status ? [""] : [] content { values = ( @@ -113,7 +113,7 @@ resource "google_folder_organization_policy" "list" { ) } } - dynamic deny { + dynamic "deny" { for_each = policy.value.status ? [] : [""] content { values = ( @@ -131,7 +131,7 @@ resource "google_folder_organization_policy" "list" { } } - dynamic restore_policy { + dynamic "restore_policy" { for_each = each.value.status == null ? [true] : [] content { default = true @@ -224,3 +224,12 @@ resource "google_logging_folder_exclusion" "logging-exclusion" { description = "${each.key} (Terraform-managed)" filter = each.value } + +resource "google_essential_contacts_contact" "contact" { + provider = google-beta + for_each = var.contacts + parent = local.folder.name + email = each.key + language_tag = "en" + notification_category_subscriptions = each.value +} diff --git a/modules/folder/variables.tf b/modules/folder/variables.tf index e52cc0df..b9d9b253 100644 --- a/modules/folder/variables.tf +++ b/modules/folder/variables.tf @@ -104,3 +104,9 @@ variable "id" { type = string default = null } + +variable "contacts" { + description = "List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES" + type = map(list(string)) + default = {} +} diff --git a/modules/folder/versions.tf b/modules/folder/versions.tf index aac1e5f9..7262ee55 100644 --- a/modules/folder/versions.tf +++ b/modules/folder/versions.tf @@ -16,4 +16,7 @@ terraform { required_version = ">= 0.13.0" + required_providers { + google = "~> 3.57" + } } diff --git a/modules/organization/README.md b/modules/organization/README.md index 9b775673..e16ab79a 100644 --- a/modules/organization/README.md +++ b/modules/organization/README.md @@ -121,6 +121,7 @@ module "org" { | name | description | type | required | default | |---|---|:---: |:---:|:---:| | organization_id | Organization id in organizations/nnnnnn format. | string | ✓ | | +| *contacts* | List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES | map(list(string)) | | {} | | *custom_roles* | Map of role name => list of permissions to create in this project. | map(list(string)) | | {} | | *firewall_policies* | Hierarchical firewall policies to *create* in the organization. | map(map(object({...}))) | | {} | | *firewall_policy_attachments* | List of hierarchical firewall policy IDs to *attach* to the organization | map(string) | | {} | diff --git a/modules/organization/main.tf b/modules/organization/main.tf index 03dabd6a..10788dba 100644 --- a/modules/organization/main.tf +++ b/modules/organization/main.tf @@ -120,7 +120,7 @@ resource "google_organization_iam_audit_config" "config" { for_each = var.iam_audit_config org_id = local.organization_id_numeric service = each.key - dynamic audit_log_config { + dynamic "audit_log_config" { for_each = each.value iterator = config content { @@ -135,7 +135,7 @@ resource "google_organization_policy" "boolean" { org_id = local.organization_id_numeric constraint = each.key - dynamic boolean_policy { + dynamic "boolean_policy" { for_each = each.value == null ? [] : [each.value] iterator = policy content { @@ -143,7 +143,7 @@ resource "google_organization_policy" "boolean" { } } - dynamic restore_policy { + dynamic "restore_policy" { for_each = each.value == null ? [""] : [] content { default = true @@ -156,13 +156,13 @@ resource "google_organization_policy" "list" { org_id = local.organization_id_numeric constraint = each.key - dynamic list_policy { + dynamic "list_policy" { for_each = each.value.status == null ? [] : [each.value] iterator = policy content { inherit_from_parent = policy.value.inherit_from_parent suggested_value = policy.value.suggested_value - dynamic allow { + dynamic "allow" { for_each = policy.value.status ? [""] : [] content { values = ( @@ -177,7 +177,7 @@ resource "google_organization_policy" "list" { ) } } - dynamic deny { + dynamic "deny" { for_each = policy.value.status ? [] : [""] content { values = ( @@ -195,7 +195,7 @@ resource "google_organization_policy" "list" { } } - dynamic restore_policy { + dynamic "restore_policy" { for_each = each.value.status == null ? [true] : [] content { default = true @@ -288,3 +288,12 @@ resource "google_logging_organization_exclusion" "logging-exclusion" { description = "${each.key} (Terraform-managed)" filter = each.value } + +resource "google_essential_contacts_contact" "contact" { + provider = google-beta + for_each = var.contacts + parent = var.organization_id + email = each.key + language_tag = "en" + notification_category_subscriptions = each.value +} diff --git a/modules/organization/variables.tf b/modules/organization/variables.tf index 1a0c7817..67e1143b 100644 --- a/modules/organization/variables.tf +++ b/modules/organization/variables.tf @@ -133,3 +133,9 @@ variable "logging_exclusions" { type = map(string) default = {} } + +variable "contacts" { + description = "List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES" + type = map(list(string)) + default = {} +} diff --git a/modules/organization/versions.tf b/modules/organization/versions.tf index 7c3f279a..cca8a5fc 100644 --- a/modules/organization/versions.tf +++ b/modules/organization/versions.tf @@ -16,4 +16,7 @@ terraform { required_version = ">= 0.12.6" + required_providers { + google = "~> 3.57" + } } diff --git a/modules/project/README.md b/modules/project/README.md index 12e78e39..050c3ffa 100644 --- a/modules/project/README.md +++ b/modules/project/README.md @@ -135,6 +135,7 @@ module "project-host" { | name | Project name and id suffix. | string | ✓ | | | *auto_create_network* | Whether to create the default network for the project | bool | | false | | *billing_account* | Billing account id. | string | | null | +| *contacts* | List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES | map(list(string)) | | {} | | *custom_roles* | Map of role name => list of permissions to create in this project. | map(list(string)) | | {} | | *iam* | IAM bindings in {ROLE => [MEMBERS]} format. | map(set(string)) | | {} | | *iam_additive* | IAM additive bindings in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | diff --git a/modules/project/main.tf b/modules/project/main.tf index 929de3bb..2a82f564 100644 --- a/modules/project/main.tf +++ b/modules/project/main.tf @@ -169,7 +169,7 @@ resource "google_project_organization_policy" "boolean" { project = local.project.project_id constraint = each.key - dynamic boolean_policy { + dynamic "boolean_policy" { for_each = each.value == null ? [] : [each.value] iterator = policy content { @@ -177,7 +177,7 @@ resource "google_project_organization_policy" "boolean" { } } - dynamic restore_policy { + dynamic "restore_policy" { for_each = each.value == null ? [""] : [] content { default = true @@ -190,13 +190,13 @@ resource "google_project_organization_policy" "list" { project = local.project.project_id constraint = each.key - dynamic list_policy { + dynamic "list_policy" { for_each = each.value.status == null ? [] : [each.value] iterator = policy content { inherit_from_parent = policy.value.inherit_from_parent suggested_value = policy.value.suggested_value - dynamic allow { + dynamic "allow" { for_each = policy.value.status ? [""] : [] content { values = ( @@ -211,7 +211,7 @@ resource "google_project_organization_policy" "list" { ) } } - dynamic deny { + dynamic "deny" { for_each = policy.value.status ? [] : [""] content { values = ( @@ -229,7 +229,7 @@ resource "google_project_organization_policy" "list" { } } - dynamic restore_policy { + dynamic "restore_policy" { for_each = each.value.status == null ? [true] : [] content { default = true @@ -298,3 +298,12 @@ resource "google_logging_project_exclusion" "logging-exclusion" { description = "${each.key} (Terraform-managed)" filter = each.value } + +resource "google_essential_contacts_contact" "contact" { + provider = google-beta + for_each = var.contacts + parent = "projects/${local.project.project_id}" + email = each.key + language_tag = "en" + notification_category_subscriptions = each.value +} diff --git a/modules/project/variables.tf b/modules/project/variables.tf index a63a971a..64c9a08f 100644 --- a/modules/project/variables.tf +++ b/modules/project/variables.tf @@ -182,3 +182,10 @@ variable "logging_exclusions" { type = map(string) default = {} } + + +variable "contacts" { + description = "List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES" + type = map(list(string)) + default = {} +} diff --git a/modules/project/versions.tf b/modules/project/versions.tf index aac1e5f9..7262ee55 100644 --- a/modules/project/versions.tf +++ b/modules/project/versions.tf @@ -16,4 +16,7 @@ terraform { required_version = ">= 0.13.0" + required_providers { + google = "~> 3.57" + } }