Add service usage consumer role to IaC SAs, refactor delegated grants in FAST (#1773)

* add serviceusage role to iac sas, refactor delegated grants

* fix test

* tfdoc
This commit is contained in:
Ludovico Magnocavallo 2023-10-18 14:18:31 +02:00 committed by GitHub
parent 1a060dfb53
commit e7e188818a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 316 additions and 238 deletions

View File

@ -7,24 +7,24 @@ Legend: <code>+</code> additive, <code>•</code> conditional.
| members | roles |
|---|---|
|<b>GCP organization domain</b><br><small><i>domain</i></small>|[roles/browser](https://cloud.google.com/iam/docs/understanding-roles#browser) |
|<b>gcp-billing-admins</b><br><small><i>group</i></small>|[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) <code>+</code><br>[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) <code>+</code>|
|<b>cloud-gong-hierarchy_management-hm_tool-latchkey-presubmits</b><br><small><i>group</i></small>|[roles/browser](https://cloud.google.com/iam/docs/understanding-roles#browser) |
|<b>gcp-devops</b><br><small><i>group</i></small>|[roles/cloudsupport.techSupportEditor](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.techSupportEditor) <br>[roles/logging.viewer](https://cloud.google.com/iam/docs/understanding-roles#logging.viewer) <br>[roles/monitoring.viewer](https://cloud.google.com/iam/docs/understanding-roles#monitoring.viewer) |
|<b>gcp-network-admins</b><br><small><i>group</i></small>|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner) <br>[roles/cloudsupport.techSupportEditor](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.techSupportEditor) <br>[roles/compute.orgFirewallPolicyAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.orgFirewallPolicyAdmin) <code>+</code><br>[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) <code>+</code>|
|<b>gcp-organization-admins</b><br><small><i>group</i></small>|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner) <br>[roles/cloudsupport.admin](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.admin) <br>[roles/compute.osAdminLogin](https://cloud.google.com/iam/docs/understanding-roles#compute.osAdminLogin) <br>[roles/compute.osLoginExternalUser](https://cloud.google.com/iam/docs/understanding-roles#compute.osLoginExternalUser) <br>[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) <br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.organizationAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.organizationAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) <br>[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) <code>+</code><br>[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) <code>+</code><br>[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) <code>+</code>|
|<b>gcp-organization-admins</b><br><small><i>group</i></small>|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner) <br>[roles/cloudsupport.admin](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.admin) <br>[roles/compute.osAdminLogin](https://cloud.google.com/iam/docs/understanding-roles#compute.osAdminLogin) <br>[roles/compute.osLoginExternalUser](https://cloud.google.com/iam/docs/understanding-roles#compute.osLoginExternalUser) <br>[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) <br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.organizationAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.organizationAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) <br>[roles/resourcemanager.tagAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagAdmin) <br>[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) <code>+</code><br>[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) <code>+</code>|
|<b>gcp-security-admins</b><br><small><i>group</i></small>|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner) <br>[roles/cloudsupport.techSupportEditor](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.techSupportEditor) <br>[roles/iam.securityReviewer](https://cloud.google.com/iam/docs/understanding-roles#iam.securityReviewer) <br>[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin) <br>[roles/securitycenter.admin](https://cloud.google.com/iam/docs/understanding-roles#securitycenter.admin) <br>[roles/accesscontextmanager.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#accesscontextmanager.policyAdmin) <code>+</code><br>[roles/iam.organizationRoleAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.organizationRoleAdmin) <code>+</code><br>[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) <code>+</code>|
|<b>prod-bootstrap-0</b><br><small><i>serviceAccount</i></small>|[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin) <br>[roles/resourcemanager.organizationAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.organizationAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) <br>[roles/resourcemanager.projectMover](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectMover) <br>[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) <code>+</code><br>[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) <code>+</code><br>[roles/iam.organizationRoleAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.organizationRoleAdmin) <code>+</code>|
|<b>prod-resman-0</b><br><small><i>serviceAccount</i></small>|organizations/[org_id #0]/roles/organizationIamAdmin <code></code><br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.tagAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagAdmin) <br>[roles/resourcemanager.tagUser](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagUser) <br>[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) <code>+</code><br>[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) <code>+</code><br>[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) <code>+</code>|
|<b>latchkey-multiorg-ephemeral-custom-automation</b><br><small><i>serviceAccount</i></small>|[roles/iam.organizationRoleAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.organizationRoleAdmin) <code>+</code>|
|<b>latchkey-multiorg-ephemeral-iam-automation</b><br><small><i>serviceAccount</i></small>|[roles/resourcemanager.organizationAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.organizationAdmin) |
|<b>latchkey-multiorg-ephemeral-organization-automation</b><br><small><i>serviceAccount</i></small>|[roles/browser](https://cloud.google.com/iam/docs/understanding-roles#browser) |
|<b>prod-bootstrap-0</b><br><small><i>serviceAccount</i></small>|[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin) <br>[roles/resourcemanager.organizationAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.organizationAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) <br>[roles/resourcemanager.projectMover](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectMover) <br>[roles/resourcemanager.tagAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagAdmin) <br>[roles/iam.organizationRoleAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.organizationRoleAdmin) <code>+</code><br>[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) <code>+</code>|
|<b>prod-resman-0</b><br><small><i>serviceAccount</i></small>|[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin) <br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) <br>[roles/resourcemanager.tagAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagAdmin) <br>[roles/resourcemanager.tagUser](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagUser) <br>organizations/[org_id #0]/roles/organizationIamAdmin <code></code><br>[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) <code>+</code>|
|<b>tf-cf-quota-monitor</b><br><small><i>serviceAccount</i></small>|[roles/compute.viewer](https://cloud.google.com/iam/docs/understanding-roles#compute.viewer) |
## Project <i>prod-audit-logs-0</i>
| members | roles |
|---|---|
|<b>prod-bootstrap-0</b><br><small><i>serviceAccount</i></small>|[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) |
## Project <i>prod-billing-exp-0</i>
| members | roles |
|---|---|
|<b>o366118655033-148933</b><br><small><i>serviceAccount</i></small>|[roles/logging.bucketWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.bucketWriter) <code>+</code><code></code>|
|<b>o366118655033-468879</b><br><small><i>serviceAccount</i></small>|[roles/logging.bucketWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.bucketWriter) <code>+</code><code></code>|
|<b>prod-bootstrap-0</b><br><small><i>serviceAccount</i></small>|[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) |
## Project <i>prod-iac-core-0</i>
@ -36,5 +36,5 @@ Legend: <code>+</code> additive, <code>•</code> conditional.
|<b>SERVICE_IDENTITY_service-networking</b><br><small><i>serviceAccount</i></small>|[roles/servicenetworking.serviceAgent](https://cloud.google.com/iam/docs/understanding-roles#servicenetworking.serviceAgent) <code>+</code>|
|<b>prod-bootstrap-0</b><br><small><i>serviceAccount</i></small>|[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) |
|<b>prod-bootstrap-1</b><br><small><i>serviceAccount</i></small>|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) <code>+</code>|
|<b>prod-resman-0</b><br><small><i>serviceAccount</i></small>|[roles/cloudbuild.builds.editor](https://cloud.google.com/iam/docs/understanding-roles#cloudbuild.builds.editor) <br>[roles/iam.serviceAccountAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.serviceAccountAdmin) <br>[roles/iam.workloadIdentityPoolAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.workloadIdentityPoolAdmin) <br>[roles/source.admin](https://cloud.google.com/iam/docs/understanding-roles#source.admin) <br>[roles/storage.admin](https://cloud.google.com/iam/docs/understanding-roles#storage.admin) |
|<b>prod-resman-0</b><br><small><i>serviceAccount</i></small>|[roles/cloudbuild.builds.editor](https://cloud.google.com/iam/docs/understanding-roles#cloudbuild.builds.editor) <br>[roles/iam.serviceAccountAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.serviceAccountAdmin) <br>[roles/iam.workloadIdentityPoolAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.workloadIdentityPoolAdmin) <br>[roles/source.admin](https://cloud.google.com/iam/docs/understanding-roles#source.admin) <br>[roles/storage.admin](https://cloud.google.com/iam/docs/understanding-roles#storage.admin) <br>[roles/resourcemanager.projectIamAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectIamAdmin) <code></code><br>[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer) <code>+</code>|
|<b>prod-resman-1</b><br><small><i>serviceAccount</i></small>|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) <code>+</code>|

View File

@ -60,6 +60,26 @@ module "automation-project" {
module.automation-tf-resman-sa.iam_email
]
}
iam_bindings = {
delegated_grants_resman = {
members = [module.automation-tf-resman-sa.iam_email]
role = "roles/resourcemanager.projectIamAdmin"
condition = {
title = "resman_delegated_grant"
description = "Resource manager service account delegated grant."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['%s'])",
"roles/serviceusage.serviceUsageConsumer"
)
}
}
}
iam_bindings_additive = {
serviceusage_resman = {
member = module.automation-tf-resman-sa.iam_email
role = "roles/serviceusage.serviceUsageConsumer"
}
}
services = [
"accesscontextmanager.googleapis.com",
"bigquery.googleapis.com",

View File

@ -6,14 +6,11 @@ Legend: <code>+</code> additive, <code>•</code> conditional.
| members | roles |
|---|---|
|<b>dev-resman-dp-0</b><br><small><i>serviceAccount</i></small>|[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) <code>+</code><code></code><br>[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) <code>+</code>|
|<b>dev-resman-gke-0</b><br><small><i>serviceAccount</i></small>|[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) <code>+</code>|
|<b>dev-resman-pf-0</b><br><small><i>serviceAccount</i></small>|[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) <code>+</code><code></code><br>[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) <code>+</code><br>[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) <code>+</code>|
|<b>prod-resman-dp-0</b><br><small><i>serviceAccount</i></small>|[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) <code>+</code><code></code><br>[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) <code>+</code>|
|<b>prod-resman-gke-0</b><br><small><i>serviceAccount</i></small>|[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) <code>+</code>|
|<b>prod-resman-net-0</b><br><small><i>serviceAccount</i></small>|[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) <code>+</code><br>[roles/compute.orgFirewallPolicyAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.orgFirewallPolicyAdmin) <code>+</code><br>[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) <code>+</code>|
|<b>prod-resman-pf-0</b><br><small><i>serviceAccount</i></small>|[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) <code>+</code><code></code><br>[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) <code>+</code><br>[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) <code>+</code>|
|<b>prod-resman-sec-0</b><br><small><i>serviceAccount</i></small>|[roles/accesscontextmanager.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#accesscontextmanager.policyAdmin) <code>+</code><br>[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) <code>+</code>|
|<b>egov-test-0</b><br><small><i>group</i></small>|[roles/resourcemanager.organizationViewer](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.organizationViewer) <code>+</code>|
|<b>dev-resman-pf-0</b><br><small><i>serviceAccount</i></small>|[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) <code>+</code><code></code>|
|<b>prod-resman-net-0</b><br><small><i>serviceAccount</i></small>|[roles/compute.orgFirewallPolicyAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.orgFirewallPolicyAdmin) <code>+</code><br>[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) <code>+</code>|
|<b>prod-resman-pf-0</b><br><small><i>serviceAccount</i></small>|[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) <code>+</code><code></code>|
|<b>security-0</b><br><small><i>serviceAccount</i></small>|[roles/accesscontextmanager.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#accesscontextmanager.policyAdmin) <code>+</code>|
## Folder <i>development [#0]</i>
@ -41,6 +38,29 @@ Legend: <code>+</code> additive, <code>•</code> conditional.
|---|---|
|<b>dev-resman-pf-0</b><br><small><i>serviceAccount</i></small>|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin <br>[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin) <br>[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) <br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
## Folder <i>egov test 0 - core [#1]</i>
| members | roles |
|---|---|
|<b>egov-test-0</b><br><small><i>group</i></small>|organizations/[org_id #0]/roles/tenantLoadBalancerAdmin <br>[roles/compute.instanceAdmin.v1](https://cloud.google.com/iam/docs/understanding-roles#compute.instanceAdmin.v1) <br>[roles/viewer](https://cloud.google.com/iam/docs/understanding-roles#viewer) |
|<b>egov-t0-iac-0</b><br><small><i>serviceAccount</i></small>|organizations/[org_id #0]/roles/tenantLoadBalancerAdmin <br>[roles/compute.instanceAdmin.v1](https://cloud.google.com/iam/docs/understanding-roles#compute.instanceAdmin.v1) <br>[roles/viewer](https://cloud.google.com/iam/docs/understanding-roles#viewer) |
|<b>tn-egov-t0-0</b><br><small><i>serviceAccount</i></small>|[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) |
## Folder <i>egov test 0 - tenant [#1]</i>
| members | roles |
|---|---|
|<b>egov-test-0</b><br><small><i>group</i></small>|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner) <br>[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) <br>[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) <br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) <br>[roles/resourcemanager.tagUser](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagUser) |
|<b>egov-t0-iac-0</b><br><small><i>serviceAccount</i></small>|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner) <br>[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) <br>[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) <br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) <br>[roles/resourcemanager.tagUser](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagUser) |
## Folder <i>egov test 0 [#1]</i>
| members | roles |
|---|---|
|<b>egov-test-0</b><br><small><i>group</i></small>|[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin) <br>[roles/monitoring.admin](https://cloud.google.com/iam/docs/understanding-roles#monitoring.admin) <br>[roles/resourcemanager.folderViewer](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderViewer) <br>[roles/browser](https://cloud.google.com/iam/docs/understanding-roles#browser) |
|<b>egov-t0-iac-0</b><br><small><i>serviceAccount</i></small>|[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin) <br>[roles/monitoring.admin](https://cloud.google.com/iam/docs/understanding-roles#monitoring.admin) <br>[roles/resourcemanager.folderViewer](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderViewer) |
|<b>tn-egov-t0-0</b><br><small><i>serviceAccount</i></small>|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner) <br>[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) <br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) <br>[roles/resourcemanager.tagUser](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagUser) |
## Folder <i>networking</i>
| members | roles |
@ -85,7 +105,13 @@ Legend: <code>+</code> additive, <code>•</code> conditional.
| members | roles |
|---|---|
|<b>gcp-security-admins</b><br><small><i>group</i></small>|[roles/viewer](https://cloud.google.com/iam/docs/understanding-roles#viewer) |
|<b>prod-resman-sec-0</b><br><small><i>serviceAccount</i></small>|[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin) <br>[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) <br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
|<b>security-0</b><br><small><i>serviceAccount</i></small>|[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin) <br>[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) <br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
## Folder <i>team 0</i>
| members | roles |
|---|---|
|<b>prod-teams-team-0-0</b><br><small><i>serviceAccount</i></small>|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) <br>[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin) <br>[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) <br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
## Folder <i>teams</i>
@ -93,21 +119,26 @@ Legend: <code>+</code> additive, <code>•</code> conditional.
|---|---|
|<b>prod-resman-teams-0</b><br><small><i>serviceAccount</i></small>|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) <br>[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin) <br>[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) <br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
## Folder <i>teams test</i>
## Project <i>egov-t0-iac-core-0</i>
| members | roles |
|---|---|
|<b>prod-teams-teams-test-0</b><br><small><i>serviceAccount</i></small>|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) <br>[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin) <br>[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner) <br>[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin) <br>[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
|<b>egov-test-0</b><br><small><i>group</i></small>|[roles/iam.serviceAccountAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.serviceAccountAdmin) <br>[roles/iam.serviceAccountTokenCreator](https://cloud.google.com/iam/docs/understanding-roles#iam.serviceAccountTokenCreator) <br>[roles/iam.workloadIdentityPoolAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.workloadIdentityPoolAdmin) |
|<b>SERVICE_IDENTITY_service-networking</b><br><small><i>serviceAccount</i></small>|[roles/servicenetworking.serviceAgent](https://cloud.google.com/iam/docs/understanding-roles#servicenetworking.serviceAgent) <code>+</code>|
## Project <i>prod-iac-core-0</i>
| members | roles |
|---|---|
|<b>dev-pf-resman-pf-1</b><br><small><i>serviceAccount</i></small>|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) <code>+</code>|
|<b>dev-resman-dp-1</b><br><small><i>serviceAccount</i></small>|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) <code>+</code>|
|<b>dev-resman-gke-1</b><br><small><i>serviceAccount</i></small>|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) <code>+</code>|
|<b>prod-pf-resman-pf-1</b><br><small><i>serviceAccount</i></small>|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) <code>+</code>|
|<b>prod-resman-dp-1</b><br><small><i>serviceAccount</i></small>|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) <code>+</code>|
|<b>prod-resman-gke-1</b><br><small><i>serviceAccount</i></small>|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) <code>+</code>|
|<b>dev-resman-dp-0</b><br><small><i>serviceAccount</i></small>|[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer) <code>+</code>|
|<b>dev-resman-gke-0</b><br><small><i>serviceAccount</i></small>|[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer) <code>+</code>|
|<b>dev-resman-pf-0</b><br><small><i>serviceAccount</i></small>|[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer) <code>+</code>|
|<b>dev-resman-sbox-0</b><br><small><i>serviceAccount</i></small>|[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer) <code>+</code>|
|<b>prod-resman-gke-0</b><br><small><i>serviceAccount</i></small>|[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer) <code>+</code>|
|<b>prod-resman-net-0</b><br><small><i>serviceAccount</i></small>|[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer) <code>+</code>|
|<b>prod-resman-net-1</b><br><small><i>serviceAccount</i></small>|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) <code>+</code>|
|<b>prod-resman-pf-0</b><br><small><i>serviceAccount</i></small>|[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer) <code>+</code>|
|<b>prod-resman-sec-1</b><br><small><i>serviceAccount</i></small>|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) <code>+</code>|
|<b>prod-resman-teams-0</b><br><small><i>serviceAccount</i></small>|[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer) <code>+</code>|
|<b>security-0</b><br><small><i>serviceAccount</i></small>|[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer) <code>+</code>|
|<b>tn-egov-t0-0</b><br><small><i>serviceAccount</i></small>|[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer) <code>+</code>|

View File

@ -88,6 +88,9 @@ module "branch-dp-dev-sa" {
try(module.branch-dp-dev-sa-cicd.0.iam_email, null)
])
}
iam_project_roles = {
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.objectAdmin"]
}

View File

@ -87,6 +87,9 @@ module "branch-gke-dev-sa" {
])
)
}
iam_project_roles = {
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.objectAdmin"]
}
@ -111,6 +114,9 @@ module "branch-gke-prod-sa" {
])
)
}
iam_project_roles = {
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.objectAdmin"]
}

View File

@ -96,6 +96,9 @@ module "branch-network-sa" {
try(module.branch-network-sa-cicd.0.iam_email, null)
])
}
iam_project_roles = {
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.objectAdmin"]
}

View File

@ -29,6 +29,9 @@ module "branch-pf-dev-sa" {
try(module.branch-pf-dev-sa-cicd.0.iam_email, null)
])
}
iam_project_roles = {
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.objectAdmin"]
}
@ -47,6 +50,9 @@ module "branch-pf-prod-sa" {
try(module.branch-pf-prod-sa-cicd.0.iam_email, null)
])
}
iam_project_roles = {
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.objectAdmin"]
}

View File

@ -59,4 +59,7 @@ module "branch-sandbox-sa" {
name = "dev-resman-sbox-0"
display_name = "Terraform resman sandbox service account."
prefix = var.prefix
iam_project_roles = {
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
}
}

View File

@ -60,9 +60,7 @@ module "branch-security-sa" {
])
}
iam_project_roles = {
(var.automation.project_id) = [
"roles/serviceusage.serviceUsageConsumer",
]
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.objectAdmin"]

View File

@ -46,6 +46,9 @@ module "branch-teams-sa" {
name = "prod-resman-teams-0"
display_name = "Terraform resman teams service account."
prefix = var.prefix
iam_project_roles = {
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.objectAdmin"]
}
@ -82,6 +85,8 @@ module "branch-teams-team-folder" {
group_iam = each.value.group_iam == null ? {} : each.value.group_iam
}
# TODO: move into team's own IaC project
module "branch-teams-team-sa" {
source = "../../../modules/iam-service-account"
for_each = var.fast_features.teams ? coalesce(var.team_folders, {}) : {}

View File

@ -135,6 +135,9 @@ module "tenant-core-sa" {
name = "tn-${each.key}-0"
description = "Terraform service account for tenant ${each.key}."
prefix = var.prefix
iam_project_roles = {
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
}
}
module "tenant-core-gcs" {

View File

@ -376,8 +376,8 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
| [outputs.tf](./outputs.tf) | Module outputs. | | <code>google_storage_bucket_object</code> · <code>local_file</code> |
| [peerings.tf](./peerings.tf) | None | <code>net-vpc-peering</code> | |
| [regions.tf](./regions.tf) | Compute short names for regions. | | |
| [spoke-dev.tf](./spoke-dev.tf) | Dev spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | <code>google_project_iam_binding</code> |
| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | <code>google_project_iam_binding</code> |
| [spoke-dev.tf](./spoke-dev.tf) | Dev spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | |
| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | |
| [test-resources.tf](./test-resources.tf) | temporary instances for testing | <code>compute-vm</code> | |
| [variables-peerings.tf](./variables-peerings.tf) | Peering related variables. | | |
| [variables.tf](./variables.tf) | Module variables. | | |

View File

@ -43,6 +43,26 @@ module "dev-spoke-project" {
try(local.service_accounts.project-factory-prod, null),
])
}
# allow specific service accounts to assign a set of roles
iam_bindings = {
sa_delegated_grants = {
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-dev, null),
try(local.service_accounts.project-factory-dev, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-dev, null),
])
condition = {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}
}
}
module "dev-spoke-vpc" {
@ -84,23 +104,3 @@ module "dev-spoke-cloudnat" {
router_network = module.dev-spoke-vpc.name
logging_filter = "ERRORS_ONLY"
}
# Create delegated grants for stage3 service accounts
resource "google_project_iam_binding" "dev_spoke_project_iam_delegated" {
project = module.dev-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-dev, null),
try(local.service_accounts.project-factory-dev, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-dev, null),
])
condition {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}

View File

@ -42,6 +42,25 @@ module "prod-spoke-project" {
try(local.service_accounts.project-factory-prod, null),
])
}
# allow specific service accounts to assign a set of roles
iam_bindings = {
sa_delegated_grants = {
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-prod, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-prod, null),
])
condition = {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}
}
}
module "prod-spoke-vpc" {
@ -83,22 +102,3 @@ module "prod-spoke-cloudnat" {
router_network = module.prod-spoke-vpc.name
logging_filter = "ERRORS_ONLY"
}
# Create delegated grants for stage3 service accounts
resource "google_project_iam_binding" "prod_spoke_project_iam_delegated" {
project = module.prod-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-prod, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-prod, null),
])
condition {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}

View File

@ -397,8 +397,8 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
| [monitoring.tf](./monitoring.tf) | Network monitoring dashboards. | | <code>google_monitoring_dashboard</code> |
| [outputs.tf](./outputs.tf) | Module outputs. | | <code>google_storage_bucket_object</code> · <code>local_file</code> |
| [regions.tf](./regions.tf) | Compute short names for regions. | | |
| [spoke-dev.tf](./spoke-dev.tf) | Dev spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | <code>google_project_iam_binding</code> |
| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | <code>google_project_iam_binding</code> |
| [spoke-dev.tf](./spoke-dev.tf) | Dev spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | |
| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | |
| [test-resources.tf](./test-resources.tf) | temporary instances for testing | <code>compute-vm</code> | |
| [variables-vpn.tf](./variables-vpn.tf) | None | | |
| [variables.tf](./variables.tf) | Module variables. | | |

View File

@ -43,6 +43,26 @@ module "dev-spoke-project" {
try(local.service_accounts.project-factory-prod, null),
])
}
# allow specific service accounts to assign a set of roles
iam_bindings = {
sa_delegated_grants = {
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-dev, null),
try(local.service_accounts.project-factory-dev, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-dev, null),
])
condition = {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}
}
}
module "dev-spoke-vpc" {
@ -84,23 +104,3 @@ module "dev-spoke-cloudnat" {
router_network = module.dev-spoke-vpc.name
logging_filter = "ERRORS_ONLY"
}
# Create delegated grants for stage3 service accounts
resource "google_project_iam_binding" "dev_spoke_project_iam_delegated" {
project = module.dev-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-dev, null),
try(local.service_accounts.project-factory-dev, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-dev, null),
])
condition {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}

View File

@ -42,6 +42,25 @@ module "prod-spoke-project" {
try(local.service_accounts.project-factory-prod, null),
])
}
# allow specific service accounts to assign a set of roles
iam_bindings = {
sa_delegated_grants = {
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-prod, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-prod, null),
])
condition = {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}
}
}
module "prod-spoke-vpc" {
@ -83,22 +102,3 @@ module "prod-spoke-cloudnat" {
router_network = module.prod-spoke-vpc.name
logging_filter = "ERRORS_ONLY"
}
# Create delegated grants for stage3 service accounts
resource "google_project_iam_binding" "prod_spoke_project_iam_delegated" {
project = module.prod-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-prod, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-prod, null),
])
condition {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}

View File

@ -446,8 +446,8 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
| [nva.tf](./nva.tf) | None | <code>compute-mig</code> · <code>compute-vm</code> · <code>simple-nva</code> | |
| [outputs.tf](./outputs.tf) | Module outputs. | | <code>google_storage_bucket_object</code> · <code>local_file</code> |
| [regions.tf](./regions.tf) | Compute short names for regions. | | |
| [spoke-dev.tf](./spoke-dev.tf) | Dev spoke VPC and related resources. | <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpc-peering</code> · <code>project</code> | <code>google_project_iam_binding</code> |
| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpc-peering</code> · <code>project</code> | <code>google_project_iam_binding</code> |
| [spoke-dev.tf](./spoke-dev.tf) | Dev spoke VPC and related resources. | <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpc-peering</code> · <code>project</code> | |
| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpc-peering</code> · <code>project</code> | |
| [test-resources.tf](./test-resources.tf) | temporary instances for testing | <code>compute-vm</code> | |
| [variables.tf](./variables.tf) | Module variables. | | |
| [vpn-onprem.tf](./vpn-onprem.tf) | VPN between landing and onprem. | <code>net-vpn-ha</code> | |

View File

@ -42,6 +42,26 @@ module "dev-spoke-project" {
try(local.service_accounts.project-factory-prod, null),
])
}
# allow specific service accounts to assign a set of roles
iam_bindings = {
sa_delegated_grants = {
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-dev, null),
try(local.service_accounts.project-factory-dev, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-dev, null),
])
condition = {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}
}
}
module "dev-spoke-vpc" {
@ -110,23 +130,3 @@ module "peering-dev" {
local_network = module.dev-spoke-vpc.self_link
peer_network = module.landing-trusted-vpc.self_link
}
# Create delegated grants for stage3 service accounts
resource "google_project_iam_binding" "dev_spoke_project_iam_delegated" {
project = module.dev-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-dev, null),
try(local.service_accounts.project-factory-dev, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-dev, null),
])
condition {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}

View File

@ -41,6 +41,25 @@ module "prod-spoke-project" {
try(local.service_accounts.project-factory-prod, null),
])
}
# allow specific service accounts to assign a set of roles
iam_bindings = {
sa_delegated_grants = {
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-prod, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-prod, null),
])
condition = {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}
}
}
module "prod-spoke-vpc" {
@ -109,22 +128,3 @@ module "peering-prod" {
local_network = module.prod-spoke-vpc.self_link
peer_network = module.landing-trusted-vpc.self_link
}
# Create delegated grants for stage3 service accounts
resource "google_project_iam_binding" "prod_spoke_project_iam_delegated" {
project = module.prod-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-prod, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-prod, null),
])
condition {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}

View File

@ -320,8 +320,8 @@ Regions are defined via the `regions` variable which sets up a mapping between t
| [monitoring.tf](./monitoring.tf) | Network monitoring dashboards. | | <code>google_monitoring_dashboard</code> |
| [outputs.tf](./outputs.tf) | Module outputs. | | <code>google_storage_bucket_object</code> · <code>local_file</code> |
| [regions.tf](./regions.tf) | Compute short names for regions. | | |
| [spoke-dev.tf](./spoke-dev.tf) | Dev spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | <code>google_project_iam_binding</code> |
| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | <code>google_project_iam_binding</code> |
| [spoke-dev.tf](./spoke-dev.tf) | Dev spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | |
| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | |
| [test-resources.tf](./test-resources.tf) | Temporary instances for testing | <code>compute-vm</code> | |
| [variables.tf](./variables.tf) | Module variables. | | |
| [vpn-onprem.tf](./vpn-onprem.tf) | VPN between landing and onprem. | <code>net-vpn-ha</code> | |

View File

@ -43,6 +43,26 @@ module "dev-spoke-project" {
try(local.service_accounts.project-factory-prod, null),
])
}
# allow specific service accounts to assign a set of roles
iam_bindings = {
sa_delegated_grants = {
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-dev, null),
try(local.service_accounts.project-factory-dev, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-dev, null),
])
condition = {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}
}
}
module "dev-spoke-vpc" {
@ -84,23 +104,3 @@ module "dev-spoke-cloudnat" {
router_network = module.dev-spoke-vpc.name
logging_filter = "ERRORS_ONLY"
}
# Create delegated grants for stage3 service accounts
resource "google_project_iam_binding" "dev_spoke_project_iam_delegated" {
project = module.dev-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-dev, null),
try(local.service_accounts.gke-dev, null),
try(local.service_accounts.project-factory-dev, null),
try(local.service_accounts.project-factory-prod, null),
])
condition {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}

View File

@ -42,6 +42,25 @@ module "prod-spoke-project" {
try(local.service_accounts.project-factory-prod, null)
])
}
# allow specific service accounts to assign a set of roles
iam_bindings = {
sa_delegated_grants = {
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-prod, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-prod, null),
])
condition = {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}
}
}
module "prod-spoke-vpc" {
@ -83,22 +102,3 @@ module "prod-spoke-cloudnat" {
router_network = module.prod-spoke-vpc.name
logging_filter = "ERRORS_ONLY"
}
# Create delegated grants for stage3 service accounts
resource "google_project_iam_binding" "prod_spoke_project_iam_delegated" {
project = module.prod-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-prod, null),
try(local.service_accounts.gke-platform-prod, null),
try(local.service_accounts.project-factory-prod, null),
])
condition {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}

View File

@ -472,8 +472,8 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
| [nva.tf](./nva.tf) | None | <code>compute-vm</code> · <code>simple-nva</code> | <code>google_compute_address</code> |
| [outputs.tf](./outputs.tf) | Module outputs. | | <code>google_storage_bucket_object</code> · <code>local_file</code> |
| [regions.tf](./regions.tf) | Compute short names for regions. | | |
| [spoke-dev.tf](./spoke-dev.tf) | Dev spoke VPC and related resources. | <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpc-peering</code> · <code>project</code> | <code>google_project_iam_binding</code> |
| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpc-peering</code> · <code>project</code> | <code>google_project_iam_binding</code> |
| [spoke-dev.tf](./spoke-dev.tf) | Dev spoke VPC and related resources. | <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpc-peering</code> · <code>project</code> | |
| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpc-peering</code> · <code>project</code> | |
| [test-resources.tf](./test-resources.tf) | temporary instances for testing | <code>compute-vm</code> | |
| [variables.tf](./variables.tf) | Module variables. | | |
| [vpn-onprem.tf](./vpn-onprem.tf) | VPN between landing and onprem. | <code>net-vpn-ha</code> | |

View File

@ -42,6 +42,26 @@ module "dev-spoke-project" {
try(local.service_accounts.project-factory-prod, null),
])
}
# allow specific service accounts to assign a set of roles
iam_bindings = {
sa_delegated_grants = {
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-dev, null),
try(local.service_accounts.project-factory-dev, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-dev, null),
])
condition = {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}
}
}
module "dev-spoke-vpc" {
@ -80,23 +100,3 @@ module "peering-dev" {
local_network = module.dev-spoke-vpc.self_link
peer_network = module.landing-trusted-vpc.self_link
}
# Create delegated grants for stage3 service accounts
resource "google_project_iam_binding" "dev_spoke_project_iam_delegated" {
project = module.dev-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-dev, null),
try(local.service_accounts.project-factory-dev, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-dev, null),
])
condition {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}

View File

@ -41,6 +41,25 @@ module "prod-spoke-project" {
try(local.service_accounts.project-factory-prod, null),
])
}
# allow specific service accounts to assign a set of roles
iam_bindings = {
sa_delegated_grants = {
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-prod, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-prod, null),
])
condition = {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}
}
}
module "prod-spoke-vpc" {
@ -79,22 +98,3 @@ module "peering-prod" {
local_network = module.prod-spoke-vpc.self_link
peer_network = module.landing-trusted-vpc.self_link
}
# Create delegated grants for stage3 service accounts
resource "google_project_iam_binding" "prod_spoke_project_iam_delegated" {
project = module.prod-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = compact([
try(local.service_accounts.data-platform-prod, null),
try(local.service_accounts.project-factory-prod, null),
try(local.service_accounts.gke-prod, null),
])
condition {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", local.stage3_sas_delegated_grants))
)
}
}

View File

@ -20,8 +20,8 @@ counts:
google_organization_iam_custom_role: 3
google_organization_iam_member: 13
google_project: 3
google_project_iam_binding: 9
google_project_iam_member: 3
google_project_iam_binding: 10
google_project_iam_member: 4
google_project_service: 29
google_project_service_identity: 3
google_service_account: 2