From c83a7de0763064bcac79c9063f731b9d04b46a67 Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Sat, 12 Nov 2022 19:24:41 +0100 Subject: [PATCH] Remove as_logging_destination --- fast/stages/00-bootstrap/organization.tf | 3 +- modules/bigquery-dataset/outputs.tf | 15 ----- modules/folder/README.md | 24 ++++---- modules/folder/logging.tf | 18 +++--- modules/folder/variables.tf | 24 ++++---- modules/gcs/outputs.tf | 25 +++++---- modules/logging-bucket/outputs.tf | 13 ----- modules/organization/README.md | 30 +++++----- modules/organization/logging.tf | 18 +++--- modules/organization/variables.tf | 22 ++++---- modules/project/README.md | 55 ++++++++++--------- modules/project/logging.tf | 18 +++--- modules/project/variables.tf | 24 ++++---- modules/pubsub/outputs.tf | 11 ---- .../folder/fixture/test.logging-sinks.tfvars | 30 ++++------ .../fixture/test.logging-sinks.tfvars | 30 ++++------ .../project/fixture/test.logging-sinks.tfvars | 32 ++++------- 17 files changed, 170 insertions(+), 222 deletions(-) diff --git a/fast/stages/00-bootstrap/organization.tf b/fast/stages/00-bootstrap/organization.tf index 297e0f868..0700d564e 100644 --- a/fast/stages/00-bootstrap/organization.tf +++ b/fast/stages/00-bootstrap/organization.tf @@ -193,8 +193,9 @@ module "organization" { logging_sinks = { for name, attrs in var.log_sinks : name => { bq_partitioned_table = attrs.type == "bigquery" - destination = local.log_sink_destinations[name].as_logging_destination + destination = local.log_sink_destinations[name].id filter = attrs.filter + type = attrs.type } } } diff --git a/modules/bigquery-dataset/outputs.tf b/modules/bigquery-dataset/outputs.tf index 11d7f3bb6..dd2da22c6 100644 --- a/modules/bigquery-dataset/outputs.tf +++ b/modules/bigquery-dataset/outputs.tf @@ -14,21 +14,6 @@ * limitations under the License. */ -output "as_logging_destination" { - description = "Parameters to use this dataset as a log sink destination." - value = { - type = "bigquery" - target = google_bigquery_dataset.default.id - } - depends_on = [ - google_bigquery_dataset_access.domain, - google_bigquery_dataset_access.group_by_email, - google_bigquery_dataset_access.special_group, - google_bigquery_dataset_access.user_by_email, - google_bigquery_dataset_access.views - ] -} - output "dataset" { description = "Dataset resource." value = google_bigquery_dataset.default diff --git a/modules/folder/README.md b/modules/folder/README.md index c8dbcda02..1943882d0 100644 --- a/modules/folder/README.md +++ b/modules/folder/README.md @@ -173,23 +173,27 @@ module "folder-sink" { name = "my-folder" logging_sinks = { warnings = { - destination = module.gcs.as_logging_destination + destination = module.gcs.id filter = "severity=WARNING" + type = "storage" } info = { - destination = module.dataset.as_logging_destination + destination = module.dataset.id filter = "severity=INFO" + type = "bigquery" } notice = { - destination = module.pubsub.as_logging_destination + destination = module.pubsub.id filter = "severity=NOTICE" + type = "pubsub" } debug = { - destination = module.bucket.as_logging_destination + destination = module.bucket.id filter = "severity=DEBUG" exclusions = { no-compute = "logName:compute" } + type = "logging" } } logging_exclusions = { @@ -302,12 +306,12 @@ module "folder" { | [iam_additive_members](variables.tf#L85) | IAM additive bindings in {MEMBERS => [ROLE]} format. This might break if members are dynamic values. | map(list(string)) | | {} | | [id](variables.tf#L92) | Folder ID in case you use folder_create=false. | string | | null | | [logging_exclusions](variables.tf#L98) | Logging exclusions for this folder in the form {NAME -> FILTER}. | map(string) | | {} | -| [logging_sinks](variables.tf#L105) | Logging sinks to create for this folder. | map(object({…})) | | {} | -| [name](variables.tf#L137) | Folder name. | string | | null | -| [org_policies](variables.tf#L143) | Organization policies applied to this folder keyed by policy name. | map(object({…})) | | {} | -| [org_policies_data_path](variables.tf#L183) | Path containing org policies in YAML format. | string | | null | -| [parent](variables.tf#L189) | Parent in folders/folder_id or organizations/org_id format. | string | | null | -| [tag_bindings](variables.tf#L199) | Tag bindings for this folder, in key => tag value id format. | map(string) | | null | +| [logging_sinks](variables.tf#L105) | Logging sinks to create for the organization. | map(object({…})) | | {} | +| [name](variables.tf#L135) | Folder name. | string | | null | +| [org_policies](variables.tf#L141) | Organization policies applied to this folder keyed by policy name. | map(object({…})) | | {} | +| [org_policies_data_path](variables.tf#L181) | Path containing org policies in YAML format. | string | | null | +| [parent](variables.tf#L187) | Parent in folders/folder_id or organizations/org_id format. | string | | null | +| [tag_bindings](variables.tf#L197) | Tag bindings for this folder, in key => tag value id format. | map(string) | | null | ## Outputs diff --git a/modules/folder/logging.tf b/modules/folder/logging.tf index e733dfbc6..6351194a8 100644 --- a/modules/folder/logging.tf +++ b/modules/folder/logging.tf @@ -22,7 +22,7 @@ locals { type => { for name, sink in var.logging_sinks : name => sink - if sink.destination.type == type + if sink.type == type } } } @@ -32,7 +32,7 @@ resource "google_logging_folder_sink" "sink" { name = each.key description = coalesce(each.value.description, "${each.key} (Terraform-managed).") folder = local.folder.name - destination = "${each.value.destination.type}.googleapis.com/${each.value.destination.target}" + destination = "${each.value.type}.googleapis.com/${each.value.destination}" filter = each.value.filter include_children = each.value.include_children disabled = each.value.disabled @@ -60,37 +60,37 @@ resource "google_logging_folder_sink" "sink" { resource "google_storage_bucket_iam_member" "gcs-sinks-binding" { for_each = local.sink_bindings["storage"] - bucket = each.value.destination.target + bucket = each.value.destination role = "roles/storage.objectCreator" member = google_logging_folder_sink.sink[each.key].writer_identity } resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" { for_each = local.sink_bindings["bigquery"] - project = split("/", each.value.destination.target)[1] - dataset_id = split("/", each.value.destination.target)[3] + project = split("/", each.value.destination)[1] + dataset_id = split("/", each.value.destination)[3] role = "roles/bigquery.dataEditor" member = google_logging_folder_sink.sink[each.key].writer_identity } resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" { for_each = local.sink_bindings["pubsub"] - project = split("/", each.value.destination.target)[1] - topic = split("/", each.value.destination.target)[3] + project = split("/", each.value.destination)[1] + topic = split("/", each.value.destination)[3] role = "roles/pubsub.publisher" member = google_logging_folder_sink.sink[each.key].writer_identity } resource "google_project_iam_member" "bucket-sinks-binding" { for_each = local.sink_bindings["logging"] - project = split("/", each.value.destination.target)[1] + project = split("/", each.value.destination)[1] role = "roles/logging.bucketWriter" member = google_logging_folder_sink.sink[each.key].writer_identity condition { title = "${each.key} bucket writer" description = "Grants bucketWriter to ${google_logging_folder_sink.sink[each.key].writer_identity} used by log sink ${each.key} on ${local.folder.id}" - expression = "resource.name.endsWith('${each.value.destination.target}')" + expression = "resource.name.endsWith('${each.value.destination}')" } } diff --git a/modules/folder/variables.tf b/modules/folder/variables.tf index 44bee5dae..a93ea1aae 100644 --- a/modules/folder/variables.tf +++ b/modules/folder/variables.tf @@ -103,34 +103,32 @@ variable "logging_exclusions" { } variable "logging_sinks" { - description = "Logging sinks to create for this folder." + description = "Logging sinks to create for the organization." type = map(object({ bq_partitioned_table = optional(bool) description = optional(string) - destination = object({ - type = string - target = string - }) - disabled = optional(bool, false) - exclusions = optional(map(string), {}) - filter = string - include_children = optional(bool, true) + destination = string + disabled = optional(bool, false) + exclusions = optional(map(string), {}) + filter = string + include_children = optional(bool, true) + type = string })) default = {} nullable = false validation { condition = alltrue([ for k, v in var.logging_sinks : - contains(["bigquery", "logging", "pubsub", "storage"], v.destination.type) + contains(["bigquery", "logging", "pubsub", "storage"], v.type) ]) - error_message = "Destination type must be one of 'bigquery', 'logging', 'pubsub', 'storage'." + error_message = "Type must be one of 'bigquery', 'logging', 'pubsub', 'storage'." } validation { condition = alltrue([ for k, v in var.logging_sinks : - v.bq_partitioned_table != true || v.destination.type == "bigquery" + v.bq_partitioned_table != true || v.type == "bigquery" ]) - error_message = "Can only set when destination type is `bigquery`." + error_message = "Can only set bq_partitioned_table when type is `bigquery`." } } diff --git a/modules/gcs/outputs.tf b/modules/gcs/outputs.tf index a92118da2..a00c04cf7 100644 --- a/modules/gcs/outputs.tf +++ b/modules/gcs/outputs.tf @@ -14,23 +14,26 @@ * limitations under the License. */ -output "as_logging_destination" { - description = "Parameters to use this bucket as a log sink destination." - value = { - type = "storage" - target = "${local.prefix}${lower(var.name)}" - } +output "bucket" { + description = "Bucket resource." + value = google_storage_bucket.bucket +} + +# We add `id` as an alias to `name` to simplify log sink handling. +# Since all other log destinations (pubsub, logging-bucket, bigquery) +# have an id output, it is convenient to have in this module too to +# handle all log destination as homogeneous objects (i.e. you can +# assume any valid log destination has an `id` output). + +output "id" { + description = "Bucket ID (same as name)." + value = "${local.prefix}${lower(var.name)}" depends_on = [ google_storage_bucket.bucket, google_storage_bucket_iam_binding.bindings ] } -output "bucket" { - description = "Bucket resource." - value = google_storage_bucket.bucket -} - output "name" { description = "Bucket name." value = "${local.prefix}${lower(var.name)}" diff --git a/modules/logging-bucket/outputs.tf b/modules/logging-bucket/outputs.tf index 945c56f95..7100237e3 100644 --- a/modules/logging-bucket/outputs.tf +++ b/modules/logging-bucket/outputs.tf @@ -14,19 +14,6 @@ * limitations under the License. */ -output "as_logging_destination" { - description = "Parameters to use this bucket as a log sink destination." - value = { - type = "logging" - target = try( - google_logging_project_bucket_config.bucket.0.id, - google_logging_folder_bucket_config.bucket.0.id, - google_logging_organization_bucket_config.bucket.0.id, - google_logging_billing_account_bucket_config.bucket.0.id, - ) - } -} - output "id" { description = "ID of the created bucket." value = try( diff --git a/modules/organization/README.md b/modules/organization/README.md index b99f9a29f..d81611ee7 100644 --- a/modules/organization/README.md +++ b/modules/organization/README.md @@ -311,24 +311,28 @@ module "org" { logging_sinks = { warnings = { - destination = module.gcs.as_logging_destination + destination = module.gcs.id filter = "severity=WARNING" + type = "storage" } info = { - destination = module.dataset.as_logging_destination - filter = "severity=INFO" bq_partitioned_table = true + destination = module.dataset.id + filter = "severity=INFO" + type = "bigquery" } notice = { - destination = module.pubsub.as_logging_destination + destination = module.pubsub.id filter = "severity=NOTICE" + type = "pubsub" } debug = { - destination = module.bucket.as_logging_destination + destination = module.bucket.id filter = "severity=DEBUG" exclusions = { no-compute = "logName:compute" } + type = "logging" } } logging_exclusions = { @@ -411,7 +415,7 @@ module "org" { | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [organization_id](variables.tf#L227) | Organization id in organizations/nnnnnn format. | string | ✓ | | +| [organization_id](variables.tf#L225) | Organization id in organizations/nnnnnn format. | string | ✓ | | | [contacts](variables.tf#L17) | 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](variables.tf#L24) | Map of role name => list of permissions to create in this project. | map(list(string)) | | {} | | [firewall_policies](variables.tf#L31) | Hierarchical firewall policy rules created in the organization. | map(map(object({…}))) | | {} | @@ -425,13 +429,13 @@ module "org" { | [iam_audit_config_authoritative](variables.tf#L105) | IAM Authoritative service audit logging configuration. Service as key, map of log permission (eg DATA_READ) and excluded members as value for each service. Audit config should also be authoritative when using authoritative bindings. Use with caution. | map(map(list(string))) | | null | | [iam_bindings_authoritative](variables.tf#L116) | IAM authoritative bindings, in {ROLE => [MEMBERS]} format. Roles and members not explicitly listed will be cleared. Bindings should also be authoritative when using authoritative audit config. Use with caution. | map(list(string)) | | null | | [logging_exclusions](variables.tf#L122) | Logging exclusions for this organization in the form {NAME -> FILTER}. | map(string) | | {} | -| [logging_sinks](variables.tf#L129) | Logging sinks to create for the organization. | map(object({…})) | | {} | -| [org_policies](variables.tf#L161) | Organization policies applied to this organization keyed by policy name. | map(object({…})) | | {} | -| [org_policies_data_path](variables.tf#L201) | Path containing org policies in YAML format. | string | | null | -| [org_policy_custom_constraints](variables.tf#L207) | Organization policiy custom constraints keyed by constraint name. | map(object({…})) | | {} | -| [org_policy_custom_constraints_data_path](variables.tf#L221) | Path containing org policy custom constraints in YAML format. | string | | null | -| [tag_bindings](variables.tf#L237) | Tag bindings for this organization, in key => tag value id format. | map(string) | | null | -| [tags](variables.tf#L243) | Tags by key name. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | null | +| [logging_sinks](variables.tf#L129) | Logging sinks to create for the organization. | map(object({…})) | | {} | +| [org_policies](variables.tf#L159) | Organization policies applied to this organization keyed by policy name. | map(object({…})) | | {} | +| [org_policies_data_path](variables.tf#L199) | Path containing org policies in YAML format. | string | | null | +| [org_policy_custom_constraints](variables.tf#L205) | Organization policiy custom constraints keyed by constraint name. | map(object({…})) | | {} | +| [org_policy_custom_constraints_data_path](variables.tf#L219) | Path containing org policy custom constraints in YAML format. | string | | null | +| [tag_bindings](variables.tf#L235) | Tag bindings for this organization, in key => tag value id format. | map(string) | | null | +| [tags](variables.tf#L241) | Tags by key name. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | null | ## Outputs diff --git a/modules/organization/logging.tf b/modules/organization/logging.tf index 042228d43..a4f90ef5d 100644 --- a/modules/organization/logging.tf +++ b/modules/organization/logging.tf @@ -21,7 +21,7 @@ locals { for type in ["bigquery", "logging", "pubsub", "storage"] : type => { for name, sink in var.logging_sinks : - name => sink if sink.destination.type == type + name => sink if sink.type == type } } } @@ -31,7 +31,7 @@ resource "google_logging_organization_sink" "sink" { name = each.key description = coalesce(each.value.description, "${each.key} (Terraform-managed).") org_id = local.organization_id_numeric - destination = "${each.value.destination.type}.googleapis.com/${each.value.destination.target}" + destination = "${each.value.type}.googleapis.com/${each.value.destination}" filter = each.value.filter include_children = each.value.include_children disabled = each.value.disabled @@ -61,37 +61,37 @@ resource "google_logging_organization_sink" "sink" { resource "google_storage_bucket_iam_member" "storage-sinks-binding" { for_each = local.sink_bindings["storage"] - bucket = each.value.destination.target + bucket = each.value.destination role = "roles/storage.objectCreator" member = google_logging_organization_sink.sink[each.key].writer_identity } resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" { for_each = local.sink_bindings["bigquery"] - project = split("/", each.value.destination.target)[1] - dataset_id = split("/", each.value.destination.target)[3] + project = split("/", each.value.destination)[1] + dataset_id = split("/", each.value.destination)[3] role = "roles/bigquery.dataEditor" member = google_logging_organization_sink.sink[each.key].writer_identity } resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" { for_each = local.sink_bindings["pubsub"] - project = split("/", each.value.destination.target)[1] - topic = split("/", each.value.destination.target)[3] + project = split("/", each.value.destination)[1] + topic = split("/", each.value.destination)[3] role = "roles/pubsub.publisher" member = google_logging_organization_sink.sink[each.key].writer_identity } resource "google_project_iam_member" "bucket-sinks-binding" { for_each = local.sink_bindings["logging"] - project = split("/", each.value.destination.target)[1] + project = split("/", each.value.destination)[1] role = "roles/logging.bucketWriter" member = google_logging_organization_sink.sink[each.key].writer_identity condition { title = "${each.key} bucket writer" description = "Grants bucketWriter to ${google_logging_organization_sink.sink[each.key].writer_identity} used by log sink ${each.key} on ${var.organization_id}" - expression = "resource.name.endsWith('${each.value.destination.target}')" + expression = "resource.name.endsWith('${each.value.destination}')" } } diff --git a/modules/organization/variables.tf b/modules/organization/variables.tf index 636bba748..f8a949f52 100644 --- a/modules/organization/variables.tf +++ b/modules/organization/variables.tf @@ -131,30 +131,28 @@ variable "logging_sinks" { type = map(object({ bq_partitioned_table = optional(bool) description = optional(string) - destination = object({ - type = string - target = string - }) - disabled = optional(bool, false) - exclusions = optional(map(string), {}) - filter = string - include_children = optional(bool, true) + destination = string + disabled = optional(bool, false) + exclusions = optional(map(string), {}) + filter = string + include_children = optional(bool, true) + type = string })) default = {} nullable = false validation { condition = alltrue([ for k, v in var.logging_sinks : - contains(["bigquery", "logging", "pubsub", "storage"], v.destination.type) + contains(["bigquery", "logging", "pubsub", "storage"], v.type) ]) - error_message = "Destination type must be one of 'bigquery', 'logging', 'pubsub', 'storage'." + error_message = "Type must be one of 'bigquery', 'logging', 'pubsub', 'storage'." } validation { condition = alltrue([ for k, v in var.logging_sinks : - v.bq_partitioned_table != true || v.destination.type == "bigquery" + v.bq_partitioned_table != true || v.type == "bigquery" ]) - error_message = "Can only set bq_partitioned_table when destination type is `bigquery`." + error_message = "Can only set bq_partitioned_table when type is `bigquery`." } } diff --git a/modules/project/README.md b/modules/project/README.md index 55798a549..03ea00a19 100644 --- a/modules/project/README.md +++ b/modules/project/README.md @@ -312,23 +312,27 @@ module "project-host" { parent = "folders/1234567890" logging_sinks = { warnings = { - destination = module.gcs.as_logging_destination + destination = module.gcs.id filter = "severity=WARNING" + type = "storage" } info = { - destination = module.dataset.as_logging_destination + destination = module.dataset.id filter = "severity=INFO" + type = "bigquery" } notice = { - destination = module.pubsub.as_logging_destination + destination = module.pubsub.id filter = "severity=NOTICE" + type = "pubsub" } debug = { - destination = module.bucket.as_logging_destination + destination = module.bucket.id filter = "severity=DEBUG" exclusions = { no-compute = "logName:compute" } + type = "logging" } } logging_exclusions = { @@ -357,9 +361,10 @@ module "project-host" { parent = "folders/1234567890" logging_sinks = { warnings = { - destination = module.gcs.as_logging_destination + destination = module.gcs.id filter = "severity=WARNING" unique_writer = true + type = "storage" } } } @@ -469,7 +474,7 @@ output "compute_robot" { | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [name](variables.tf#L142) | Project name and id suffix. | string | ✓ | | +| [name](variables.tf#L140) | Project name and id suffix. | string | ✓ | | | [auto_create_network](variables.tf#L17) | Whether to create the default network for the project. | bool | | false | | [billing_account](variables.tf#L23) | Billing account id. | string | | null | | [contacts](variables.tf#L29) | 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)) | | {} | @@ -483,25 +488,25 @@ output "compute_robot" { | [labels](variables.tf#L82) | Resource labels. | map(string) | | {} | | [lien_reason](variables.tf#L89) | If non-empty, creates a project lien with this description. | string | | "" | | [logging_exclusions](variables.tf#L95) | Logging exclusions for this project in the form {NAME -> FILTER}. | map(string) | | {} | -| [logging_sinks](variables.tf#L102) | Logging sinks to create for this project. | map(object({…})) | | {} | -| [metric_scopes](variables.tf#L135) | List of projects that will act as metric scopes for this project. | list(string) | | [] | -| [org_policies](variables.tf#L147) | Organization policies applied to this project keyed by policy name. | map(object({…})) | | {} | -| [org_policies_data_path](variables.tf#L187) | Path containing org policies in YAML format. | string | | null | -| [oslogin](variables.tf#L193) | Enable OS Login. | bool | | false | -| [oslogin_admins](variables.tf#L199) | List of IAM-style identities that will be granted roles necessary for OS Login administrators. | list(string) | | [] | -| [oslogin_users](variables.tf#L207) | List of IAM-style identities that will be granted roles necessary for OS Login users. | list(string) | | [] | -| [parent](variables.tf#L214) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | string | | null | -| [prefix](variables.tf#L224) | Optional prefix used to generate project id and name. | string | | null | -| [project_create](variables.tf#L234) | Create project. When set to false, uses a data source to reference existing project. | bool | | true | -| [service_config](variables.tf#L240) | Configure service API activation. | object({…}) | | {…} | -| [service_encryption_key_ids](variables.tf#L252) | Cloud KMS encryption key in {SERVICE => [KEY_URL]} format. | map(list(string)) | | {} | -| [service_perimeter_bridges](variables.tf#L259) | Name of VPC-SC Bridge perimeters to add project into. See comment in the variables file for format. | list(string) | | null | -| [service_perimeter_standard](variables.tf#L266) | Name of VPC-SC Standard perimeter to add project into. See comment in the variables file for format. | string | | null | -| [services](variables.tf#L272) | Service APIs to enable. | list(string) | | [] | -| [shared_vpc_host_config](variables.tf#L278) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | object({…}) | | null | -| [shared_vpc_service_config](variables.tf#L287) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | object({…}) | | null | -| [skip_delete](variables.tf#L297) | Allows the underlying resources to be destroyed without destroying the project itself. | bool | | false | -| [tag_bindings](variables.tf#L303) | Tag bindings for this project, in key => tag value id format. | map(string) | | null | +| [logging_sinks](variables.tf#L102) | Logging sinks to create for this project. | map(object({…})) | | {} | +| [metric_scopes](variables.tf#L133) | List of projects that will act as metric scopes for this project. | list(string) | | [] | +| [org_policies](variables.tf#L145) | Organization policies applied to this project keyed by policy name. | map(object({…})) | | {} | +| [org_policies_data_path](variables.tf#L185) | Path containing org policies in YAML format. | string | | null | +| [oslogin](variables.tf#L191) | Enable OS Login. | bool | | false | +| [oslogin_admins](variables.tf#L197) | List of IAM-style identities that will be granted roles necessary for OS Login administrators. | list(string) | | [] | +| [oslogin_users](variables.tf#L205) | List of IAM-style identities that will be granted roles necessary for OS Login users. | list(string) | | [] | +| [parent](variables.tf#L212) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | string | | null | +| [prefix](variables.tf#L222) | Optional prefix used to generate project id and name. | string | | null | +| [project_create](variables.tf#L232) | Create project. When set to false, uses a data source to reference existing project. | bool | | true | +| [service_config](variables.tf#L238) | Configure service API activation. | object({…}) | | {…} | +| [service_encryption_key_ids](variables.tf#L250) | Cloud KMS encryption key in {SERVICE => [KEY_URL]} format. | map(list(string)) | | {} | +| [service_perimeter_bridges](variables.tf#L257) | Name of VPC-SC Bridge perimeters to add project into. See comment in the variables file for format. | list(string) | | null | +| [service_perimeter_standard](variables.tf#L264) | Name of VPC-SC Standard perimeter to add project into. See comment in the variables file for format. | string | | null | +| [services](variables.tf#L270) | Service APIs to enable. | list(string) | | [] | +| [shared_vpc_host_config](variables.tf#L276) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | object({…}) | | null | +| [shared_vpc_service_config](variables.tf#L285) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | object({…}) | | null | +| [skip_delete](variables.tf#L295) | Allows the underlying resources to be destroyed without destroying the project itself. | bool | | false | +| [tag_bindings](variables.tf#L301) | Tag bindings for this project, in key => tag value id format. | map(string) | | null | ## Outputs diff --git a/modules/project/logging.tf b/modules/project/logging.tf index 1e5948f77..bc1b1e8b0 100644 --- a/modules/project/logging.tf +++ b/modules/project/logging.tf @@ -21,7 +21,7 @@ locals { for type in ["bigquery", "pubsub", "logging", "storage"] : type => { for name, sink in var.logging_sinks : - name => sink if sink.iam && sink.destination.type == type + name => sink if sink.iam && sink.type == type } } } @@ -31,7 +31,7 @@ resource "google_logging_project_sink" "sink" { name = each.key description = coalesce(each.value.description, "${each.key} (Terraform-managed).") project = local.project.project_id - destination = "${each.value.destination.type}.googleapis.com/${each.value.destination.target}" + destination = "${each.value.type}.googleapis.com/${each.value.destination}" filter = each.value.filter unique_writer_identity = each.value.unique_writer disabled = each.value.disabled @@ -60,37 +60,37 @@ resource "google_logging_project_sink" "sink" { resource "google_storage_bucket_iam_member" "gcs-sinks-binding" { for_each = local.sink_bindings["storage"] - bucket = each.value.destination.target + bucket = each.value.destination role = "roles/storage.objectCreator" member = google_logging_project_sink.sink[each.key].writer_identity } resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" { for_each = local.sink_bindings["bigquery"] - project = split("/", each.value.destination.target)[1] - dataset_id = split("/", each.value.destination.target)[3] + project = split("/", each.value.destination)[1] + dataset_id = split("/", each.value.destination)[3] role = "roles/bigquery.dataEditor" member = google_logging_project_sink.sink[each.key].writer_identity } resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" { for_each = local.sink_bindings["pubsub"] - project = split("/", each.value.destination.target)[1] - topic = split("/", each.value.destination.target)[3] + project = split("/", each.value.destination)[1] + topic = split("/", each.value.destination)[3] role = "roles/pubsub.publisher" member = google_logging_project_sink.sink[each.key].writer_identity } resource "google_project_iam_member" "bucket-sinks-binding" { for_each = local.sink_bindings["logging"] - project = split("/", each.value.destination.target)[1] + project = split("/", each.value.destination)[1] role = "roles/logging.bucketWriter" member = google_logging_project_sink.sink[each.key].writer_identity condition { title = "${each.key} bucket writer" description = "Grants bucketWriter to ${google_logging_project_sink.sink[each.key].writer_identity} used by log sink ${each.key} on ${local.project.project_id}" - expression = "resource.name.endsWith('${each.value.destination.target}')" + expression = "resource.name.endsWith('${each.value.destination}')" } } diff --git a/modules/project/variables.tf b/modules/project/variables.tf index e31ee84cb..3769a1fb4 100644 --- a/modules/project/variables.tf +++ b/modules/project/variables.tf @@ -104,31 +104,29 @@ variable "logging_sinks" { type = map(object({ bq_partitioned_table = optional(bool) description = optional(string) - destination = object({ - type = string - target = string - }) - disabled = optional(bool, false) - exclusions = optional(map(string), {}) - filter = string - iam = optional(bool, true) - unique_writer = optional(bool) + destination = string + disabled = optional(bool, false) + exclusions = optional(map(string), {}) + filter = string + iam = optional(bool, true) + type = string + unique_writer = optional(bool) })) default = {} nullable = false validation { condition = alltrue([ for k, v in var.logging_sinks : - contains(["bigquery", "logging", "pubsub", "storage"], v.destination.type) + contains(["bigquery", "logging", "pubsub", "storage"], v.type) ]) - error_message = "Destination type must be one of 'bigquery', 'logging', 'pubsub', 'storage'." + error_message = "Type must be one of 'bigquery', 'logging', 'pubsub', 'storage'." } validation { condition = alltrue([ for k, v in var.logging_sinks : - v.bq_partitioned_table != true || v.destination.type == "bigquery" + v.bq_partitioned_table != true || v.type == "bigquery" ]) - error_message = "Can only set bq_partitioned_table when destination type is `bigquery`." + error_message = "Can only set bq_partitioned_table when type is `bigquery`." } } diff --git a/modules/pubsub/outputs.tf b/modules/pubsub/outputs.tf index 9a2be657c..c26eb4d9a 100644 --- a/modules/pubsub/outputs.tf +++ b/modules/pubsub/outputs.tf @@ -14,17 +14,6 @@ * limitations under the License. */ -output "as_logging_destination" { - description = "Parameters to use this topic as a log sink destination." - value = { - type = "pubsub" - target = google_pubsub_topic.default.id - } - depends_on = [ - google_pubsub_topic_iam_binding.default - ] -} - output "id" { description = "Topic id." value = google_pubsub_topic.default.id diff --git a/tests/modules/folder/fixture/test.logging-sinks.tfvars b/tests/modules/folder/fixture/test.logging-sinks.tfvars index b7dc66876..95a272e1f 100644 --- a/tests/modules/folder/fixture/test.logging-sinks.tfvars +++ b/tests/modules/folder/fixture/test.logging-sinks.tfvars @@ -1,32 +1,24 @@ logging_sinks = { warning = { - destination = { - type = "storage" - target = "mybucket" - } - filter = "severity=WARNING" + destination = "mybucket" + type = "storage" + filter = "severity=WARNING" } info = { - destination = { - type = "bigquery" - target = "projects/myproject/datasets/mydataset" - } - filter = "severity=INFO" - disabled = true + destination = "projects/myproject/datasets/mydataset" + type = "bigquery" + filter = "severity=INFO" + disabled = true } notice = { - destination = { - type = "pubsub" - target = "projects/myproject/topics/mytopic" - } + destination = "projects/myproject/topics/mytopic" + type = "pubsub" filter = "severity=NOTICE" include_children = false } debug = { - destination = { - type = "logging" - target = "projects/myproject/locations/global/buckets/mybucket" - } + destination = "projects/myproject/locations/global/buckets/mybucket" + type = "logging" filter = "severity=DEBUG" include_children = false exclusions = { diff --git a/tests/modules/organization/fixture/test.logging-sinks.tfvars b/tests/modules/organization/fixture/test.logging-sinks.tfvars index b7dc66876..95a272e1f 100644 --- a/tests/modules/organization/fixture/test.logging-sinks.tfvars +++ b/tests/modules/organization/fixture/test.logging-sinks.tfvars @@ -1,32 +1,24 @@ logging_sinks = { warning = { - destination = { - type = "storage" - target = "mybucket" - } - filter = "severity=WARNING" + destination = "mybucket" + type = "storage" + filter = "severity=WARNING" } info = { - destination = { - type = "bigquery" - target = "projects/myproject/datasets/mydataset" - } - filter = "severity=INFO" - disabled = true + destination = "projects/myproject/datasets/mydataset" + type = "bigquery" + filter = "severity=INFO" + disabled = true } notice = { - destination = { - type = "pubsub" - target = "projects/myproject/topics/mytopic" - } + destination = "projects/myproject/topics/mytopic" + type = "pubsub" filter = "severity=NOTICE" include_children = false } debug = { - destination = { - type = "logging" - target = "projects/myproject/locations/global/buckets/mybucket" - } + destination = "projects/myproject/locations/global/buckets/mybucket" + type = "logging" filter = "severity=DEBUG" include_children = false exclusions = { diff --git a/tests/modules/project/fixture/test.logging-sinks.tfvars b/tests/modules/project/fixture/test.logging-sinks.tfvars index 35f991706..5c79cfb55 100644 --- a/tests/modules/project/fixture/test.logging-sinks.tfvars +++ b/tests/modules/project/fixture/test.logging-sinks.tfvars @@ -1,33 +1,25 @@ logging_sinks = { warning = { - destination = { - type = "storage" - target = "mybucket" - } - filter = "severity=WARNING" + destination = "mybucket" + type = "storage" + filter = "severity=WARNING" } info = { - destination = { - type = "bigquery" - target = "projects/myproject/datasets/mydataset" - } - filter = "severity=INFO" - disabled = true + destination = "projects/myproject/datasets/mydataset" + type = "bigquery" + filter = "severity=INFO" + disabled = true } notice = { - destination = { - type = "pubsub" - target = "projects/myproject/topics/mytopic" - } + destination = "projects/myproject/topics/mytopic" + type = "pubsub" filter = "severity=NOTICE" unique_writer = true } debug = { - destination = { - type = "logging" - target = "projects/myproject/locations/global/buckets/mybucket" - } - filter = "severity=DEBUG" + destination = "projects/myproject/locations/global/buckets/mybucket" + type = "logging" + filter = "severity=DEBUG" exclusions = { no-compute = "logName:compute" no-container = "logName:container"