add the self project key to service account namespaces (#3490)

This commit is contained in:
Ludovico Magnocavallo
2025-10-30 17:42:13 +01:00
committed by GitHub
parent 4a9085675e
commit c765043c5c
8 changed files with 66 additions and 14 deletions

View File

@@ -30,6 +30,7 @@ The code is meant to be executed by a high level service account with powerful p
- [Projects](#projects)
- [Factory-wide project defaults, merges, optionals](#factory-wide-project-defaults-merges-optionals)
- [Project templates](#project-templates)
- [Context expansion for template-derived resources](#context-expansion-for-template-derived-resources)
- [Service accounts and buckets](#service-accounts-and-buckets)
- [Automation resources](#automation-resources)
- [Prefix handling](#prefix-handling)
@@ -88,6 +89,10 @@ For example, declaring `iam` or `org_policies` in the template and then doing th
The set of available templates is defined via a dedicated path in the `factories_config` file, and then a template can be referenced from a project definition via the `project_template` YAML attribute.
#### Context expansion for template-derived resources
Using a template makes it hard or impossible to reference project-level resources that contain the project key in the context id, as for example `$iam_principals:service_accounts/my-project/rw`. In those cases, alternate context ids are provided of the form `$iam_principals:service_accounts/_self_/rw`. Those are only available within the scope of the project itself and are currently only supported for service accounts in the `$iam_principals` and `$service_account_ids` context namespaces.
### Service accounts and buckets
Service accounts and GCS buckets can be managed as part of each project's YAML configuration. This allows creation of default service accounts used for GCE instances, in firewall rules, or for application-level credentials without resorting to a separate Terraform configuration.
@@ -577,6 +582,9 @@ parent: $folder_ids:team-a/app-0
iam_by_principals:
$iam_principals:service_accounts/dev-ta-app0-be/app-0-be:
- roles/storage.objectViewer
# alternate context lookup, mainly for project template use
$iam_principals:service_accounts/_self_/app-0-fe:
- roles/storage.objectViewer
iam:
roles/cloudkms.cryptoKeyEncrypterDecrypter:
- $service_agents:storage
@@ -589,6 +597,13 @@ service_accounts:
iam_self_roles:
- roles/logging.logWriter
- roles/monitoring.metricWriter
# this is just for illustrative/test purposes
iam:
roles/iam.serviceAccountUser:
- $iam_principals:service_accounts/_self_/app-0-fe
iam_sa_roles:
$service_account_ids:_self_/app-0-fe:
- roles/iam.serviceAccountUser
app-0-fe:
display_name: "Frontend instances."
iam_project_roles:

View File

@@ -161,7 +161,7 @@ module "automation-service-accounts-iam" {
use_data_source = false
}
context = merge(local.ctx, {
service_account_ids = local.project_sas_ids
service_account_ids = local.projects_sas_ids
})
iam_sa_roles = lookup(each.value, "iam_sa_roles", {})
}

View File

@@ -39,7 +39,8 @@ module "bigquery-datasets" {
iam_principals = merge(
local.ctx.iam_principals,
local.projects_sas_iam_emails,
local.automation_sas_iam_emails
local.automation_sas_iam_emails,
lookup(local.self_sas_iam_emails, each.value.project_key, {})
)
locations = local.ctx.locations
project_ids = local.ctx_project_ids

View File

@@ -72,7 +72,8 @@ module "buckets" {
iam_principals = merge(
local.ctx.iam_principals,
local.projects_sas_iam_emails,
local.automation_sas_iam_emails
local.automation_sas_iam_emails,
lookup(local.self_sas_iam_emails, each.value.project_key, {})
)
locations = local.ctx.locations
project_ids = local.ctx_project_ids

View File

@@ -50,7 +50,8 @@ module "log-buckets" {
iam_principals = merge(
local.ctx.iam_principals,
local.projects_sas_iam_emails,
local.automation_sas_iam_emails
local.automation_sas_iam_emails,
lookup(local.self_sas_iam_emails, each.value.project_key, {})
)
locations = local.ctx.locations
project_ids = local.ctx_project_ids

View File

@@ -44,7 +44,7 @@ locals {
projects_sas_iam_emails = {
for k, v in module.service-accounts : "service_accounts/${k}" => v.iam_email
}
project_sas_ids = merge(
projects_sas_ids = merge(
{
for k, v in module.service-accounts : k => v.id
},
@@ -52,6 +52,22 @@ locals {
for k, v in module.automation-service-accounts : k => v.id
}
)
self_sas = {
for k in local.projects_service_accounts :
k.project_key => { key = "${k.project_key}/${k.name}", name = k.name }...
}
self_sas_iam_emails = {
for k, v in local.self_sas : k => {
for vv in v :
"service_accounts/_self_/${vv.name}" => module.service-accounts[vv.key].iam_email
}
}
self_sas_ids = {
for k, v in local.self_sas : k => {
for vv in v :
"_self_/${vv.name}" => module.service-accounts[vv.key].id
}
}
}
module "service-accounts" {
@@ -93,9 +109,13 @@ module "service_accounts-iam" {
iam_principals = merge(
local.ctx.iam_principals,
local.projects_sas_iam_emails,
local.automation_sas_iam_emails
local.automation_sas_iam_emails,
lookup(local.self_sas_iam_emails, each.value.project_key, {})
)
service_account_ids = merge(
local.projects_sas_ids,
lookup(local.self_sas_ids, each.value.project_key, {})
)
service_account_ids = local.project_sas_ids
})
iam = each.value.iam
iam_sa_roles = each.value.iam_sa_roles

View File

@@ -124,10 +124,13 @@ module "projects-iam" {
}
}
context = merge(local.ctx, {
folder_ids = local.ctx.folder_ids
kms_keys = local.ctx.kms_keys
iam_principals = local.ctx_iam_principals
log_buckets = local.ctx_log_buckets
folder_ids = local.ctx.folder_ids
kms_keys = local.ctx.kms_keys
iam_principals = merge(
local.ctx_iam_principals,
lookup(local.self_sas_iam_emails, each.key, {})
)
log_buckets = local.ctx_log_buckets
})
factories_config = {
# we do anything that can refer to IAM and custom roles in this call