diff --git a/modules/compute-vm/README.md b/modules/compute-vm/README.md
index fb1166410..81cbee2c4 100644
--- a/modules/compute-vm/README.md
+++ b/modules/compute-vm/README.md
@@ -301,7 +301,7 @@ module "instance-group" {
| [name](variables.tf#L160) | Instance name. | string | ✓ | |
| [network_interfaces](variables.tf#L174) | Network interfaces configuration. Use self links for Shared VPC, set addresses to null if not needed. | list(object({…})) | ✓ | |
| [project_id](variables.tf#L201) | Project id. | string | ✓ | |
-| [zone](variables.tf#L254) | Compute zone. | string | ✓ | |
+| [zone](variables.tf#L260) | Compute zone. | string | ✓ | |
| [attached_disk_defaults](variables.tf#L17) | Defaults for attached disks options. | object({…}) | | {…} |
| [attached_disks](variables.tf#L32) | Additional disks, if options is null defaults will be used in its place. Source type is one of 'image' (zonal disks in vms and template), 'snapshot' (vm), 'existing', and null. | list(object({…})) | | [] |
| [boot_disk](variables.tf#L58) | Boot disk properties. | object({…}) | | {…} |
@@ -326,7 +326,8 @@ module "instance-group" {
| [service_account_create](variables.tf#L224) | Auto-create service account. | bool | | false |
| [service_account_scopes](variables.tf#L232) | Scopes applied to service account. | list(string) | | [] |
| [shielded_config](variables.tf#L238) | Shielded VM configuration of the instances. | object({…}) | | null |
-| [tags](variables.tf#L248) | Instance tags. | list(string) | | [] |
+| [tag_bindings](variables.tf#L248) | Tag bindings for this instance, in key => tag value id format. | map(string) | | null |
+| [tags](variables.tf#L254) | Instance network tags for firewall rule targets. | list(string) | | [] |
## Outputs
diff --git a/modules/compute-vm/tags.tf b/modules/compute-vm/tags.tf
new file mode 100644
index 000000000..a9001323e
--- /dev/null
+++ b/modules/compute-vm/tags.tf
@@ -0,0 +1,21 @@
+/**
+ * Copyright 2022 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.
+ */
+
+resource "google_tags_tag_binding" "binding" {
+ for_each = var.create_template ? {} : coalesce(var.tag_bindings, {})
+ parent = "//compute.googleapis.com/${google_compute_instance.default.0.id}"
+ tag_value = each.value
+}
diff --git a/modules/compute-vm/variables.tf b/modules/compute-vm/variables.tf
index f82d75b12..653c66daf 100644
--- a/modules/compute-vm/variables.tf
+++ b/modules/compute-vm/variables.tf
@@ -245,8 +245,14 @@ variable "shielded_config" {
default = null
}
+variable "tag_bindings" {
+ description = "Tag bindings for this instance, in key => tag value id format."
+ type = map(string)
+ default = null
+}
+
variable "tags" {
- description = "Instance tags."
+ description = "Instance network tags for firewall rule targets."
type = list(string)
default = []
}
diff --git a/modules/folder/README.md b/modules/folder/README.md
index 11a8c3f7d..4f6898b97 100644
--- a/modules/folder/README.md
+++ b/modules/folder/README.md
@@ -216,6 +216,38 @@ module "folder2" {
# tftest modules=2 resources=6
```
+## Tags
+
+Refer to the [Creating and managing tags](https://cloud.google.com/resource-manager/docs/tags/tags-creating-and-managing) documentation for details on usage.
+
+```hcl
+module "org" {
+ source = "./modules/organization"
+ organization_id = var.organization_id
+ tags = {
+ environment = {
+ description = "Environment specification."
+ iam = null
+ values = {
+ dev = null
+ prod = null
+ }
+ }
+ }
+}
+
+module "folder" {
+ source = "./modules/folder"
+ name = "Test"
+ parent = module.org.organization_id
+ tag_bindings = {
+ env-prod = module.org.tag_values["environment/prod"].id
+ foo = "tagValues/12345678"
+ }
+}
+# tftest modules=2 resources=6
+```
+
@@ -229,6 +261,7 @@ module "folder2" {
| [main.tf](./main.tf) | Module-level locals and resources. | google_essential_contacts_contact · google_folder |
| [organization-policies.tf](./organization-policies.tf) | Folder-level organization policies. | google_folder_organization_policy |
| [outputs.tf](./outputs.tf) | Module outputs. | |
+| [tags.tf](./tags.tf) | None | google_tags_tag_binding |
| [variables.tf](./variables.tf) | Module variables. | |
| [versions.tf](./versions.tf) | Version pins. | |
@@ -250,6 +283,7 @@ module "folder2" {
| [parent](variables.tf#L118) | Parent in folders/folder_id or organizations/org_id format. | string | | null |
| [policy_boolean](variables.tf#L128) | Map of boolean org policies and enforcement value, set value to null for policy restore. | map(bool) | | {} |
| [policy_list](variables.tf#L135) | Map of list org policies, status is true for allow, false for deny, null for restore. Values can only be used for allow or deny. | map(object({…})) | | {} |
+| [tag_bindings](variables.tf#L147) | Tag bindings for this folder, in key => tag value id format. | map(string) | | null |
## Outputs
diff --git a/modules/folder/tags.tf b/modules/folder/tags.tf
new file mode 100644
index 000000000..2cd2f2fd1
--- /dev/null
+++ b/modules/folder/tags.tf
@@ -0,0 +1,21 @@
+/**
+ * Copyright 2022 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.
+ */
+
+resource "google_tags_tag_binding" "binding" {
+ for_each = coalesce(var.tag_bindings, {})
+ parent = "//cloudresourcemanager.googleapis.com/${local.folder.id}"
+ tag_value = each.value
+}
diff --git a/modules/folder/variables.tf b/modules/folder/variables.tf
index 788574111..a3f32e376 100644
--- a/modules/folder/variables.tf
+++ b/modules/folder/variables.tf
@@ -143,3 +143,9 @@ variable "policy_list" {
default = {}
nullable = false
}
+
+variable "tag_bindings" {
+ description = "Tag bindings for this folder, in key => tag value id format."
+ type = map(string)
+ default = null
+}
diff --git a/modules/kms/README.md b/modules/kms/README.md
index 2052c531d..af1f60e96 100644
--- a/modules/kms/README.md
+++ b/modules/kms/README.md
@@ -95,6 +95,7 @@ module "kms" {
| [key_purpose_defaults](variables.tf#L53) | Defaults used for key purpose when not defined at the key level. If purpose is not `ENCRYPT_DECRYPT` (the default), `version_template.algorithm` is required. | object({…}) | | {…} |
| [keyring_create](variables.tf#L78) | Set to false to manage keys and IAM bindings in an existing keyring. | bool | | true |
| [keys](variables.tf#L84) | Key names and base attributes. Set attributes to null if not needed. | map(object({…})) | | {} |
+| [tag_bindings](variables.tf#L98) | Tag bindings for this keyring, in key => tag value id format. | map(string) | | null |
## Outputs
diff --git a/modules/kms/tags.tf b/modules/kms/tags.tf
new file mode 100644
index 000000000..894c28aa3
--- /dev/null
+++ b/modules/kms/tags.tf
@@ -0,0 +1,21 @@
+/**
+ * Copyright 2022 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.
+ */
+
+resource "google_tags_tag_binding" "binding" {
+ for_each = coalesce(var.tag_bindings, {})
+ parent = "//cloudresourcemanager.googleapis.com/${local.keyring.id}"
+ tag_value = each.value
+}
diff --git a/modules/kms/variables.tf b/modules/kms/variables.tf
index 191f3846d..f5f0fb1b3 100644
--- a/modules/kms/variables.tf
+++ b/modules/kms/variables.tf
@@ -94,3 +94,9 @@ variable "project_id" {
description = "Project id where the keyring will be created."
type = string
}
+
+variable "tag_bindings" {
+ description = "Tag bindings for this keyring, in key => tag value id format."
+ type = map(string)
+ default = null
+}
diff --git a/modules/organization/README.md b/modules/organization/README.md
index a7f79d7b9..7aee01518 100644
--- a/modules/organization/README.md
+++ b/modules/organization/README.md
@@ -220,6 +220,7 @@ module "org" {
```
## Custom Roles
+
```hcl
module "org" {
source = "./modules/organization"
@@ -236,6 +237,39 @@ module "org" {
# tftest modules=1 resources=2
```
+## Tags
+
+Refer to the [Creating and managing tags](https://cloud.google.com/resource-manager/docs/tags/tags-creating-and-managing) documentation for details on usage.
+
+```hcl
+module "org" {
+ source = "./modules/organization"
+ organization_id = var.organization_id
+ tags = {
+ environment = {
+ description = "Environment specification."
+ iam = {
+ "roles/resourcemanager.tagAdmin" = ["group:admins@example.com"]
+ }
+ values = {
+ dev = null
+ prod = {
+ description = "Environment: production."
+ iam = {
+ "roles/resourcemanager.tagViewer" = ["user:user1@example.com"]
+ }
+ }
+ }
+ }
+ }
+ tag_bindings = {
+ env-prod = module.org.tag_values["environment/prod"].id
+ foo = "tagValues/12345678"
+ }
+}
+# tftest modules=1 resources=7
+```
+
@@ -249,6 +283,7 @@ module "org" {
| [main.tf](./main.tf) | Module-level locals and resources. | google_essential_contacts_contact |
| [organization-policies.tf](./organization-policies.tf) | Organization-level organization policies. | google_organization_policy |
| [outputs.tf](./outputs.tf) | Module outputs. | |
+| [tags.tf](./tags.tf) | None | google_tags_tag_binding · google_tags_tag_key · google_tags_tag_key_iam_binding · google_tags_tag_value · google_tags_tag_value_iam_binding |
| [variables.tf](./variables.tf) | Module variables. | |
| [versions.tf](./versions.tf) | Version pins. | |
@@ -273,6 +308,8 @@ module "org" {
| [logging_sinks](variables.tf#L129) | Logging sinks to create for this organization. | map(object({…})) | | {} |
| [policy_boolean](variables.tf#L160) | Map of boolean org policies and enforcement value, set value to null for policy restore. | map(bool) | | {} |
| [policy_list](variables.tf#L167) | Map of list org policies, status is true for allow, false for deny, null for restore. Values can only be used for allow or deny. | map(object({…})) | | {} |
+| [tag_bindings](variables.tf#L179) | Tag bindings for this organization, in key => tag value id format. | map(string) | | null |
+| [tags](variables.tf#L185) | Tags by key name. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | null |
## Outputs
@@ -283,6 +320,8 @@ module "org" {
| [firewall_policies](outputs.tf#L36) | Map of firewall policy resources created in the organization. | |
| [firewall_policy_id](outputs.tf#L41) | Map of firewall policy ids created in the organization. | |
| [organization_id](outputs.tf#L46) | Organization id dependent on module resources. | |
-| [sink_writer_identities](outputs.tf#L60) | Writer identities created for each sink. | |
+| [sink_writer_identities](outputs.tf#L64) | Writer identities created for each sink. | |
+| [tag_keys](outputs.tf#L72) | Tag key resources. | |
+| [tag_values](outputs.tf#L79) | Tag value resources. | |
diff --git a/modules/organization/outputs.tf b/modules/organization/outputs.tf
index c1f501d8f..1679a1d70 100644
--- a/modules/organization/outputs.tf
+++ b/modules/organization/outputs.tf
@@ -53,13 +53,32 @@ output "organization_id" {
google_organization_iam_member.additive,
google_organization_iam_policy.authoritative,
google_organization_policy.boolean,
- google_organization_policy.list
+ google_organization_policy.list,
+ google_tags_tag_key.default,
+ google_tags_tag_key_iam_binding.default,
+ google_tags_tag_value.default,
+ google_tags_tag_value_iam_binding.default,
]
}
output "sink_writer_identities" {
description = "Writer identities created for each sink."
value = {
- for name, sink in google_logging_organization_sink.sink : name => sink.writer_identity
+ for name, sink in google_logging_organization_sink.sink :
+ name => sink.writer_identity
+ }
+}
+
+output "tag_keys" {
+ description = "Tag key resources."
+ value = {
+ for k, v in google_tags_tag_key.default : k => v
+ }
+}
+
+output "tag_values" {
+ description = "Tag value resources."
+ value = {
+ for k, v in google_tags_tag_value.default : k => v
}
}
diff --git a/modules/organization/tags.tf b/modules/organization/tags.tf
new file mode 100644
index 000000000..7aa94cd1b
--- /dev/null
+++ b/modules/organization/tags.tf
@@ -0,0 +1,121 @@
+/**
+ * Copyright 2022 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.
+ */
+
+locals {
+ _tag_values = flatten([
+ for tag, attrs in local.tags : [
+ for value, value_attrs in coalesce(attrs.values, {}) : {
+ description = coalesce(
+ value_attrs == null ? null : value_attrs.description,
+ "Managed by the Terraform organization module."
+ )
+ key = "${tag}/${value}"
+ name = value
+ roles = keys(coalesce(
+ value_attrs == null ? null : value_attrs.iam, {}
+ ))
+ tag = tag
+ }
+ ]
+ ])
+ _tag_values_iam = flatten([
+ for key, value_attrs in local.tag_values : [
+ for role in value_attrs.roles : {
+ key = value_attrs.key
+ name = value_attrs.name
+ role = role
+ tag = value_attrs.tag
+ }
+ ]
+ ])
+ _tags_iam = flatten([
+ for tag, attrs in local.tags : [
+ for role in keys(coalesce(attrs.iam, {})) : {
+ role = role
+ tag = tag
+ }
+ ]
+ ])
+ tag_values = {
+ for t in local._tag_values : t.key => t
+ }
+ tag_values_iam = {
+ for t in local._tag_values_iam : "${t.key}:${t.role}" => t
+ }
+ tags = {
+ for k, v in coalesce(var.tags, {}) :
+ k => v == null ? { description = null, iam = {}, values = null } : v
+ }
+ tags_iam = {
+ for t in local._tags_iam : "${t.tag}:${t.role}" => t
+ }
+}
+
+# keys
+
+resource "google_tags_tag_key" "default" {
+ for_each = local.tags
+ parent = var.organization_id
+ short_name = each.key
+ description = coalesce(
+ each.value.description,
+ "Managed by the Terraform organization module."
+ )
+ depends_on = [
+ google_organization_iam_binding.authoritative,
+ google_organization_iam_member.additive,
+ google_organization_iam_policy.authoritative,
+ ]
+}
+
+resource "google_tags_tag_key_iam_binding" "default" {
+ for_each = local.tags_iam
+ tag_key = google_tags_tag_key.default[each.value.tag].id
+ role = each.value.role
+ members = coalesce(
+ local.tags[each.value.tag]["iam"][each.value.role], []
+ )
+}
+
+# values
+
+resource "google_tags_tag_value" "default" {
+ for_each = local.tag_values
+ parent = google_tags_tag_key.default[each.value.tag].id
+ short_name = each.value.name
+ description = coalesce(
+ each.value.description,
+ "Managed by the Terraform organization module."
+ )
+}
+
+resource "google_tags_tag_value_iam_binding" "default" {
+ for_each = local.tag_values_iam
+ tag_value = google_tags_tag_value.default[each.value.key].id
+ role = each.value.role
+ members = coalesce(
+ local.tags[each.value.tag]["values"][each.value.name]["iam"][each.value.role],
+ []
+ )
+}
+
+# bindings
+
+resource "google_tags_tag_binding" "binding" {
+ for_each = coalesce(var.tag_bindings, {})
+ parent = "//cloudresourcemanager.googleapis.com/${var.organization_id}"
+ tag_value = each.value
+}
diff --git a/modules/organization/variables.tf b/modules/organization/variables.tf
index 1ed117cfb..9ffce95ce 100644
--- a/modules/organization/variables.tf
+++ b/modules/organization/variables.tf
@@ -175,3 +175,22 @@ variable "policy_list" {
default = {}
nullable = false
}
+
+variable "tag_bindings" {
+ description = "Tag bindings for this organization, in key => tag value id format."
+ type = map(string)
+ default = null
+}
+
+variable "tags" {
+ description = "Tags by key name. The `iam` attribute behaves like the similarly named one at module level."
+ type = map(object({
+ description = string
+ iam = map(list(string))
+ values = map(object({
+ description = string
+ iam = map(list(string))
+ }))
+ }))
+ default = null
+}
diff --git a/modules/project/README.md b/modules/project/README.md
index 864b6c264..e4f213912 100644
--- a/modules/project/README.md
+++ b/modules/project/README.md
@@ -207,6 +207,37 @@ module "project" {
# tftest modules=1 resources=7
```
+## Tags
+
+Refer to the [Creating and managing tags](https://cloud.google.com/resource-manager/docs/tags/tags-creating-and-managing) documentation for details on usage.
+
+```hcl
+module "org" {
+ source = "./modules/organization"
+ organization_id = var.organization_id
+ tags = {
+ environment = {
+ description = "Environment specification."
+ iam = null
+ values = {
+ dev = null
+ prod = null
+ }
+ }
+ }
+}
+
+module "project" {
+ source = "./modules/project"
+ name = "test-project"
+ tag_bindings = {
+ env-prod = module.org.tag_values["environment/prod"].id
+ foo = "tagValues/12345678"
+ }
+}
+# tftest modules=2 resources=6
+```
+
@@ -221,6 +252,7 @@ module "project" {
| [outputs.tf](./outputs.tf) | Module outputs. | |
| [service-accounts.tf](./service-accounts.tf) | Service identities and supporting resources. | google_kms_crypto_key_iam_member · google_project_service_identity |
| [shared-vpc.tf](./shared-vpc.tf) | Shared VPC project-level configuration. | google_compute_shared_vpc_host_project · google_compute_shared_vpc_service_project · google_project_iam_member |
+| [tags.tf](./tags.tf) | None | google_tags_tag_binding |
| [variables.tf](./variables.tf) | Module variables. | |
| [versions.tf](./versions.tf) | Version pins. | |
| [vpc-sc.tf](./vpc-sc.tf) | VPC-SC project-level perimeter configuration. | google_access_context_manager_service_perimeter_resource |
@@ -260,6 +292,7 @@ module "project" {
| [shared_vpc_host_config](variables.tf#L230) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | object({…}) | | null |
| [shared_vpc_service_config](variables.tf#L239) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | object({…}) | | null |
| [skip_delete](variables.tf#L249) | Allows the underlying resources to be destroyed without destroying the project itself. | bool | | false |
+| [tag_bindings](variables.tf#L255) | Tag bindings for this project, in key => tag value id format. | map(string) | | null |
## Outputs
diff --git a/modules/project/tags.tf b/modules/project/tags.tf
new file mode 100644
index 000000000..683143bda
--- /dev/null
+++ b/modules/project/tags.tf
@@ -0,0 +1,21 @@
+/**
+ * Copyright 2022 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.
+ */
+
+resource "google_tags_tag_binding" "binding" {
+ for_each = coalesce(var.tag_bindings, {})
+ parent = "//cloudresourcemanager.googleapis.com/projects/${local.project.number}"
+ tag_value = each.value
+}
diff --git a/modules/project/variables.tf b/modules/project/variables.tf
index 7aa291f5c..578f9d230 100644
--- a/modules/project/variables.tf
+++ b/modules/project/variables.tf
@@ -251,3 +251,9 @@ variable "skip_delete" {
type = bool
default = false
}
+
+variable "tag_bindings" {
+ description = "Tag bindings for this project, in key => tag value id format."
+ type = map(string)
+ default = null
+}
diff --git a/tests/modules/organization/fixture/main.tf b/tests/modules/organization/fixture/main.tf
index 3a57a7900..04ae4adf0 100644
--- a/tests/modules/organization/fixture/main.tf
+++ b/tests/modules/organization/fixture/main.tf
@@ -18,16 +18,18 @@ module "test" {
source = "../../../../modules/organization"
organization_id = "organizations/1234567890"
custom_roles = var.custom_roles
+ firewall_policies = var.firewall_policies
+ firewall_policy_association = var.firewall_policy_association
+ firewall_policy_factory = var.firewall_policy_factory
group_iam = var.group_iam
iam = var.iam
iam_additive = var.iam_additive
iam_additive_members = var.iam_additive_members
iam_audit_config = var.iam_audit_config
- policy_boolean = var.policy_boolean
- policy_list = var.policy_list
- firewall_policies = var.firewall_policies
- firewall_policy_association = var.firewall_policy_association
- firewall_policy_factory = var.firewall_policy_factory
logging_sinks = var.logging_sinks
logging_exclusions = var.logging_exclusions
+ policy_boolean = var.policy_boolean
+ policy_list = var.policy_list
+ tag_bindings = var.tag_bindings
+ tags = var.tags
}
diff --git a/tests/modules/organization/fixture/variables.tf b/tests/modules/organization/fixture/variables.tf
index 6881f15e8..1d7ca88d7 100644
--- a/tests/modules/organization/fixture/variables.tf
+++ b/tests/modules/organization/fixture/variables.tf
@@ -15,89 +15,62 @@
*/
variable "custom_roles" {
- type = map(list(string))
+ type = any
default = {}
}
variable "group_iam" {
- type = map(list(string))
+ type = any
default = {}
}
variable "iam" {
- type = map(list(string))
+ type = any
default = {}
}
variable "iam_additive" {
- type = map(list(string))
+ type = any
default = {}
}
variable "iam_additive_members" {
- type = map(list(string))
+ type = any
default = {}
}
variable "iam_audit_config" {
- type = map(map(list(string)))
+ type = any
default = {}
}
variable "policy_boolean" {
- type = map(bool)
+ type = any
default = {}
}
variable "policy_list" {
- type = map(object({
- inherit_from_parent = bool
- suggested_value = string
- status = bool
- values = list(string)
- }))
+ type = any
default = {}
}
variable "firewall_policies" {
- type = map(map(object({
- description = string
- direction = string
- action = string
- priority = number
- ranges = list(string)
- ports = map(list(string))
- target_service_accounts = list(string)
- target_resources = list(string)
- logging = bool
- })))
+ type = any
default = {}
}
variable "firewall_policy_association" {
- type = map(string)
+ type = any
default = {}
}
variable "firewall_policy_factory" {
- type = object({
- cidr_file = string
- policy_name = string
- rules_file = string
- })
+ type = any
default = null
}
variable "logging_sinks" {
- type = map(object({
- destination = string
- type = string
- filter = string
- iam = bool
- include_children = bool
- bq_partitioned_table = bool
- exclusions = map(string)
- }))
+ type = any
default = {}
}
@@ -105,3 +78,13 @@ variable "logging_exclusions" {
type = map(string)
default = {}
}
+
+variable "tag_bindings" {
+ type = any
+ default = null
+}
+
+variable "tags" {
+ type = any
+ default = null
+}
diff --git a/tests/modules/organization/test_plan_tags.py b/tests/modules/organization/test_plan_tags.py
new file mode 100644
index 000000000..849502f4c
--- /dev/null
+++ b/tests/modules/organization/test_plan_tags.py
@@ -0,0 +1,77 @@
+# Copyright 2022 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.
+
+
+def test_keys(plan_runner):
+ 'Test tag keys.'
+ tags = '''{
+ foo = null
+ bar = {
+ description = null
+ iam = null
+ values = null
+ }
+ foobar = {
+ description = "Foobar tag."
+ iam = {
+ "roles/resourcemanager.tagAdmin" = [
+ "user:user1@example.com", "user:user2@example.com"
+ ]
+ }
+ values = {
+ one = null
+ two = {
+ description = "Foobar 2."
+ iam = {
+ "roles/resourcemanager.tagViewer" = [
+ "user:user3@example.com"
+ ]
+ }
+ }
+ three = {
+ description = "Foobar 3."
+ iam = {
+ "roles/resourcemanager.tagViewer" = [
+ "user:user3@example.com"
+ ]
+ "roles/resourcemanager.tagAdmin" = [
+ "user:user4@example.com"
+ ]
+ }
+ }
+ }
+ }
+ }'''
+ _, resources = plan_runner(tags=tags)
+ assert len(resources) == 10
+ resource_values = {}
+ for r in resources:
+ resource_values.setdefault(r['type'], []).append(r['values'])
+ assert len(resource_values['google_tags_tag_key']) == 3
+ assert len(resource_values['google_tags_tag_value']) == 3
+ result = [
+ r['role'] for r in resource_values['google_tags_tag_value_iam_binding']
+ ]
+ expected = [
+ 'roles/resourcemanager.tagAdmin', 'roles/resourcemanager.tagViewer',
+ 'roles/resourcemanager.tagViewer'
+ ]
+ assert result == expected
+
+
+def test_bindings(plan_runner):
+ 'Test tag bindings.'
+ tag_bindings = '{foo = "tagValues/123456789012"}'
+ _, resources = plan_runner(tag_bindings=tag_bindings)
+ assert len(resources) == 1