The feature request
This introduces the ability to define project-scoped custom roles natively within a project's YAML configuration file and immediately reference those roles in the project's IAM bindings using the $custom_roles: interpolation context.
Currently, managing custom roles requires operating outside the project factory YAML (either via upstream folder/org modules or separate project-level IAM states). This enhancement allows a single YAML file to act as the complete source of truth for IAM.
Proposed solution
The implementation passes the parsed custom_roles block to the underlying project module and merges the resulting custom role IDs into the IAM context map.
Changes in project-factory/projects.tf:
module "projects" {
source = "../project"
for_each = local.projects_input
# ... existing attributes ...
contacts = merge(
each.value.contacts, var.data_merges.contacts
)
# Added support for creating custom roles directly from YAML
custom_roles = try(each.value.custom_roles, null)
}
We then extend the projects-iam module's context to support YAML interpolation ($custom_roles:my_role) by merging the locally created role IDs with any globally defined roles:
module "projects-iam" {
source = "../project"
# ... existing attributes ...
context = merge(local.ctx, {
# ... existing context vars ...
iam_principals = merge(
local.ctx_iam_principals,
lookup(local.per_project_service_agents, each.key, {}),
lookup(local.self_sas_iam_emails, each.key, {}),
local.projects_service_agents
)
# Expose custom role IDs for YAML IAM interpolation
custom_roles = merge(
try(local.ctx.custom_roles, {}),
module.projects[each.key].custom_role_id
)
})
}
To ensure users provide valid GCP role constraints, we may update the project.schema.json to enforce strict regex validation.
Role Names: Restricted to ^[a-zA-Z0-9_.]{3,64}$ (preventing invalid characters like hyphens).
Permissions: Restricted to GCP's standard service.resource.verb pattern (^[a-zA-Z-]+.[a-zA-Z-]+.[a-zA-Z-]+$).
"custom_roles": {
"type": "object",
"additionalProperties": false,
"description": "Custom roles which will be created in your project. Created custom roles can be later referenced in IAM sections using YAML interpolation variable $custom_roles:my_role_name. Custom role names cannot contain hyphens (-). You can add only permissions to custom roles, so nesting roles is not possible.",
"patternProperties": {
"^[a-zA-Z0-9_\\\\.]{3,64}$": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-zA-Z-]+\\.[a-zA-Z-]+\\.[a-zA-Z-]+$",
"examples": [
"compute.instances.start",
"compute.instances.stop"
]
}
}
}
}
A standalone custom_role_schema.json and Markdown documentation should be included for completeness.
Additional context
No response
The feature request
This introduces the ability to define project-scoped custom roles natively within a project's YAML configuration file and immediately reference those roles in the project's IAM bindings using the $custom_roles: interpolation context.
Currently, managing custom roles requires operating outside the project factory YAML (either via upstream folder/org modules or separate project-level IAM states). This enhancement allows a single YAML file to act as the complete source of truth for IAM.
Proposed solution
The implementation passes the parsed custom_roles block to the underlying project module and merges the resulting custom role IDs into the IAM context map.
Changes in
project-factory/projects.tf:We then extend the projects-iam module's context to support YAML interpolation ($custom_roles:my_role) by merging the locally created role IDs with any globally defined roles:
To ensure users provide valid GCP role constraints, we may update the project.schema.json to enforce strict regex validation.
Role Names: Restricted to ^[a-zA-Z0-9_.]{3,64}$ (preventing invalid characters like hyphens).
Permissions: Restricted to GCP's standard service.resource.verb pattern (^[a-zA-Z-]+.[a-zA-Z-]+.[a-zA-Z-]+$).
A standalone custom_role_schema.json and Markdown documentation should be included for completeness.
Additional context
No response