Avoid tag binding permadiffs for project-factory service accounts (#4006)
* Avoid tag binding permadiffs for service accounts created by project-factory * Regenerate schema docs
This commit is contained in:
@@ -165,6 +165,9 @@
|
||||
},
|
||||
"iam_storage_roles": {
|
||||
"$ref": "#/$defs/iam_storage_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
- **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))*
|
||||
- **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))*
|
||||
- **iam_storage_roles**: *reference([iam_storage_roles](#refs-iam_storage_roles))*
|
||||
- **tag_bindings**: *reference([tag_bindings](#refs-tag_bindings))*
|
||||
- **autokey_config**: *object*
|
||||
<br>*additional properties: false*
|
||||
- **project**: *string*
|
||||
|
||||
@@ -146,6 +146,9 @@
|
||||
},
|
||||
"iam_storage_roles": {
|
||||
"$ref": "#/$defs/iam_storage_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
- **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))*
|
||||
- **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))*
|
||||
- **iam_storage_roles**: *reference([iam_storage_roles](#refs-iam_storage_roles))*
|
||||
- **tag_bindings**: *reference([tag_bindings](#refs-tag_bindings))*
|
||||
- **billing_account**: *string*
|
||||
- **billing_budgets**: *array*
|
||||
- items: *string*
|
||||
|
||||
@@ -165,6 +165,9 @@
|
||||
},
|
||||
"iam_storage_roles": {
|
||||
"$ref": "#/$defs/iam_storage_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
- **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))*
|
||||
- **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))*
|
||||
- **iam_storage_roles**: *reference([iam_storage_roles](#refs-iam_storage_roles))*
|
||||
- **tag_bindings**: *reference([tag_bindings](#refs-tag_bindings))*
|
||||
- **autokey_config**: *object*
|
||||
<br>*additional properties: false*
|
||||
- **project**: *string*
|
||||
|
||||
@@ -146,6 +146,9 @@
|
||||
},
|
||||
"iam_storage_roles": {
|
||||
"$ref": "#/$defs/iam_storage_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
- **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))*
|
||||
- **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))*
|
||||
- **iam_storage_roles**: *reference([iam_storage_roles](#refs-iam_storage_roles))*
|
||||
- **tag_bindings**: *reference([tag_bindings](#refs-tag_bindings))*
|
||||
- **billing_account**: *string*
|
||||
- **billing_budgets**: *array*
|
||||
- items: *string*
|
||||
|
||||
@@ -165,6 +165,9 @@
|
||||
},
|
||||
"iam_storage_roles": {
|
||||
"$ref": "#/$defs/iam_storage_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
- **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))*
|
||||
- **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))*
|
||||
- **iam_storage_roles**: *reference([iam_storage_roles](#refs-iam_storage_roles))*
|
||||
- **tag_bindings**: *reference([tag_bindings](#refs-tag_bindings))*
|
||||
- **autokey_config**: *object*
|
||||
<br>*additional properties: false*
|
||||
- **project**: *string*
|
||||
|
||||
@@ -146,6 +146,9 @@
|
||||
},
|
||||
"iam_storage_roles": {
|
||||
"$ref": "#/$defs/iam_storage_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
- **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))*
|
||||
- **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))*
|
||||
- **iam_storage_roles**: *reference([iam_storage_roles](#refs-iam_storage_roles))*
|
||||
- **tag_bindings**: *reference([tag_bindings](#refs-tag_bindings))*
|
||||
- **billing_account**: *string*
|
||||
- **billing_budgets**: *array*
|
||||
- items: *string*
|
||||
|
||||
@@ -165,6 +165,9 @@
|
||||
},
|
||||
"iam_storage_roles": {
|
||||
"$ref": "#/$defs/iam_storage_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
- **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))*
|
||||
- **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))*
|
||||
- **iam_storage_roles**: *reference([iam_storage_roles](#refs-iam_storage_roles))*
|
||||
- **tag_bindings**: *reference([tag_bindings](#refs-tag_bindings))*
|
||||
- **autokey_config**: *object*
|
||||
<br>*additional properties: false*
|
||||
- **project**: *string*
|
||||
|
||||
@@ -146,6 +146,9 @@
|
||||
},
|
||||
"iam_storage_roles": {
|
||||
"$ref": "#/$defs/iam_storage_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
- **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))*
|
||||
- **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))*
|
||||
- **iam_storage_roles**: *reference([iam_storage_roles](#refs-iam_storage_roles))*
|
||||
- **tag_bindings**: *reference([tag_bindings](#refs-tag_bindings))*
|
||||
- **billing_account**: *string*
|
||||
- **billing_budgets**: *array*
|
||||
- items: *string*
|
||||
|
||||
@@ -101,6 +101,6 @@ resource "google_service_account" "service_account" {
|
||||
|
||||
resource "google_tags_tag_binding" "binding" {
|
||||
for_each = local.tag_bindings
|
||||
parent = "//iam.googleapis.com/projects/${coalesce(var.project_number, var.project_id)}/serviceAccounts/${local.service_account.unique_id}"
|
||||
parent = "//iam.googleapis.com/projects/${coalesce(var.project_number, local.project_id)}/serviceAccounts/${local.service_account.unique_id}"
|
||||
tag_value = templatestring(local._tag_bindings[each.key], var.context.tag_vars)
|
||||
}
|
||||
|
||||
@@ -968,7 +968,7 @@ module "project-factory" {
|
||||
basepath = "data"
|
||||
}
|
||||
}
|
||||
# tftest modules=7 resources=31 files=test-0,test-1,test-2 inventory=test-1.yaml
|
||||
# tftest modules=10 resources=36 files=test-0,test-1,test-2 inventory=test-1.yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
@@ -995,6 +995,16 @@ tags:
|
||||
roles/resourcemanager.tagUser:
|
||||
- $iam_principals:tag-test
|
||||
- $iam_principals:service_accounts/test-1/tag-test
|
||||
service_accounts:
|
||||
tag-test:
|
||||
tag_bindings:
|
||||
project-level: $tag_values:test-0/context/project-factory
|
||||
automation:
|
||||
project: test-0
|
||||
service_accounts:
|
||||
auto-tag-test:
|
||||
tag_bindings:
|
||||
project-level: $tag_values:test-0/context/project-factory
|
||||
# tftest-file id=test-0 path=data/projects/test-0.yaml
|
||||
```
|
||||
|
||||
|
||||
@@ -126,9 +126,18 @@ module "automation-bucket" {
|
||||
}
|
||||
|
||||
module "automation-service-accounts" {
|
||||
source = "../iam-service-account"
|
||||
for_each = local.automation_sas
|
||||
project_id = each.value.automation_project
|
||||
source = "../iam-service-account"
|
||||
for_each = local.automation_sas
|
||||
project_id = each.value.automation_project
|
||||
project_number = (
|
||||
each.value.automation_project == null
|
||||
? null
|
||||
: lookup(
|
||||
local.ctx_project_numbers,
|
||||
trimprefix(each.value.automation_project, "$project_ids:"),
|
||||
null
|
||||
)
|
||||
)
|
||||
prefix = each.value.prefix
|
||||
name = each.value.name
|
||||
description = lookup(each.value, "description", null)
|
||||
@@ -143,6 +152,11 @@ module "automation-service-accounts" {
|
||||
local.ctx.iam_principals,
|
||||
local.projects_sas_iam_emails
|
||||
)
|
||||
tag_vars = {
|
||||
projects = merge(try(local.ctx.tag_vars.projects, {}), local.tag_vars_projects)
|
||||
organization = try(local.ctx.tag_vars.organization, {})
|
||||
}
|
||||
tag_values = local.ctx_tag_values
|
||||
})
|
||||
iam = lookup(each.value, "iam", {})
|
||||
iam_bindings = lookup(each.value, "iam_bindings", {})
|
||||
@@ -154,6 +168,7 @@ module "automation-service-accounts" {
|
||||
# iam_sa_roles = lookup(each.value, "iam_sa_roles", {})
|
||||
# we don't interpolate buckets here as we can't use a dynamic key
|
||||
iam_storage_roles = lookup(each.value, "iam_storage_roles", {})
|
||||
tag_bindings = lookup(each.value, "tag_bindings", {})
|
||||
}
|
||||
|
||||
module "automation-service-accounts-iam" {
|
||||
|
||||
@@ -80,10 +80,11 @@ module "service-accounts" {
|
||||
for k in local.projects_service_accounts :
|
||||
"${k.project_key}/${k.name}" => k
|
||||
}
|
||||
project_id = module.projects[each.value.project_key].project_id
|
||||
name = each.value.name
|
||||
description = each.value.description
|
||||
display_name = each.value.display_name
|
||||
project_id = module.projects[each.value.project_key].project_id
|
||||
project_number = module.projects[each.value.project_key].number
|
||||
name = each.value.name
|
||||
description = each.value.description
|
||||
display_name = each.value.display_name
|
||||
context = merge(local.ctx, {
|
||||
tag_vars = {
|
||||
projects = merge(try(local.ctx.tag_vars.projects, {}), local.tag_vars_projects)
|
||||
|
||||
@@ -165,6 +165,9 @@
|
||||
},
|
||||
"iam_storage_roles": {
|
||||
"$ref": "#/$defs/iam_storage_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
- **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))*
|
||||
- **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))*
|
||||
- **iam_storage_roles**: *reference([iam_storage_roles](#refs-iam_storage_roles))*
|
||||
- **tag_bindings**: *reference([tag_bindings](#refs-tag_bindings))*
|
||||
- **autokey_config**: *object*
|
||||
<br>*additional properties: false*
|
||||
- **project**: *string*
|
||||
|
||||
@@ -146,6 +146,9 @@
|
||||
},
|
||||
"iam_storage_roles": {
|
||||
"$ref": "#/$defs/iam_storage_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
- **iam_project_roles**: *reference([iam_project_roles](#refs-iam_project_roles))*
|
||||
- **iam_sa_roles**: *reference([iam_sa_roles](#refs-iam_sa_roles))*
|
||||
- **iam_storage_roles**: *reference([iam_storage_roles](#refs-iam_storage_roles))*
|
||||
- **tag_bindings**: *reference([tag_bindings](#refs-tag_bindings))*
|
||||
- **billing_account**: *string*
|
||||
- **billing_budgets**: *array*
|
||||
- items: *string*
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Copyright 2025 Google LLC
|
||||
# Copyright 2026 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
|
||||
# https://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,
|
||||
@@ -13,6 +13,47 @@
|
||||
# limitations under the License.
|
||||
|
||||
values:
|
||||
module.project-factory.module.automation-bucket["test-0/automation/tf-state"].google_storage_bucket.bucket[0]:
|
||||
autoclass: []
|
||||
cors: []
|
||||
custom_placement_config: []
|
||||
default_event_based_hold: null
|
||||
deletion_policy: DELETE
|
||||
effective_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
enable_object_retention: null
|
||||
encryption: []
|
||||
force_destroy: false
|
||||
hierarchical_namespace: []
|
||||
ip_filter: []
|
||||
labels: null
|
||||
lifecycle_rule: []
|
||||
location: EU
|
||||
logging: []
|
||||
name: foo-test-0-tf-state
|
||||
project: test-0
|
||||
requester_pays: null
|
||||
retention_policy: []
|
||||
storage_class: STANDARD
|
||||
terraform_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
timeouts: null
|
||||
uniform_bucket_level_access: true
|
||||
versioning:
|
||||
- enabled: false
|
||||
? module.project-factory.module.automation-service-accounts["test-0/automation/auto-tag-test"].google_service_account.service_account[0]
|
||||
: account_id: test-0-auto-tag-test
|
||||
create_ignore_already_exists: null
|
||||
deletion_policy: DELETE
|
||||
description: null
|
||||
disabled: false
|
||||
display_name: Service account auto-tag-test for test-0.
|
||||
email: test-0-auto-tag-test@test-0.iam.gserviceaccount.com
|
||||
member: serviceAccount:test-0-auto-tag-test@test-0.iam.gserviceaccount.com
|
||||
project: test-0
|
||||
timeouts: null
|
||||
? module.project-factory.module.automation-service-accounts["test-0/automation/auto-tag-test"].google_tags_tag_binding.binding["project-level"]
|
||||
: timeouts: null
|
||||
module.project-factory.module.projects-iam["test-0"].google_project_iam_member.bindings["test_context"]:
|
||||
condition:
|
||||
- description: null
|
||||
@@ -31,8 +72,6 @@ values:
|
||||
tag_value: tagValues/1234567890
|
||||
timeouts: null
|
||||
module.project-factory.module.projects-iam["test-1"].google_tags_tag_binding.binding["project-level"]:
|
||||
# tag_value is undefined at plan time as it depends on the tag
|
||||
# tag_value: $tag_values:test-0/context/project-factory
|
||||
timeouts: null
|
||||
module.project-factory.module.projects["test-0"].google_project.project[0]:
|
||||
auto_create_network: false
|
||||
@@ -65,24 +104,28 @@ values:
|
||||
project: foo-test-0
|
||||
role: roles/container.defaultNodeServiceAgent
|
||||
module.project-factory.module.projects["test-0"].google_project_service.project_services["compute.googleapis.com"]:
|
||||
deletion_policy: DELETE
|
||||
disable_dependent_services: false
|
||||
disable_on_destroy: false
|
||||
project: foo-test-0
|
||||
service: compute.googleapis.com
|
||||
timeouts: null
|
||||
? module.project-factory.module.projects["test-0"].google_project_service.project_services["contactcenteraiplatform.googleapis.com"]
|
||||
: disable_dependent_services: false
|
||||
: deletion_policy: DELETE
|
||||
disable_dependent_services: false
|
||||
disable_on_destroy: false
|
||||
project: foo-test-0
|
||||
service: contactcenteraiplatform.googleapis.com
|
||||
timeouts: null
|
||||
module.project-factory.module.projects["test-0"].google_project_service.project_services["container.googleapis.com"]:
|
||||
deletion_policy: DELETE
|
||||
disable_dependent_services: false
|
||||
disable_on_destroy: false
|
||||
project: foo-test-0
|
||||
service: container.googleapis.com
|
||||
timeouts: null
|
||||
module.project-factory.module.projects["test-0"].google_project_service.project_services["iam.googleapis.com"]:
|
||||
deletion_policy: DELETE
|
||||
disable_dependent_services: false
|
||||
disable_on_destroy: false
|
||||
project: foo-test-0
|
||||
@@ -131,18 +174,21 @@ values:
|
||||
project: test-1
|
||||
role: roles/compute.serviceAgent
|
||||
module.project-factory.module.projects["test-1"].google_project_service.project_services["compute.googleapis.com"]:
|
||||
deletion_policy: DELETE
|
||||
disable_dependent_services: false
|
||||
disable_on_destroy: false
|
||||
project: test-1
|
||||
service: compute.googleapis.com
|
||||
timeouts: null
|
||||
? module.project-factory.module.projects["test-1"].google_project_service.project_services["contactcenteraiplatform.googleapis.com"]
|
||||
: disable_dependent_services: false
|
||||
: deletion_policy: DELETE
|
||||
disable_dependent_services: false
|
||||
disable_on_destroy: false
|
||||
project: test-1
|
||||
service: contactcenteraiplatform.googleapis.com
|
||||
timeouts: null
|
||||
module.project-factory.module.projects["test-1"].google_project_service.project_services["iam.googleapis.com"]:
|
||||
deletion_policy: DELETE
|
||||
disable_dependent_services: false
|
||||
disable_on_destroy: false
|
||||
project: test-1
|
||||
@@ -178,26 +224,43 @@ values:
|
||||
project: bar-test-2
|
||||
role: roles/compute.serviceAgent
|
||||
module.project-factory.module.projects["test-2"].google_project_service.project_services["compute.googleapis.com"]:
|
||||
deletion_policy: DELETE
|
||||
disable_dependent_services: false
|
||||
disable_on_destroy: false
|
||||
project: bar-test-2
|
||||
service: compute.googleapis.com
|
||||
timeouts: null
|
||||
module.project-factory.module.projects["test-2"].google_project_service.project_services["iam.googleapis.com"]:
|
||||
deletion_policy: DELETE
|
||||
disable_dependent_services: false
|
||||
disable_on_destroy: false
|
||||
project: bar-test-2
|
||||
service: iam.googleapis.com
|
||||
timeouts: null
|
||||
module.project-factory.module.projects["test-2"].google_project_service.project_services["storage.googleapis.com"]:
|
||||
deletion_policy: DELETE
|
||||
disable_dependent_services: false
|
||||
disable_on_destroy: false
|
||||
project: bar-test-2
|
||||
service: storage.googleapis.com
|
||||
timeouts: null
|
||||
module.project-factory.module.service-accounts["test-0/tag-test"].google_service_account.service_account[0]:
|
||||
account_id: tag-test
|
||||
create_ignore_already_exists: null
|
||||
deletion_policy: DELETE
|
||||
description: null
|
||||
disabled: false
|
||||
display_name: Terraform-managed.
|
||||
email: tag-test@foo-test-0.iam.gserviceaccount.com
|
||||
member: serviceAccount:tag-test@foo-test-0.iam.gserviceaccount.com
|
||||
project: foo-test-0
|
||||
timeouts: null
|
||||
module.project-factory.module.service-accounts["test-0/tag-test"].google_tags_tag_binding.binding["project-level"]:
|
||||
timeouts: null
|
||||
module.project-factory.module.service-accounts["test-1/tag-test"].google_service_account.service_account[0]:
|
||||
account_id: tag-test
|
||||
create_ignore_already_exists: null
|
||||
deletion_policy: DELETE
|
||||
description: null
|
||||
disabled: false
|
||||
display_name: Terraform-managed.
|
||||
@@ -219,12 +282,15 @@ counts:
|
||||
google_project_iam_member: 6
|
||||
google_project_service: 10
|
||||
google_project_service_identity: 3
|
||||
google_service_account: 1
|
||||
google_service_account: 3
|
||||
google_storage_bucket: 1
|
||||
google_storage_project_service_account: 1
|
||||
google_tags_tag_binding: 2
|
||||
google_tags_tag_binding: 4
|
||||
google_tags_tag_key: 1
|
||||
google_tags_tag_value: 1
|
||||
google_tags_tag_value_iam_binding: 1
|
||||
modules: 7
|
||||
resources: 31
|
||||
modules: 10
|
||||
resources: 36
|
||||
terraform_data: 2
|
||||
|
||||
outputs: {}
|
||||
|
||||
Reference in New Issue
Block a user