From a2a9be25932d9773677717c2d18cd0d59459363e Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Thu, 20 Nov 2025 16:12:16 +0100 Subject: [PATCH] dataplex aspect types module refactor (#3544) --- modules/data-catalog-policy-tag/README.md | 12 ++-- modules/data-catalog-policy-tag/iam.tf | 33 +++++++--- modules/data-catalog-policy-tag/main.tf | 20 +++--- modules/data-catalog-policy-tag/variables.tf | 36 ++++++++--- modules/dataplex-aspect-types/README.md | 19 +++--- modules/dataplex-aspect-types/iam.tf | 20 +++--- modules/dataplex-aspect-types/main.tf | 14 ++++- .../schemas/aspect-type.schema.json | 12 ++-- modules/dataplex-aspect-types/variables.tf | 16 ++++- .../data_catalog_policy_tag/context.tfvars | 51 +++++++++++++++ .../data_catalog_policy_tag/context.yaml | 63 +++++++++++++++++++ .../data_catalog_policy_tag/tftest.yaml | 17 +++++ .../dataplex_aspect_types/context.tfvars | 57 +++++++++++++++++ .../dataplex_aspect_types/context.yaml | 52 +++++++++++++++ .../modules/dataplex_aspect_types/tftest.yaml | 17 +++++ 15 files changed, 378 insertions(+), 61 deletions(-) create mode 100644 tests/modules/data_catalog_policy_tag/context.tfvars create mode 100644 tests/modules/data_catalog_policy_tag/context.yaml create mode 100644 tests/modules/data_catalog_policy_tag/tftest.yaml create mode 100644 tests/modules/dataplex_aspect_types/context.tfvars create mode 100644 tests/modules/dataplex_aspect_types/context.yaml create mode 100644 tests/modules/dataplex_aspect_types/tftest.yaml diff --git a/modules/data-catalog-policy-tag/README.md b/modules/data-catalog-policy-tag/README.md index a9906ed63..207ab0aef 100644 --- a/modules/data-catalog-policy-tag/README.md +++ b/modules/data-catalog-policy-tag/README.md @@ -81,17 +81,17 @@ module "cmn-dc" { | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [location](variables.tf#L29) | Data Catalog Taxonomy location. | string | ✓ | | -| [name](variables.tf#L34) | Name of this taxonomy. | string | ✓ | | -| [project_id](variables.tf#L49) | GCP project id. | string | ✓ | | +| [location](variables.tf#L52) | Data Catalog Taxonomy location. | string | ✓ | | +| [name](variables.tf#L58) | Name of this taxonomy. | string | ✓ | | +| [project_id](variables.tf#L64) | GCP project id. | string | ✓ | | | [activated_policy_types](variables.tf#L17) | A list of policy types that are activated for this taxonomy. | list(string) | | ["FINE_GRAINED_ACCESS_CONTROL"] | -| [description](variables.tf#L23) | Description of this taxonomy. | string | | "Taxonomy - Terraform managed" | +| [context](variables.tf#L32) | Context-specific interpolations. | object({…}) | | {} | +| [description](variables.tf#L45) | Description of this taxonomy. | string | | "Taxonomy - Terraform managed" | | [iam](variables-iam.tf#L23) | IAM bindings in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | | [iam_bindings](variables-iam.tf#L29) | Authoritative IAM bindings in {KEY => {role = ROLE, members = [], condition = {}}}. Keys are arbitrary. | map(object({…})) | | {} | | [iam_bindings_additive](variables-iam.tf#L44) | Individual additive IAM bindings. Keys are arbitrary. | map(object({…})) | | {} | | [iam_by_principals](variables-iam.tf#L17) | Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid cycle errors. Merged internally with the `iam` variable. | map(list(string)) | | {} | -| [prefix](variables.tf#L39) | Optional prefix used to generate project id and name. | string | | null | -| [tags](variables.tf#L54) | List of Data Catalog Policy tags to be created with optional IAM binging configuration in {tag => {ROLE => [MEMBERS]}} format. | map(object({…})) | | {} | +| [tags](variables.tf#L70) | List of Data Catalog Policy tags to be created with optional IAM binging configuration in {tag => {ROLE => [MEMBERS]}} format. | map(object({…})) | | {} | ## Outputs diff --git a/modules/data-catalog-policy-tag/iam.tf b/modules/data-catalog-policy-tag/iam.tf index 4abd98a92..ef3fb914a 100644 --- a/modules/data-catalog-policy-tag/iam.tf +++ b/modules/data-catalog-policy-tag/iam.tf @@ -46,20 +46,28 @@ resource "google_data_catalog_taxonomy_iam_binding" "authoritative" { provider = google-beta for_each = local.iam taxonomy = google_data_catalog_taxonomy.default.id - role = each.key - members = each.value + role = lookup(local.ctx.custom_roles, each.key, each.key) + members = [ + for v in each.value : + lookup(local.ctx.iam_principals, v, v) + ] } resource "google_data_catalog_taxonomy_iam_binding" "bindings" { provider = google-beta for_each = var.iam_bindings taxonomy = google_data_catalog_taxonomy.default.id - role = each.value.role - members = each.value.members + role = lookup(local.ctx.custom_roles, each.value.role, each.value.role) + members = [ + for v in each.value.members : + lookup(local.ctx.iam_principals, v, v) + ] dynamic "condition" { for_each = each.value.condition == null ? [] : [""] content { - expression = each.value.condition.expression + expression = templatestring( + each.value.condition.expression, var.context.condition_vars + ) title = each.value.condition.title description = each.value.condition.description } @@ -70,12 +78,14 @@ resource "google_data_catalog_taxonomy_iam_member" "bindings" { provider = google-beta for_each = var.iam_bindings_additive taxonomy = google_data_catalog_taxonomy.default.id - role = each.value.role - member = each.value.member + role = lookup(local.ctx.custom_roles, each.value.role, each.value.role) + member = lookup(local.ctx.iam_principals, each.value.member, each.value.member) dynamic "condition" { for_each = each.value.condition == null ? [] : [""] content { - expression = each.value.condition.expression + expression = templatestring( + each.value.condition.expression, var.context.condition_vars + ) title = each.value.condition.title description = each.value.condition.description } @@ -88,6 +98,9 @@ resource "google_data_catalog_policy_tag_iam_binding" "authoritative" { for v in local.tags_iam : "${v.tag}.${v.role}" => v } policy_tag = google_data_catalog_policy_tag.default[each.value.tag].name - role = each.value.role - members = each.value.members + role = lookup(local.ctx.custom_roles, each.value.role, each.value.role) + members = [ + for v in each.value.members : + lookup(local.ctx.iam_principals, v, v) + ] } diff --git a/modules/data-catalog-policy-tag/main.tf b/modules/data-catalog-policy-tag/main.tf index 0ccd9235f..4b2677ccf 100644 --- a/modules/data-catalog-policy-tag/main.tf +++ b/modules/data-catalog-policy-tag/main.tf @@ -17,24 +17,30 @@ # tfdoc:file:description Data Catalog Taxonomy definition locals { - name = ( - var.name != null ? var.name : "${local.prefix}taxonomy" + ctx = { + for k, v in var.context : k => { + for kk, vv in v : "${local.ctx_p}${k}:${kk}" => vv + } if k != "condition_vars" + } + ctx_p = "$" + location = try(local.ctx.locations[var.location], var.location) + project_id = var.project_id == null ? null : lookup( + local.ctx.project_ids, var.project_id, var.project_id ) - prefix = var.prefix == null ? "" : "${var.prefix}-" } resource "google_data_catalog_taxonomy" "default" { provider = google-beta - project = var.project_id - region = var.location - display_name = local.name + project = local.project_id + region = local.location + display_name = var.name description = var.description activated_policy_types = var.activated_policy_types } resource "google_data_catalog_policy_tag" "default" { - for_each = var.tags provider = google-beta + for_each = var.tags taxonomy = google_data_catalog_taxonomy.default.id display_name = each.key description = coalesce( diff --git a/modules/data-catalog-policy-tag/variables.tf b/modules/data-catalog-policy-tag/variables.tf index c294b086e..51a16de8d 100644 --- a/modules/data-catalog-policy-tag/variables.tf +++ b/modules/data-catalog-policy-tag/variables.tf @@ -17,38 +17,54 @@ variable "activated_policy_types" { description = "A list of policy types that are activated for this taxonomy." type = list(string) + nullable = true default = ["FINE_GRAINED_ACCESS_CONTROL"] + validation { + condition = alltrue([ + for v in coalesce(var.activated_policy_types, []) : contains( + ["FINE_GRAINED_ACCESS_CONTROL", "POLICY_TYPE_UNSPECIFIED"], v + ) + ]) + error_message = "Invalid policy type activation value." + } +} + +variable "context" { + description = "Context-specific interpolations." + type = object({ + condition_vars = optional(map(map(string)), {}) + custom_roles = optional(map(string), {}) + iam_principals = optional(map(string), {}) + locations = optional(map(string), {}) + project_ids = optional(map(string), {}) + }) + default = {} + nullable = false } variable "description" { description = "Description of this taxonomy." type = string + nullable = true default = "Taxonomy - Terraform managed" } variable "location" { description = "Data Catalog Taxonomy location." type = string + nullable = false } variable "name" { description = "Name of this taxonomy." type = string -} - -variable "prefix" { - description = "Optional prefix used to generate project id and name." - type = string - default = null - validation { - condition = var.prefix != "" - error_message = "Prefix cannot be empty, please use null instead." - } + nullable = false } variable "project_id" { description = "GCP project id." type = string + nullable = false } variable "tags" { diff --git a/modules/dataplex-aspect-types/README.md b/modules/dataplex-aspect-types/README.md index 9977282d2..0dc341694 100644 --- a/modules/dataplex-aspect-types/README.md +++ b/modules/dataplex-aspect-types/README.md @@ -75,13 +75,13 @@ IAM attributes can leverage substitutions for principals, which need to be defin module "aspect-types" { source = "./fabric/modules/dataplex-aspect-types" project_id = "test-project" + context = { + iam_principals = { + test-sa = "serviceAccount:sa-0@test-project.iam.gserviceaccount.com" + } + } factories_config = { aspect_types = "data/aspect-types" - context = { - iam_principals = { - test-sa = "serviceAccount:sa-0@test-project.iam.gserviceaccount.com" - } - } } } # tftest modules=1 resources=4 files=aspect-0,aspect-1 @@ -125,7 +125,7 @@ display_name: "Test template 1." iam_bindings_additive: user: role: roles/dataplex.aspectTypeUser - member: test-sa + member: $iam_principals:test-sa metadata_template: | { "name": "tf-test-template-1", @@ -158,10 +158,11 @@ metadata_template: | | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [project_id](variables.tf#L67) | Project id where resources will be created. | string | ✓ | | +| [project_id](variables.tf#L77) | Project id where resources will be created. | string | ✓ | | | [aspect_types](variables.tf#L17) | Aspect templates. Merged with those defined via the factory. | map(object({…})) | | {} | -| [factories_config](variables.tf#L48) | Paths to folders for the optional factories. | object({…}) | | {} | -| [location](variables.tf#L60) | Location for aspect types. | string | | "global" | +| [context](variables.tf#L48) | Context-specific interpolations. | object({…}) | | {} | +| [factories_config](variables.tf#L61) | Paths to folders for the optional factories. | object({…}) | | {} | +| [location](variables.tf#L70) | Location for aspect types. | string | | "global" | ## Outputs diff --git a/modules/dataplex-aspect-types/iam.tf b/modules/dataplex-aspect-types/iam.tf index 2cbfbcb77..32b805319 100644 --- a/modules/dataplex-aspect-types/iam.tf +++ b/modules/dataplex-aspect-types/iam.tf @@ -53,26 +53,28 @@ resource "google_dataplex_aspect_type_iam_binding" "authoritative" { for binding in local.iam : "${binding.aspect_type_id}.${binding.role}" => binding } - role = each.value.role aspect_type_id = google_dataplex_aspect_type.default[each.value.aspect_type_id].id + role = lookup(local.ctx.custom_roles, each.value.role, each.value.role) members = [ for v in each.value.members : - lookup(var.factories_config.context.iam_principals, v, v) + lookup(local.ctx.iam_principals, v, v) ] } resource "google_dataplex_aspect_type_iam_binding" "bindings" { for_each = local.iam_bindings - role = each.value.role aspect_type_id = google_dataplex_aspect_type.default[each.value.aspect_type_id].id + role = lookup(local.ctx.custom_roles, each.value.role, each.value.role) members = [ for v in each.value.members : - lookup(var.factories_config.context.iam_principals, v, v) + lookup(local.ctx.iam_principals, v, v) ] dynamic "condition" { for_each = each.value.condition == null ? [] : [""] content { - expression = each.value.condition.expression + expression = templatestring( + each.value.condition.expression, var.context.condition_vars + ) title = each.value.condition.title description = each.value.condition.description } @@ -82,14 +84,16 @@ resource "google_dataplex_aspect_type_iam_binding" "bindings" { resource "google_dataplex_aspect_type_iam_member" "members" { for_each = local.iam_bindings_additive aspect_type_id = google_dataplex_aspect_type.default[each.value.aspect_type_id].id - role = each.value.role + role = lookup(local.ctx.custom_roles, each.value.role, each.value.role) member = lookup( - var.factories_config.context.iam_principals, each.value.member, each.value.member + local.ctx.iam_principals, each.value.member, each.value.member ) dynamic "condition" { for_each = each.value.condition == null ? [] : [""] content { - expression = each.value.condition.expression + expression = templatestring( + each.value.condition.expression, var.context.condition_vars + ) title = each.value.condition.title description = each.value.condition.description } diff --git a/modules/dataplex-aspect-types/main.tf b/modules/dataplex-aspect-types/main.tf index 1b6df7404..5f2f57097 100644 --- a/modules/dataplex-aspect-types/main.tf +++ b/modules/dataplex-aspect-types/main.tf @@ -37,12 +37,22 @@ locals { metadata_template = lookup(v, "metadata_template", null) } }) + ctx = { + for k, v in var.context : k => { + for kk, vv in v : "${local.ctx_p}${k}:${kk}" => vv + } if k != "condition_vars" + } + ctx_p = "$" + location = try(local.ctx.locations[var.location], var.location) + project_id = var.project_id == null ? null : lookup( + local.ctx.project_ids, var.project_id, var.project_id + ) } resource "google_dataplex_aspect_type" "default" { for_each = local.aspect_types - project = var.project_id - location = var.location + project = local.project_id + location = local.location aspect_type_id = each.key description = each.value.description display_name = each.value.display_name diff --git a/modules/dataplex-aspect-types/schemas/aspect-type.schema.json b/modules/dataplex-aspect-types/schemas/aspect-type.schema.json index 5148fdd9e..f2fbf31c0 100644 --- a/modules/dataplex-aspect-types/schemas/aspect-type.schema.json +++ b/modules/dataplex-aspect-types/schemas/aspect-type.schema.json @@ -31,11 +31,11 @@ "type": "object", "additionalProperties": false, "patternProperties": { - "^roles/": { + "^(?:roles/|\\$custom_roles:)": { "type": "array", "items": { "type": "string", - "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|[a-z])" + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:||\\$iam_principals:[a-z0-9_-]+)" } } } @@ -52,12 +52,12 @@ "type": "array", "items": { "type": "string", - "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|[a-z])" + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:[a-z0-9_-]+)" } }, "role": { "type": "string", - "pattern": "^roles/" + "pattern": "^(?:roles/|\\$custom_roles:)" }, "condition": { "type": "object", @@ -92,11 +92,11 @@ "properties": { "member": { "type": "string", - "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|[a-z])" + "pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:[a-z0-9_-]+)" }, "role": { "type": "string", - "pattern": "^roles/" + "pattern": "^(?:roles/|\\$custom_roles:)" }, "condition": { "type": "object", diff --git a/modules/dataplex-aspect-types/variables.tf b/modules/dataplex-aspect-types/variables.tf index bc52caaaf..4397b8ea7 100644 --- a/modules/dataplex-aspect-types/variables.tf +++ b/modules/dataplex-aspect-types/variables.tf @@ -45,13 +45,23 @@ variable "aspect_types" { default = {} } +variable "context" { + description = "Context-specific interpolations." + type = object({ + condition_vars = optional(map(map(string)), {}) + custom_roles = optional(map(string), {}) + iam_principals = optional(map(string), {}) + locations = optional(map(string), {}) + project_ids = optional(map(string), {}) + }) + default = {} + nullable = false +} + variable "factories_config" { description = "Paths to folders for the optional factories." type = object({ aspect_types = optional(string) - context = optional(object({ - iam_principals = optional(map(string), {}) - }), {}) }) nullable = false default = {} diff --git a/tests/modules/data_catalog_policy_tag/context.tfvars b/tests/modules/data_catalog_policy_tag/context.tfvars new file mode 100644 index 000000000..82e3f9349 --- /dev/null +++ b/tests/modules/data_catalog_policy_tag/context.tfvars @@ -0,0 +1,51 @@ +context = { + condition_vars = { + organization = { + id = 1234567890 + } + } + custom_roles = { + myrole = "organizations/366118655033/roles/myRoleOne" + } + iam_principals = { + mygroup = "group:test-group@example.com" + mysa = "serviceAccount:test@test-project.iam.gserviceaccount.com" + myuser = "user:test-user@example.com" + myuser2 = "user:test-user2@example.com" + } + locations = { + ew8 = "europe-west8" + } + project_ids = { + test = "myproject" + } +} +project_id = "$project_ids:test" +location = "$locations:ew8" +name = "test" +tags = { + low = {} + medium = {} + high = { + iam = { + "roles/datacatalog.categoryFineGrainedReader" = [ + "$iam_principals:mysa" + ] + } + } +} +iam = { + "roles/datacatalog.categoryAdmin" = [ + "$iam_principals:mygroup" + ] +} +iam_bindings_additive = { + am1-admin = { + member = "$iam_principals:myuser" + role = "$custom_roles:myrole" + condition = { + title = "Test" + expression = "resource.matchTag('$${organization.id}/environment', 'development')" + } + } +} diff --git a/tests/modules/data_catalog_policy_tag/context.yaml b/tests/modules/data_catalog_policy_tag/context.yaml new file mode 100644 index 000000000..96b468f40 --- /dev/null +++ b/tests/modules/data_catalog_policy_tag/context.yaml @@ -0,0 +1,63 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +values: + google_data_catalog_policy_tag.default["high"]: + description: high - Terraform managed. + display_name: high + parent_policy_tag: null + timeouts: null + google_data_catalog_policy_tag.default["low"]: + description: low - Terraform managed. + display_name: low + parent_policy_tag: null + timeouts: null + google_data_catalog_policy_tag.default["medium"]: + description: medium - Terraform managed. + display_name: medium + parent_policy_tag: null + timeouts: null + google_data_catalog_policy_tag_iam_binding.authoritative["high.roles/datacatalog.categoryFineGrainedReader"]: + condition: [] + members: + - serviceAccount:test@test-project.iam.gserviceaccount.com + role: roles/datacatalog.categoryFineGrainedReader + google_data_catalog_taxonomy.default: + activated_policy_types: + - FINE_GRAINED_ACCESS_CONTROL + description: Taxonomy - Terraform managed + display_name: test + project: myproject + region: europe-west8 + timeouts: null + google_data_catalog_taxonomy_iam_binding.authoritative["roles/datacatalog.categoryAdmin"]: + condition: [] + members: + - group:test-group@example.com + role: roles/datacatalog.categoryAdmin + google_data_catalog_taxonomy_iam_member.bindings["am1-admin"]: + condition: + - description: null + expression: resource.matchTag('1234567890/environment', 'development') + title: Test + member: user:test-user@example.com + role: organizations/366118655033/roles/myRoleOne +counts: + google_data_catalog_policy_tag: 3 + google_data_catalog_policy_tag_iam_binding: 1 + google_data_catalog_taxonomy: 1 + google_data_catalog_taxonomy_iam_binding: 1 + google_data_catalog_taxonomy_iam_member: 1 + modules: 0 + resources: 7 diff --git a/tests/modules/data_catalog_policy_tag/tftest.yaml b/tests/modules/data_catalog_policy_tag/tftest.yaml new file mode 100644 index 000000000..483e0f4da --- /dev/null +++ b/tests/modules/data_catalog_policy_tag/tftest.yaml @@ -0,0 +1,17 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module: modules/data-catalog-policy-tag +tests: + context: diff --git a/tests/modules/dataplex_aspect_types/context.tfvars b/tests/modules/dataplex_aspect_types/context.tfvars new file mode 100644 index 000000000..59832970d --- /dev/null +++ b/tests/modules/dataplex_aspect_types/context.tfvars @@ -0,0 +1,57 @@ +context = { + condition_vars = { + organization = { + id = 1234567890 + } + } + custom_roles = { + myrole_one = "organizations/366118655033/roles/myRoleOne" + myrole_two = "organizations/366118655033/roles/myRoleTwo" + myrole_three = "organizations/366118655033/roles/myRoleThree" + myrole_four = "organizations/366118655033/roles/myRoleFour" + } + iam_principals = { + mygroup = "group:test-group@example.com" + mysa = "serviceAccount:test@test-project.iam.gserviceaccount.com" + myuser = "user:test-user@example.com" + myuser2 = "user:test-user2@example.com" + } + locations = { + ew8 = "europe-west8" + } + project_ids = { + test = "myproject" + } + tag_values = { + "test/one" = "tagValues/1234567890" + } +} +project_id = "$project_ids:test" +location = "$locations:ew8" +aspect_types = { + tf-test-template = { + display_name = "Test template." + iam = { + "roles/dataplex.aspectTypeOwner" = ["$iam_principals:mygroup"] + } + iam_bindings = { + myrole_two = { + role = "$custom_roles:myrole_two" + members = [ + "$iam_principals:mysa" + ] + condition = { + title = "Test" + expression = "resource.matchTag('$${organization.id}/environment', 'development')" + } + } + } + iam_bindings_additive = { + user = { + role = "roles/dataplex.aspectTypeUser" + member = "$iam_principals:mysa" + } + } + metadata_template = "{}" + } +} diff --git a/tests/modules/dataplex_aspect_types/context.yaml b/tests/modules/dataplex_aspect_types/context.yaml new file mode 100644 index 000000000..3ba54bb52 --- /dev/null +++ b/tests/modules/dataplex_aspect_types/context.yaml @@ -0,0 +1,52 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +values: + google_dataplex_aspect_type.default["tf-test-template"]: + aspect_type_id: tf-test-template + description: null + display_name: Test template. + effective_labels: + goog-terraform-provisioned: 'true' + labels: null + location: europe-west8 + metadata_template: '{}' + project: myproject + terraform_labels: + goog-terraform-provisioned: 'true' + timeouts: null + google_dataplex_aspect_type_iam_binding.authoritative["tf-test-template.roles/dataplex.aspectTypeOwner"]: + condition: [] + members: + - group:test-group@example.com + role: roles/dataplex.aspectTypeOwner + google_dataplex_aspect_type_iam_binding.bindings["myrole_two"]: + condition: + - description: null + expression: resource.matchTag('1234567890/environment', 'development') + title: Test + members: + - serviceAccount:test@test-project.iam.gserviceaccount.com + role: organizations/366118655033/roles/myRoleTwo + google_dataplex_aspect_type_iam_member.members["user"]: + condition: [] + member: serviceAccount:test@test-project.iam.gserviceaccount.com + role: roles/dataplex.aspectTypeUser + +counts: + google_dataplex_aspect_type: 1 + google_dataplex_aspect_type_iam_binding: 2 + google_dataplex_aspect_type_iam_member: 1 + modules: 0 + resources: 4 diff --git a/tests/modules/dataplex_aspect_types/tftest.yaml b/tests/modules/dataplex_aspect_types/tftest.yaml new file mode 100644 index 000000000..39f49922a --- /dev/null +++ b/tests/modules/dataplex_aspect_types/tftest.yaml @@ -0,0 +1,17 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module: modules/dataplex-aspect-types +tests: + context: