Add support for org-level service agents in stage 0 (#3962)

* Add support for org-level service agents in stage 0

* update schema doc

* Fix service agents context key separator
This commit is contained in:
Ludovico Magnocavallo
2026-05-14 14:36:34 +02:00
committed by GitHub
parent 2c489cfd32
commit 332b516ae8
24 changed files with 2281 additions and 4 deletions

View File

@@ -406,7 +406,7 @@ The default paths point to the dataset in the `datasets/classic` folder which de
- **billing_accounts** (`[dataset]/billing-accounts`) \
folder-level factory where each YAML file defines billing-account level IAM for one billing account; only used for externally managed accounts
- **organization** (`[dataset]/organization/.config.yaml`) \
file-level factory to define organization IAM and log sinks
file-level factory to define organization IAM, service agents, and log sinks
- **custom roles** (`[dataset]/organization/custom-roles`) \
folder-level factory to define organization-level custom roles
- **org policies** (`[dataset]/organization/org-policies`) \
@@ -515,7 +515,7 @@ logging_sinks:
### Organization configuration
The default dataset implements a classic FAST design, recreating the required custom roles, IAM bindings, org policies, tags, and log sinks via the factories described in a previous section.
The default dataset implements a classic FAST design, recreating the required custom roles, IAM bindings, org policies, tags, service agents, and log sinks via the factories described in a previous section.
Compared to classic FAST this approach makes org-level configuration explicit, allowing easy customization of IAM and all other attributes. Before running this stage, check that the data files match your expected design.

View File

@@ -61,6 +61,8 @@ iam_by_principals:
- roles/iam.workforcePoolAdmin
- roles/logging.admin
- roles/orgpolicy.policyAdmin
# Uncomment to allow managing PAM entitlements.
# - roles/privilegedaccessmanager.admin
- roles/resourcemanager.folderAdmin
- roles/resourcemanager.organizationAdmin
- roles/resourcemanager.projectCreator
@@ -74,6 +76,8 @@ iam_by_principals:
- roles/iam.workforcePoolViewer
- roles/logging.viewer
- roles/orgpolicy.policyViewer
# Uncomment to allow viewing PAM entitlements.
# - roles/privilegedaccessmanager.viewer
- roles/resourcemanager.folderViewer
- roles/resourcemanager.tagViewer
- roles/serviceusage.serviceUsageViewer

View File

@@ -90,7 +90,8 @@ module "organization" {
email_addresses = local.ctx.email_addresses
locations = local.ctx.locations
}
contacts = lookup(local.organization, "contacts", {})
contacts = lookup(local.organization, "contacts", {})
service_agents_config = lookup(local.organization, "service_agents_config", {})
factories_config = {
custom_roles = "${local.paths.organization}/custom-roles"
tags = "${local.paths.organization}/tags"
@@ -122,7 +123,11 @@ module "organization-iam" {
)
iam_principals = merge(
local.ctx.iam_principals,
module.factory.iam_principals
module.factory.iam_principals,
{
for k, v in module.organization[0].service_agents :
"service_agents/${k}" => v.iam_email
}
)
log_buckets = module.factory.log_buckets
project_ids = merge(

View File

@@ -305,6 +305,21 @@
"pam_entitlements": {
"$ref": "#/$defs/pam_entitlements"
},
"service_agents_config": {
"type": "object",
"additionalProperties": false,
"properties": {
"create_agents": {
"type": "boolean"
},
"services": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"tags": {
"type": "object",
"additionalProperties": {

View File

@@ -96,6 +96,11 @@
- **location**: *string*
- **title**: *string*
- **pam_entitlements**: *reference([pam_entitlements](#refs-pam_entitlements))*
- **service_agents_config**: *object*
<br>*additional properties: false*
- **create_agents**: *boolean*
- **services**: *array*
- items: *string*
- **tags**: *object*
<br>*additional properties: object*
- **workforce_identity_pools**: *object*

View File

@@ -0,0 +1,6 @@
factories_config = {
paths = {
defaults = "./data-customizations/defaults.yaml"
organization = "./data-customizations/organization"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../../fast/stages/0-org-setup/schemas/defaults.schema.json
# defaults:
# storage_location: europe-west1
global:
billing_account: 012345-012345-012345
organization:
domain: example.org
id: 1234567890
customer_id: abcd123456
projects:
defaults:
prefix: ft0
locations:
bigquery: $locations:primary
logging: $locations:primary
storage: $locations:primary
overrides: {}
output_files:
local_path: /tmp/fast-config
storage_bucket: $storage_buckets:iac-0/iac-outputs
providers:
0-org-setup:
bucket: $storage_buckets:iac-0/iac-org-state
service_account: $iam_principals:service_accounts/iac-0/iac-org-rw
0-org-setup-ro:
bucket: $storage_buckets:iac-0/iac-org-state
service_account: $iam_principals:service_accounts/iac-0/iac-org-rw
1-vpcsc:
bucket: $storage_buckets:iac-0/iac-stage-state
prefix: 1-vpcsc
service_account: $iam_principals:service_accounts/iac-0/iac-vpcsc-rw
2-networking:
bucket: $storage_buckets:iac-0/iac-stage-state
prefix: 2-networking
service_account: $iam_principals:service_accounts/iac-0/iac-networking-rw
2-security:
bucket: $storage_buckets:iac-0/iac-stage-state
prefix: 2-security
service_account: $iam_principals:service_accounts/iac-0/iac-security-rw
2-project-factory:
bucket: $storage_buckets:iac-0/iac-stage-state
prefix: 2-project-factory
service_account: $iam_principals:service_accounts/iac-0/iac-pf-rw
context:
iam_principals:
gcp-organization-admins: group:fabric-fast-owners@google.com
locations:
primary: europe-west1
workload_identity_providers:
iac-0/default/github-default: projects/1234567890/locations/global/workloadIdentityPools/default

View File

@@ -0,0 +1,19 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../schemas/folder.schema.json
name: Development
tag_bindings:
environment: $tag_values:environment/development

View File

@@ -0,0 +1,19 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../schemas/folder.schema.json
name: Production
tag_bindings:
environment: $tag_values:environment/production

View File

@@ -0,0 +1,66 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# TODO: data access logs
# yaml-language-server: $schema=../../../schemas/organization.schema.json
id: $defaults:organization/id
service_agents_config:
services:
- privilegedaccessmanager.googleapis.com
iam_by_principals:
$iam_principals:gcp-organization-admins:
- roles/cloudasset.owner
- roles/cloudsupport.admin
- roles/cloudsupport.techSupportEditor
- roles/compute.osAdminLogin
- roles/compute.osLoginExternalUser
- roles/compute.xpnAdmin
- roles/orgpolicy.policyAdmin
- roles/owner
- roles/resourcemanager.folderAdmin
- roles/resourcemanager.organizationAdmin
- roles/resourcemanager.projectCreator
- roles/resourcemanager.tagAdmin
- roles/iam.workforcePoolAdmin
$iam_principals:service_accounts/iac-0/iac-org-rw:
- roles/accesscontextmanager.policyAdmin
- roles/cloudasset.viewer
- roles/essentialcontacts.admin
- roles/iam.organizationRoleAdmin
- roles/iam.workforcePoolAdmin
- roles/logging.admin
- roles/orgpolicy.policyAdmin
- roles/privilegedaccessmanager.admin
- roles/resourcemanager.folderAdmin
- roles/resourcemanager.organizationAdmin
- roles/resourcemanager.projectCreator
- roles/resourcemanager.projectMover
- roles/resourcemanager.tagAdmin
- roles/resourcemanager.tagUser
"$iam_principals:service_agents/pam":
- roles/viewer
logging:
sinks:
audit-logs:
destination: $log_buckets:iac-0/audit-logs
filter: |
log_id("cloudaudit.googleapis.com/activity") OR
log_id("cloudaudit.googleapis.com/system_event") OR
log_id("cloudaudit.googleapis.com/policy") OR
log_id("cloudaudit.googleapis.com/access_transparency")
iam:
roles/billing.creator: []

View File

@@ -0,0 +1,43 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../schemas/tags.schema.json
description: "Organization-level environments."
# iam:
# "roles/resourcemanager.tagViewer":
# - "group:finance-team@example.com"
values:
development:
description: "Development."
iam:
"roles/resourcemanager.tagUser":
- $iam_principals:service_accounts/iac-0/iac-networking-rw
- $iam_principals:service_accounts/iac-0/iac-security-rw
- $iam_principals:service_accounts/iac-0/iac-pf-rw
"roles/resourcemanager.tagViewer":
- $iam_principals:service_accounts/iac-0/iac-networking-ro
- $iam_principals:service_accounts/iac-0/iac-security-ro
- $iam_principals:service_accounts/iac-0/iac-pf-ro
production:
description: "Production."
iam:
"roles/resourcemanager.tagUser":
- $iam_principals:service_accounts/iac-0/iac-networking-rw
- $iam_principals:service_accounts/iac-0/iac-security-rw
- $iam_principals:service_accounts/iac-0/iac-pf-rw
"roles/resourcemanager.tagViewer":
- $iam_principals:service_accounts/iac-0/iac-networking-ro
- $iam_principals:service_accounts/iac-0/iac-security-ro
- $iam_principals:service_accounts/iac-0/iac-pf-ro

View File

@@ -0,0 +1,26 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../schemas/project.schema.json
name: dev-app-example-0
parent: $folder_ids:dev
services:
- bigquery.googleapis.com
- compute.googleapis.com
- logging.googleapis.com
- monitoring.googleapis.com
- storage.googleapis.com
shared_vpc_service_config:
host_project: $project_ids:dev-net-0

View File

@@ -0,0 +1,26 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../schemas/project.schema.json
name: prod-app-example-0
parent: $folder_ids:prod
services:
- bigquery.googleapis.com
- compute.googleapis.com
- logging.googleapis.com
- monitoring.googleapis.com
- storage.googleapis.com
shared_vpc_service_config:
host_project: $project_ids:prod-net-0

View File

@@ -0,0 +1,73 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../schemas/project.schema.json
name: prod-iac-core-0
iam_by_principals:
$iam_principals:gcp-organization-admins:
- roles/iam.serviceAccountTokenCreator
- roles/iam.workloadIdentityPoolAdmin
$iam_principals:service_accounts/iac-0/iac-org-rw:
- roles/cloudbuild.builds.editor
- roles/iam.serviceAccountAdmin
- roles/iam.workloadIdentityPoolAdmin
- roles/owner
- roles/storage.admin
services:
- accesscontextmanager.googleapis.com
- bigquery.googleapis.com
- bigquerystorage.googleapis.com
- cloudbilling.googleapis.com
- cloudkms.googleapis.com
- cloudresourcemanager.googleapis.com
- compute.googleapis.com
- container.googleapis.com
- essentialcontacts.googleapis.com
- iam.googleapis.com
- iamcredentials.googleapis.com
- logging.googleapis.com
- monitoring.googleapis.com
- orgpolicy.googleapis.com
- pubsub.googleapis.com
- serviceusage.googleapis.com
- storage-component.googleapis.com
- storage.googleapis.com
- sts.googleapis.com
buckets:
iac-org-state:
description: Terraform state for the org-level automation.
versioning: true
iam:
roles/storage.admin:
- $iam_principals:service_accounts/iac-0/iac-org-rw
$custom_roles:storage_viewer:
- $iam_principals:service_accounts/iac-0/iac-org-ro
iac-outputs:
description: Terraform state for the org-level automation.
versioning: true
iam:
roles/storage.admin:
- $iam_principals:service_accounts/iac-0/iac-org-rw
service_accounts:
iac-org-rw:
display_name: IaC service account for org setup (read-write).
datasets:
billing_export:
friendly_name: Billing export
log_buckets:
audit-logs:
log_analytics:
enable: true
retention: 31

View File

@@ -0,0 +1,27 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../schemas/project.schema.json
name: dev-net-shared-0
parent: $folder_ids:dev
services:
- container.googleapis.com
- compute.googleapis.com
- dns.googleapis.com
- iap.googleapis.com
- logging.googleapis.com
- monitoring.googleapis.com
shared_vpc_host_config:
enabled: true

View File

@@ -0,0 +1,27 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../schemas/project.schema.json
name: prod-net-shared-0
parent: $folder_ids:prod
services:
- container.googleapis.com
- compute.googleapis.com
- dns.googleapis.com
- iap.googleapis.com
- logging.googleapis.com
- monitoring.googleapis.com
shared_vpc_host_config:
enabled: true

View File

@@ -0,0 +1,19 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../schemas/vpc-factory.schema.json
name: dev-shared-0
project_id: $project_ids:dev-net-0
auto_create_subnetworks: false

View File

@@ -0,0 +1,42 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../../schemas/firewall-rules.schema.json
ingress:
ingress-default-allow-iap:
description: Allow IAP.
source_ranges:
- 35.235.240.0/20
rules:
- protocol: all
ports: []
ingress-default-allow-healthchecks:
description: Allow GCP Healthcheck Ranges.
source_ranges:
- 35.191.0.0/16
- 130.211.0.0/22
- 209.85.152.0/22
- 209.85.204.0/22
rules:
- protocol: all
ports: []
ingress-default-allow-icmp:
description: Allow ICMP.
rules:
- protocol: icmp
ports: []

View File

@@ -0,0 +1,20 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../../schemas/subnet.schema.json
name: default
region: $locations:primary
ip_cidr_range: 10.0.0.0/24
description: Default primary-region subnet for dev

View File

@@ -0,0 +1,19 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../schemas/vpc-factory.schema.json
name: prod-shared-0
project_id: $project_ids:prod-net-0
auto_create_subnetworks: false

View File

@@ -0,0 +1,42 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../../schemas/firewall-rules.schema.json
ingress:
ingress-default-allow-iap:
description: Allow IAP.
source_ranges:
- 35.235.240.0/20
rules:
- protocol: all
ports: []
ingress-default-allow-healthchecks:
description: Allow GCP Healthcheck Ranges.
source_ranges:
- 35.191.0.0/16
- 130.211.0.0/22
- 209.85.152.0/22
- 209.85.204.0/22
rules:
- protocol: all
ports: []
ingress-default-allow-icmp:
description: Allow ICMP.
rules:
- protocol: icmp
ports: []

View File

@@ -0,0 +1,20 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# yaml-language-server: $schema=../../../../../schemas/subnet.schema.json
name: default
region: $locations:primary
ip_cidr_range: 10.0.0.0/24
description: Default primary-region subnet for prod

View File

@@ -30,3 +30,8 @@ tests:
- starter-gcd.yaml
extra_dirs:
- ../../../tests/fast/stages/s0_org_setup/data-starter-gcd
customizations:
inventory:
- customizations.yaml
extra_dirs:
- ../../../tests/fast/stages/s0_org_setup/data-customizations