Essential contacts in schemas, and email context substitutions (#3495)

* modules

* fast

* duplicate diff

* fix contacts in FAST stage 0 datasets, update contacts in YAML schemas
This commit is contained in:
Ludovico Magnocavallo
2025-11-03 08:53:29 +01:00
committed by GitHub
parent 153046307f
commit 0a2cc758ac
46 changed files with 2489 additions and 103 deletions

View File

@@ -745,9 +745,9 @@ Define values for the `var.environments` variable in a tfvars file.
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [context](variables.tf#L17) | Context-specific interpolations. | <code title="object&#40;&#123;&#10; custom_roles &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; folder_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; iam_principals &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; kms_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; notification_channels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; project_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; service_account_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_values &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpc_host_projects &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpc_sc_perimeters &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [factories_config](variables.tf#L37) | Configuration for the resource factories or external data. | <code title="object&#40;&#123;&#10; billing_accounts &#61; optional&#40;string, &#34;datasets&#47;classic&#47;billing-accounts&#34;&#41;&#10; cicd &#61; optional&#40;string&#41;&#10; defaults &#61; optional&#40;string, &#34;datasets&#47;classic&#47;defaults.yaml&#34;&#41;&#10; folders &#61; optional&#40;string, &#34;datasets&#47;classic&#47;folders&#34;&#41;&#10; organization &#61; optional&#40;string, &#34;datasets&#47;classic&#47;organization&#34;&#41;&#10; project_templates &#61; optional&#40;string, &#34;datasets&#47;classic&#47;templates&#34;&#41;&#10; projects &#61; optional&#40;string, &#34;datasets&#47;classic&#47;projects&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [org_policies_imports](variables.tf#L52) | List of org policies to import. These need to also be defined in data files. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
| [context](variables.tf#L17) | Context-specific interpolations. | <code title="object&#40;&#123;&#10; custom_roles &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; email_addresses &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; folder_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; iam_principals &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; kms_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; notification_channels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; project_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; service_account_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_values &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpc_host_projects &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpc_sc_perimeters &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [factories_config](variables.tf#L38) | Configuration for the resource factories or external data. | <code title="object&#40;&#123;&#10; billing_accounts &#61; optional&#40;string, &#34;datasets&#47;classic&#47;billing-accounts&#34;&#41;&#10; cicd &#61; optional&#40;string&#41;&#10; defaults &#61; optional&#40;string, &#34;datasets&#47;classic&#47;defaults.yaml&#34;&#41;&#10; folders &#61; optional&#40;string, &#34;datasets&#47;classic&#47;folders&#34;&#41;&#10; organization &#61; optional&#40;string, &#34;datasets&#47;classic&#47;organization&#34;&#41;&#10; project_templates &#61; optional&#40;string, &#34;datasets&#47;classic&#47;templates&#34;&#41;&#10; projects &#61; optional&#40;string, &#34;datasets&#47;classic&#47;projects&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [org_policies_imports](variables.tf#L53) | List of org policies to import. These need to also be defined in data files. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
## Outputs
@@ -757,4 +757,3 @@ Define values for the `var.environments` variable in a tfvars file.
| [projects](outputs.tf#L22) | Attributes for managed projects. | |
| [tfvars](outputs.tf#L27) | Stage tfvars. | ✓ |
<!-- END TFDOC -->

View File

@@ -33,6 +33,8 @@ projects:
overrides: {}
context:
# you can populate context variables here for use in YAML replacements
email_addresses:
gcp-organization-admins: gcp-organization-admins@example.com
iam_principals:
# this is the default group used in bootstrap, initial user must be a member
gcp-organization-admins: group:gcp-organization-admins@example.com

View File

@@ -18,8 +18,8 @@
id: $defaults:organization/id
contacts:
default:
- $iam_principals:gcp-organization-admins
$email_addresses:gcp-organization-admins:
- ALL
# conditional authoritative IAM bindings
iam_bindings:
# these don't conflict with IAM / IAM by principal

View File

@@ -33,6 +33,8 @@ projects:
overrides: {}
context:
# you can populate context variables here for use in YAML replacements
email_addresses:
gcp-organization-admins: gcp-organization-admins@example.com
iam_principals:
# this is the default group used in bootstrap, initial user must be a member
gcp-organization-admins: group:gcp-organization-admins@example.com

View File

@@ -18,8 +18,8 @@
id: $defaults:organization/id
contacts:
default:
- $iam_principals:gcp-organization-admins
$email_addresses:gcp-organization-admins:
- ALL
# conditional authoritative IAM bindings
iam_bindings:
# these don't conflict with IAM / IAM by principal

View File

@@ -538,6 +538,11 @@
"type": "string"
}
},
"email_addresses": {
"additionalProperties": {
"type": "string"
}
},
"folder_ids": {
"type": "object",
"additionalProperties": {

View File

@@ -64,6 +64,27 @@
}
}
},
"contacts": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^(\\S+@\\S+\\.\\S+|\\$email_addresses:\\S+)$": {
"type": "array",
"items": {
"type": "string",
"enum": [
"ALL",
"BILLING",
"LEGAL",
"SECURITY",
"PRODUCT_UPDATES",
"SUSPENSION",
"TECHNICAL"
]
}
}
}
},
"factories_config": {
"type": "object",
"additionalProperties": false,
@@ -552,4 +573,4 @@
}
}
}
}
}

View File

@@ -11,10 +11,19 @@
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$": {
"^(\\S+@\\S+\\.\\S+|\\$email_addresses:\\S+)$": {
"type": "array",
"items": {
"type": "string"
"type": "string",
"enum": [
"ALL",
"BILLING",
"LEGAL",
"SECURITY",
"PRODUCT_UPDATES",
"SUSPENSION",
"TECHNICAL"
]
}
}
}

View File

@@ -80,10 +80,19 @@
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9_-]+$": {
"^(\\S+@\\S+\\.\\S+|\\$email_addresses:\\S+)$": {
"type": "array",
"items": {
"type": "string"
"type": "string",
"enum": [
"ALL",
"BILLING",
"LEGAL",
"SECURITY",
"PRODUCT_UPDATES",
"SUSPENSION",
"TECHNICAL"
]
}
}
}
@@ -1005,4 +1014,4 @@
}
}
}
}
}

View File

@@ -18,6 +18,7 @@ variable "context" {
description = "Context-specific interpolations."
type = object({
custom_roles = optional(map(string), {})
email_addresses = optional(map(string), {})
folder_ids = optional(map(string), {})
iam_principals = optional(map(string), {})
locations = optional(map(string), {})

View File

@@ -52,7 +52,7 @@ resource "google_iam_workload_identity_pool_provider" "default" {
# If users don't provide an issuer_uri, we set the public one for the platform chosen.
issuer_uri = coalesce(
try(each.value.custom_settings.issuer_uri, null),
try(each.value.custom_settings.okta == null ? null : "https://${each.value.custom_settings.okta.organization_name}/oauth2/${each.value.custom_settings.okta.auth_server_name}", null),
try("https://${each.value.custom_settings.okta.organization_name}/oauth2/${each.value.custom_settings.okta.auth_server_name}", null),
try(each.value.issuer_uri, null),
)
# OIDC JWKs in JSON String format. If no value is provided, they key is

View File

@@ -316,9 +316,9 @@ Internally created resources are mapped to context namespaces, and use specific
| [billing_account](variables-fast.tf#L17) | Billing account id. | <code title="object&#40;&#123;&#10; id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [organization](variables-fast.tf#L49) | Organization details. | <code title="object&#40;&#123;&#10; id &#61; number&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [prefix](variables-fast.tf#L66) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | <code>string</code> | ✓ | |
| [context](variables.tf#L17) | Context-specific interpolations. | <code title="object&#40;&#123;&#10; cidr_ranges_sets &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; custom_roles &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; folder_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; kms_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; iam_principals &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; project_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; storage_buckets &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_values &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpc_sc_perimeters &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [context](variables.tf#L17) | Context-specific interpolations. | <code title="object&#40;&#123;&#10; cidr_ranges_sets &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; custom_roles &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; email_addresses &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; folder_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; kms_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; iam_principals &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; project_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; storage_buckets &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_values &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpc_sc_perimeters &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [custom_roles](variables-fast.tf#L25) | Custom roles defined at the org level, in key => id format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [factories_config](variables.tf#L36) | Configuration for the resource factories or external data. | <code title="object&#40;&#123;&#10; defaults &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;defaults.yaml&#34;&#41;&#10; dns &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;dns&#47;zones&#34;&#41;&#10; dns-response-policies &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;dns&#47;response-policies&#34;&#41;&#10; firewall-policies &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;firewall-policies&#34;&#41;&#10; folders &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;folders&#34;&#41;&#10; ncc-hubs &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;ncc-hubs&#34;&#41;&#10; nvas &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;nvas&#34;&#41;&#10; projects &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;projects&#34;&#41;&#10; vpcs &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;vpcs&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [factories_config](variables.tf#L37) | Configuration for the resource factories or external data. | <code title="object&#40;&#123;&#10; defaults &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;defaults.yaml&#34;&#41;&#10; dns &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;dns&#47;zones&#34;&#41;&#10; dns-response-policies &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;dns&#47;response-policies&#34;&#41;&#10; firewall-policies &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;firewall-policies&#34;&#41;&#10; folders &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;folders&#34;&#41;&#10; ncc-hubs &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;ncc-hubs&#34;&#41;&#10; nvas &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;nvas&#34;&#41;&#10; projects &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;projects&#34;&#41;&#10; vpcs &#61; optional&#40;string, &#34;datasets&#47;hub-and-spokes-peerings&#47;vpcs&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [folder_ids](variables-fast.tf#L33) | Folders created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [iam_principals](variables-fast.tf#L41) | IAM-format principals. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [perimeters](variables-fast.tf#L58) | Optional VPC-SC perimeter ids. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
@@ -327,7 +327,7 @@ Internally created resources are mapped to context namespaces, and use specific
| [storage_buckets](variables-fast.tf#L92) | Storage buckets created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [tag_keys](variables-fast.tf#L100) | FAST-managed resource manager tag keys. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [tag_values](variables-fast.tf#L108) | FAST-managed resource manager tag values. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [universe](variables.tf#L53) | GCP universe where to deploy projects. The prefix will be prepended to the project id. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; prefix &#61; string&#10; forced_jit_service_identities &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; unavailable_services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; unavailable_service_identities &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [universe](variables.tf#L54) | GCP universe where to deploy projects. The prefix will be prepended to the project id. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; prefix &#61; string&#10; forced_jit_service_identities &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; unavailable_services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; unavailable_service_identities &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
## Outputs

View File

@@ -549,6 +549,11 @@
"type": "string"
}
},
"email_addresses": {
"additionalProperties": {
"type": "string"
}
},
"folder_ids": {
"type": "object",
"additionalProperties": {

View File

@@ -64,6 +64,27 @@
}
}
},
"contacts": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^(\\S+@\\S+\\.\\S+|\\$email_addresses:\\S+)$": {
"type": "array",
"items": {
"type": "string",
"enum": [
"ALL",
"BILLING",
"LEGAL",
"SECURITY",
"PRODUCT_UPDATES",
"SUSPENSION",
"TECHNICAL"
]
}
}
}
},
"factories_config": {
"type": "object",
"additionalProperties": false,
@@ -552,4 +573,4 @@
}
}
}
}
}

View File

@@ -80,10 +80,19 @@
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9_-]+$": {
"^(\\S+@\\S+\\.\\S+|\\$email_addresses:\\S+)$": {
"type": "array",
"items": {
"type": "string"
"type": "string",
"enum": [
"ALL",
"BILLING",
"LEGAL",
"SECURITY",
"PRODUCT_UPDATES",
"SUSPENSION",
"TECHNICAL"
]
}
}
}
@@ -1005,4 +1014,4 @@
}
}
}
}
}

View File

@@ -19,6 +19,7 @@ variable "context" {
type = object({
cidr_ranges_sets = optional(map(list(string)), {})
custom_roles = optional(map(string), {})
email_addresses = optional(map(string), {})
folder_ids = optional(map(string), {})
kms_keys = optional(map(string), {})
iam_principals = optional(map(string), {})

View File

@@ -481,12 +481,12 @@ Pattern-based files make specific assumptions:
| [automation](variables-fast.tf#L17) | Automation resources created by the bootstrap stage. | <code title="object&#40;&#123;&#10; outputs_bucket &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-org-setup</code> |
| [billing_account](variables-fast.tf#L26) | Billing account id. | <code title="object&#40;&#123;&#10; id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-org-setup</code> |
| [prefix](variables-fast.tf#L82) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | <code>string</code> | ✓ | | <code>0-org-setup</code> |
| [context](variables.tf#L17) | Context-specific interpolations. | <code title="object&#40;&#123;&#10; condition_vars &#61; optional&#40;map&#40;map&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; custom_roles &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; folder_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; iam_principals &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; kms_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; notification_channels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; project_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_values &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpc_host_projects &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpc_sc_perimeters &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [context](variables.tf#L17) | Context-specific interpolations. | <code title="object&#40;&#123;&#10; condition_vars &#61; optional&#40;map&#40;map&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; custom_roles &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; email_addresses &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; folder_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; iam_principals &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; kms_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; notification_channels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; project_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_values &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpc_host_projects &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpc_sc_perimeters &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [custom_roles](variables-fast.tf#L34) | Custom roles defined at the org level, in key => id format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [data_defaults](variables-projects.tf#L17) | Optional default values used when corresponding project or folder data from files are missing. | <code title="object&#40;&#123;&#10; billing_account &#61; optional&#40;string&#41;&#10; bucket &#61; optional&#40;object&#40;&#123;&#10; force_destroy &#61; optional&#40;bool&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; deletion_policy &#61; optional&#40;string&#41;&#10; factories_config &#61; optional&#40;object&#40;&#123;&#10; custom_roles &#61; optional&#40;string&#41;&#10; observability &#61; optional&#40;string&#41;&#10; org_policies &#61; optional&#40;string&#41;&#10; quotas &#61; optional&#40;string&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;object&#40;&#123;&#10; bigquery &#61; optional&#40;string&#41;&#10; logging &#61; optional&#40;string&#41;&#10; storage &#61; optional&#40;string&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; logging_data_access &#61; optional&#40;map&#40;object&#40;&#123;&#10; ADMIN_READ &#61; optional&#40;object&#40;&#123; exempted_members &#61; optional&#40;list&#40;string&#41;&#41; &#125;&#41;&#41;,&#10; DATA_READ &#61; optional&#40;object&#40;&#123; exempted_members &#61; optional&#40;list&#40;string&#41;&#41; &#125;&#41;&#41;,&#10; DATA_WRITE &#61; optional&#40;object&#40;&#123; exempted_members &#61; optional&#40;list&#40;string&#41;&#41; &#125;&#41;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; metric_scopes &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; parent &#61; optional&#40;string&#41;&#10; prefix &#61; optional&#40;string&#41;&#10; project_reuse &#61; optional&#40;object&#40;&#123;&#10; use_data_source &#61; optional&#40;bool, true&#41;&#10; attributes &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; number &#61; number&#10; services_enabled &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string, &#34;Terraform-managed.&#34;&#41;&#10; iam_self_roles &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; shared_vpc_service_config &#61; optional&#40;object&#40;&#123;&#10; host_project &#61; string&#10; iam_bindings_additive &#61; optional&#40;map&#40;object&#40;&#123;&#10; member &#61; string&#10; role &#61; string&#10; condition &#61; optional&#40;object&#40;&#123;&#10; expression &#61; string&#10; title &#61; string&#10; description &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; network_users &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_agent_iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_agent_subnet_iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_iam_grants &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; network_subnet_users &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; &#125;&#41;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; universe &#61; optional&#40;object&#40;&#123;&#10; prefix &#61; string&#10; forced_jit_service_identities &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; unavailable_service_identities &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; unavailable_services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;&#41;&#10; vpc_sc &#61; optional&#40;object&#40;&#123;&#10; perimeter_name &#61; string&#10; is_dry_run &#61; optional&#40;bool, false&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [data_merges](variables-projects.tf#L93) | Optional values that will be merged with corresponding data from files. Combines with `data_defaults`, file data, and `data_overrides`. | <code title="object&#40;&#123;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; metric_scopes &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string, &#34;Terraform-managed.&#34;&#41;&#10; iam_self_roles &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [data_overrides](variables-projects.tf#L112) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | <code title="object&#40;&#123;&#10; billing_account &#61; optional&#40;string&#41;&#10; bucket &#61; optional&#40;object&#40;&#123;&#10; force_destroy &#61; optional&#40;bool&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;&#41;&#10; deletion_policy &#61; optional&#40;string&#41;&#10; factories_config &#61; optional&#40;object&#40;&#123;&#10; custom_roles &#61; optional&#40;string&#41;&#10; observability &#61; optional&#40;string&#41;&#10; org_policies &#61; optional&#40;string&#41;&#10; quotas &#61; optional&#40;string&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;object&#40;&#123;&#10; bigquery &#61; optional&#40;string&#41;&#10; logging &#61; optional&#40;string&#41;&#10; storage &#61; optional&#40;string&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; logging_data_access &#61; optional&#40;map&#40;object&#40;&#123;&#10; ADMIN_READ &#61; optional&#40;object&#40;&#123; exempted_members &#61; optional&#40;list&#40;string&#41;&#41; &#125;&#41;&#41;,&#10; DATA_READ &#61; optional&#40;object&#40;&#123; exempted_members &#61; optional&#40;list&#40;string&#41;&#41; &#125;&#41;&#41;,&#10; DATA_WRITE &#61; optional&#40;object&#40;&#123; exempted_members &#61; optional&#40;list&#40;string&#41;&#41; &#125;&#41;&#41;&#10; &#125;&#41;&#41;&#41;&#10; parent &#61; optional&#40;string&#41;&#10; prefix &#61; optional&#40;string&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string, &#34;Terraform-managed.&#34;&#41;&#10; iam_self_roles &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;&#41;&#10; universe &#61; optional&#40;object&#40;&#123;&#10; prefix &#61; string&#10; forced_jit_service_identities &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; unavailable_service_identities &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; unavailable_services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;&#41;&#10; vpc_sc &#61; optional&#40;object&#40;&#123;&#10; perimeter_name &#61; string&#10; is_dry_run &#61; optional&#40;bool, false&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [factories_config](variables.tf#L36) | Path to folder with YAML resource description data files. | <code title="object&#40;&#123;&#10; defaults &#61; optional&#40;string, &#34;data&#47;defaults.yaml&#34;&#41;&#10; folders &#61; optional&#40;string, &#34;data&#47;folders&#34;&#41;&#10; projects &#61; optional&#40;string, &#34;data&#47;projects&#34;&#41;&#10; budgets &#61; optional&#40;object&#40;&#123;&#10; billing_account_id &#61; string&#10; data &#61; string&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [factories_config](variables.tf#L37) | Path to folder with YAML resource description data files. | <code title="object&#40;&#123;&#10; defaults &#61; optional&#40;string, &#34;data&#47;defaults.yaml&#34;&#41;&#10; folders &#61; optional&#40;string, &#34;data&#47;folders&#34;&#41;&#10; projects &#61; optional&#40;string, &#34;data&#47;projects&#34;&#41;&#10; budgets &#61; optional&#40;object&#40;&#123;&#10; billing_account_id &#61; string&#10; data &#61; string&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [folder_ids](variables-fast.tf#L42) | Folders created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [host_project_ids](variables-fast.tf#L58) | Host project for the shared VPC. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>2-networking</code> |
| [iam_principals](variables-fast.tf#L50) | IAM-format principals. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
@@ -494,7 +494,7 @@ Pattern-based files make specific assumptions:
| [perimeters](variables-fast.tf#L74) | Optional VPC-SC perimeter ids. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>1-vpcsc</code> |
| [project_ids](variables-fast.tf#L92) | Projects created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [service_accounts](variables-fast.tf#L100) | Service accounts created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [stage_name](variables.tf#L57) | FAST stage name. Used to separate output files across different factories. | <code>string</code> | | <code>&#34;2-project-factory&#34;</code> | |
| [stage_name](variables.tf#L58) | FAST stage name. Used to separate output files across different factories. | <code>string</code> | | <code>&#34;2-project-factory&#34;</code> | |
| [subnet_self_links](variables-fast.tf#L108) | Shared VPC subnet IDs. | <code>map&#40;map&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | <code>2-networking</code> |
| [tag_values](variables-fast.tf#L116) | FAST-managed resource manager tag values. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [universe](variables-fast.tf#L124) | GCP universe where to deploy projects. The prefix will be prepended to the project id. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; prefix &#61; string&#10; forced_jit_service_identities &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; unavailable_services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; unavailable_service_identities &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>0-org-setup</code> |

View File

@@ -572,6 +572,11 @@
"type": "string"
}
},
"email_addresses": {
"additionalProperties": {
"type": "string"
}
},
"folder_ids": {
"type": "object",
"additionalProperties": {

View File

@@ -1 +0,0 @@
../../../../modules/project-factory/schemas/folder.schema.json

View File

@@ -0,0 +1,576 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Folder",
"type": "object",
"additionalProperties": false,
"properties": {
"automation": {
"type": "object",
"additionalProperties": false,
"required": [
"project"
],
"properties": {
"prefix": {
"type": "string"
},
"project": {
"type": "string"
},
"bucket": {
"$ref": "#/$defs/bucket"
},
"service_accounts": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"description": {
"type": "string"
},
"iam": {
"$ref": "#/$defs/iam"
},
"iam_bindings": {
"$ref": "#/$defs/iam_bindings"
},
"iam_bindings_additive": {
"$ref": "#/$defs/iam_bindings_additive"
},
"iam_billing_roles": {
"$ref": "#/$defs/iam_billing_roles"
},
"iam_folder_roles": {
"$ref": "#/$defs/iam_folder_roles"
},
"iam_organization_roles": {
"$ref": "#/$defs/iam_organization_roles"
},
"iam_project_roles": {
"$ref": "#/$defs/iam_project_roles"
},
"iam_sa_roles": {
"$ref": "#/$defs/iam_sa_roles"
},
"iam_storage_roles": {
"$ref": "#/$defs/iam_storage_roles"
}
}
}
}
}
}
},
"contacts": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^(\\S+@\\S+\\.\\S+|\\$email_addresses:\\S+)$": {
"type": "array",
"items": {
"type": "string",
"enum": [
"ALL",
"BILLING",
"LEGAL",
"SECURITY",
"PRODUCT_UPDATES",
"SUSPENSION",
"TECHNICAL"
]
}
}
}
},
"factories_config": {
"type": "object",
"additionalProperties": false,
"properties": {
"org_policies": {
"type": "string"
},
"pam_entitlements": {
"type": "string"
},
"scc_sha_custom_modules": {
"type": "string"
}
}
},
"iam": {
"$ref": "#/$defs/iam"
},
"iam_bindings": {
"$ref": "#/$defs/iam_bindings"
},
"iam_bindings_additive": {
"$ref": "#/$defs/iam_bindings_additive"
},
"iam_by_principals": {
"$ref": "#/$defs/iam_by_principals"
},
"name": {
"type": "string"
},
"org_policies": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z]+\\.": {
"type": "object",
"properties": {
"inherit_from_parent": {
"type": "boolean"
},
"reset": {
"type": "boolean"
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"type": "boolean"
},
"values": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"deny": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"type": "boolean"
},
"values": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"enforce": {
"type": "boolean"
},
"condition": {
"type": "object",
"additionalProperties": false,
"properties": {
"description": {
"type": "string"
},
"expression": {
"type": "string"
},
"location": {
"type": "string"
},
"title": {
"type": "string"
}
}
}
}
}
}
}
}
}
},
"pam_entitlements": {
"$ref": "#/$defs/pam_entitlements"
},
"parent": {
"type": "string",
"pattern": "^(?:folders/[0-9]+|organizations/[0-9]+|\\$folder_ids:[a-z0-9_-]+)$"
},
"tag_bindings": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9_-]+$": {
"type": "string"
}
}
}
},
"$defs": {
"bucket": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"iam": {
"$ref": "#/$defs/iam"
},
"iam_bindings": {
"$ref": "#/$defs/iam_bindings"
},
"iam_bindings_additive": {
"$ref": "#/$defs/iam_bindings_additive"
},
"force_destroy": {
"type": "boolean"
},
"labels": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"location": {
"type": "string"
},
"managed_folders": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-zA-Z0-9][a-zA-Z0-9_/-]+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"force_destroy": {
"type": "boolean"
},
"iam": {
"$ref": "#/$defs/iam"
},
"iam_bindings": {
"$ref": "#/$defs/iam_bindings"
},
"iam_bindings_additive": {
"$ref": "#/$defs/iam_bindings_additive"
}
}
}
}
},
"prefix": {
"type": "string"
},
"storage_class": {
"type": "string"
},
"uniform_bucket_level_access": {
"type": "boolean"
},
"versioning": {
"type": "boolean"
}
}
},
"iam": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^(?:roles/|\\$custom_roles:)": {
"type": "array",
"items": {
"type": "string",
"pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:)"
}
}
}
},
"iam_bindings": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9_-]+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"members": {
"type": "array",
"items": {
"type": "string",
"pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:)"
}
},
"role": {
"type": "string",
"pattern": "^(?:roles/|\\$custom_roles:)"
},
"condition": {
"type": "object",
"additionalProperties": false,
"required": [
"expression",
"title"
],
"properties": {
"expression": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
}
}
}
}
}
}
},
"iam_bindings_additive": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9_-]+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"member": {
"type": "string",
"pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:)"
},
"role": {
"type": "string",
"pattern": "^(?:roles/|\\$custom_roles:)"
},
"condition": {
"type": "object",
"additionalProperties": false,
"required": [
"expression",
"title"
],
"properties": {
"expression": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
}
}
}
}
}
}
},
"iam_by_principals": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:)": {
"type": "array",
"items": {
"type": "string",
"pattern": "^(?:roles/|\\$custom_roles:)"
}
}
}
},
"iam_billing_roles": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"iam_folder_roles": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"iam_organization_roles": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"iam_project_roles": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"iam_sa_roles": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"iam_storage_roles": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"pam_entitlements": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z][a-z0-9-]{0,61}[a-z0-9]$": {
"type": "object",
"properties": {
"max_request_duration": {
"type": "string"
},
"eligible_users": {
"type": "array",
"items": {
"type": "string"
}
},
"privileged_access": {
"type": "array",
"items": {
"type": "object",
"properties": {
"role": {
"type": "string"
},
"condition": {
"type": "string"
}
},
"required": [
"role"
],
"additionalProperties": false
}
},
"requester_justification_config": {
"type": "object",
"properties": {
"not_mandatory": {
"type": "boolean"
},
"unstructured": {
"type": "boolean"
}
},
"additionalProperties": false
},
"manual_approvals": {
"type": "object",
"properties": {
"require_approver_justification": {
"type": "boolean"
},
"steps": {
"type": "array",
"items": {
"type": "object",
"properties": {
"approvers": {
"type": "array",
"items": {
"type": "string"
}
},
"approvals_needed": {
"type": "number"
},
"approver_email_recipients": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"approvers"
],
"additionalProperties": false
}
}
},
"required": [
"require_approver_justification",
"steps"
],
"additionalProperties": false
},
"additional_notification_targets": {
"type": "object",
"properties": {
"admin_email_recipients": {
"type": "array",
"items": {
"type": "string"
}
},
"requester_email_recipients": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
}
},
"required": [
"max_request_duration",
"eligible_users",
"privileged_access"
],
"additionalProperties": false
}
}
}
}
}

View File

@@ -1 +0,0 @@
../../../../modules/project-factory/schemas/project.schema.json

File diff suppressed because it is too large Load Diff

View File

@@ -19,6 +19,7 @@ variable "context" {
type = object({
condition_vars = optional(map(map(string)), {})
custom_roles = optional(map(string), {})
email_addresses = optional(map(string), {})
folder_ids = optional(map(string), {})
iam_principals = optional(map(string), {})
kms_keys = optional(map(string), {})

View File

@@ -183,9 +183,9 @@ A reference Certificate Authority Services (CAS) is also part of this stage, all
|---|---|:---:|:---:|:---:|:---:|
| [billing_account](variables-fast.tf#L17) | Billing account id. | <code title="object&#40;&#123;&#10; id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-org-setup</code> |
| [prefix](variables-fast.tf#L57) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | <code>string</code> | ✓ | | <code>0-org-setup</code> |
| [context](variables.tf#L17) | Context-specific interpolations. | <code title="object&#40;&#123;&#10; condition_vars &#61; optional&#40;map&#40;map&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; custom_roles &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; folder_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; iam_principals &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; project_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; storage_buckets &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_values &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpc_sc_perimeters &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [context](variables.tf#L17) | Context-specific interpolations. | <code title="object&#40;&#123;&#10; condition_vars &#61; optional&#40;map&#40;map&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; email_addresses &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; custom_roles &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; folder_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; iam_principals &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; project_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; storage_buckets &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_keys &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; tag_values &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpc_sc_perimeters &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [custom_roles](variables-fast.tf#L25) | Custom roles defined at the org level, in key => id format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [factories_config](variables.tf#L35) | Configuration for the resource factories or external data. | <code title="object&#40;&#123;&#10; certificate_authorities &#61; optional&#40;string&#41; &#35; &#34;data&#47;certificate-authorities&#34;&#10; defaults &#61; optional&#40;string, &#34;data&#47;defaults.yaml&#34;&#41;&#10; folders &#61; optional&#40;string, &#34;data&#47;folders&#34;&#41;&#10; keyrings &#61; optional&#40;string, &#34;data&#47;keyrings&#34;&#41;&#10; projects &#61; optional&#40;string, &#34;data&#47;projects&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [factories_config](variables.tf#L36) | Configuration for the resource factories or external data. | <code title="object&#40;&#123;&#10; certificate_authorities &#61; optional&#40;string&#41; &#35; &#34;data&#47;certificate-authorities&#34;&#10; defaults &#61; optional&#40;string, &#34;data&#47;defaults.yaml&#34;&#41;&#10; folders &#61; optional&#40;string, &#34;data&#47;folders&#34;&#41;&#10; keyrings &#61; optional&#40;string, &#34;data&#47;keyrings&#34;&#41;&#10; projects &#61; optional&#40;string, &#34;data&#47;projects&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [folder_ids](variables-fast.tf#L33) | Folders created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [iam_principals](variables-fast.tf#L41) | IAM-format principals. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [perimeters](variables-fast.tf#L49) | Optional VPC-SC perimeter ids. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>1-vpcsc</code> |

View File

@@ -522,6 +522,12 @@
"type": "string"
}
},
"email_addresses": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"folder_ids": {
"type": "object",
"additionalProperties": {

View File

@@ -0,0 +1,576 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Folder",
"type": "object",
"additionalProperties": false,
"properties": {
"automation": {
"type": "object",
"additionalProperties": false,
"required": [
"project"
],
"properties": {
"prefix": {
"type": "string"
},
"project": {
"type": "string"
},
"bucket": {
"$ref": "#/$defs/bucket"
},
"service_accounts": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"description": {
"type": "string"
},
"iam": {
"$ref": "#/$defs/iam"
},
"iam_bindings": {
"$ref": "#/$defs/iam_bindings"
},
"iam_bindings_additive": {
"$ref": "#/$defs/iam_bindings_additive"
},
"iam_billing_roles": {
"$ref": "#/$defs/iam_billing_roles"
},
"iam_folder_roles": {
"$ref": "#/$defs/iam_folder_roles"
},
"iam_organization_roles": {
"$ref": "#/$defs/iam_organization_roles"
},
"iam_project_roles": {
"$ref": "#/$defs/iam_project_roles"
},
"iam_sa_roles": {
"$ref": "#/$defs/iam_sa_roles"
},
"iam_storage_roles": {
"$ref": "#/$defs/iam_storage_roles"
}
}
}
}
}
}
},
"contacts": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^(\\S+@\\S+\\.\\S+|\\$email_addresses:\\S+)$": {
"type": "array",
"items": {
"type": "string",
"enum": [
"ALL",
"BILLING",
"LEGAL",
"SECURITY",
"PRODUCT_UPDATES",
"SUSPENSION",
"TECHNICAL"
]
}
}
}
},
"factories_config": {
"type": "object",
"additionalProperties": false,
"properties": {
"org_policies": {
"type": "string"
},
"pam_entitlements": {
"type": "string"
},
"scc_sha_custom_modules": {
"type": "string"
}
}
},
"iam": {
"$ref": "#/$defs/iam"
},
"iam_bindings": {
"$ref": "#/$defs/iam_bindings"
},
"iam_bindings_additive": {
"$ref": "#/$defs/iam_bindings_additive"
},
"iam_by_principals": {
"$ref": "#/$defs/iam_by_principals"
},
"name": {
"type": "string"
},
"org_policies": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z]+\\.": {
"type": "object",
"properties": {
"inherit_from_parent": {
"type": "boolean"
},
"reset": {
"type": "boolean"
},
"rules": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"type": "boolean"
},
"values": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"deny": {
"type": "object",
"additionalProperties": false,
"properties": {
"all": {
"type": "boolean"
},
"values": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"enforce": {
"type": "boolean"
},
"condition": {
"type": "object",
"additionalProperties": false,
"properties": {
"description": {
"type": "string"
},
"expression": {
"type": "string"
},
"location": {
"type": "string"
},
"title": {
"type": "string"
}
}
}
}
}
}
}
}
}
},
"pam_entitlements": {
"$ref": "#/$defs/pam_entitlements"
},
"parent": {
"type": "string",
"pattern": "^(?:folders/[0-9]+|organizations/[0-9]+|\\$folder_ids:[a-z0-9_-]+)$"
},
"tag_bindings": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9_-]+$": {
"type": "string"
}
}
}
},
"$defs": {
"bucket": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"iam": {
"$ref": "#/$defs/iam"
},
"iam_bindings": {
"$ref": "#/$defs/iam_bindings"
},
"iam_bindings_additive": {
"$ref": "#/$defs/iam_bindings_additive"
},
"force_destroy": {
"type": "boolean"
},
"labels": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"location": {
"type": "string"
},
"managed_folders": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-zA-Z0-9][a-zA-Z0-9_/-]+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"force_destroy": {
"type": "boolean"
},
"iam": {
"$ref": "#/$defs/iam"
},
"iam_bindings": {
"$ref": "#/$defs/iam_bindings"
},
"iam_bindings_additive": {
"$ref": "#/$defs/iam_bindings_additive"
}
}
}
}
},
"prefix": {
"type": "string"
},
"storage_class": {
"type": "string"
},
"uniform_bucket_level_access": {
"type": "boolean"
},
"versioning": {
"type": "boolean"
}
}
},
"iam": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^(?:roles/|\\$custom_roles:)": {
"type": "array",
"items": {
"type": "string",
"pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:)"
}
}
}
},
"iam_bindings": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9_-]+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"members": {
"type": "array",
"items": {
"type": "string",
"pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:)"
}
},
"role": {
"type": "string",
"pattern": "^(?:roles/|\\$custom_roles:)"
},
"condition": {
"type": "object",
"additionalProperties": false,
"required": [
"expression",
"title"
],
"properties": {
"expression": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
}
}
}
}
}
}
},
"iam_bindings_additive": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9_-]+$": {
"type": "object",
"additionalProperties": false,
"properties": {
"member": {
"type": "string",
"pattern": "^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:)"
},
"role": {
"type": "string",
"pattern": "^(?:roles/|\\$custom_roles:)"
},
"condition": {
"type": "object",
"additionalProperties": false,
"required": [
"expression",
"title"
],
"properties": {
"expression": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
}
}
}
}
}
}
},
"iam_by_principals": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^(?:domain:|group:|serviceAccount:|user:|principal:|principalSet:|\\$iam_principals:)": {
"type": "array",
"items": {
"type": "string",
"pattern": "^(?:roles/|\\$custom_roles:)"
}
}
}
},
"iam_billing_roles": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"iam_folder_roles": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"iam_organization_roles": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"iam_project_roles": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"iam_sa_roles": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"iam_storage_roles": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"pam_entitlements": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z][a-z0-9-]{0,61}[a-z0-9]$": {
"type": "object",
"properties": {
"max_request_duration": {
"type": "string"
},
"eligible_users": {
"type": "array",
"items": {
"type": "string"
}
},
"privileged_access": {
"type": "array",
"items": {
"type": "object",
"properties": {
"role": {
"type": "string"
},
"condition": {
"type": "string"
}
},
"required": [
"role"
],
"additionalProperties": false
}
},
"requester_justification_config": {
"type": "object",
"properties": {
"not_mandatory": {
"type": "boolean"
},
"unstructured": {
"type": "boolean"
}
},
"additionalProperties": false
},
"manual_approvals": {
"type": "object",
"properties": {
"require_approver_justification": {
"type": "boolean"
},
"steps": {
"type": "array",
"items": {
"type": "object",
"properties": {
"approvers": {
"type": "array",
"items": {
"type": "string"
}
},
"approvals_needed": {
"type": "number"
},
"approver_email_recipients": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"approvers"
],
"additionalProperties": false
}
}
},
"required": [
"require_approver_justification",
"steps"
],
"additionalProperties": false
},
"additional_notification_targets": {
"type": "object",
"properties": {
"admin_email_recipients": {
"type": "array",
"items": {
"type": "string"
}
},
"requester_email_recipients": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
}
},
"required": [
"max_request_duration",
"eligible_users",
"privileged_access"
],
"additionalProperties": false
}
}
}
}
}

View File

@@ -80,10 +80,19 @@
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9_-]+$": {
"^(\\S+@\\S+\\.\\S+|\\$email_addresses:\\S+)$": {
"type": "array",
"items": {
"type": "string"
"type": "string",
"enum": [
"ALL",
"BILLING",
"LEGAL",
"SECURITY",
"PRODUCT_UPDATES",
"SUSPENSION",
"TECHNICAL"
]
}
}
}
@@ -1005,4 +1014,4 @@
}
}
}
}
}

View File

@@ -18,6 +18,7 @@ variable "context" {
description = "Context-specific interpolations."
type = object({
condition_vars = optional(map(map(string)), {})
email_addresses = optional(map(string), {})
custom_roles = optional(map(string), {})
folder_ids = optional(map(string), {})
iam_principals = optional(map(string), {})