Implement support for VPC-SC perimeter membership from project factory (#3007)

* support project factory-level vpc-sc perimeter interpolation

* fix ro role

* add support for IAM on service accounts

* fix typo
This commit is contained in:
Ludovico Magnocavallo
2025-04-04 13:45:22 +02:00
committed by GitHub
parent 25b6020a14
commit 69188fa9d9
12 changed files with 63 additions and 11 deletions

View File

@@ -144,7 +144,8 @@ module "organization" {
|| api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])
EOT
, join(",", formatlist("'%s'", [
"roles/accesscontextmanager.policyAdmin",
"roles/accesscontextmanager.policyEditor",
"roles/accesscontextmanager.policyReader",
"roles/cloudasset.viewer",
"roles/compute.orgFirewallPolicyAdmin",
"roles/compute.orgFirewallPolicyUser",

View File

@@ -25,3 +25,9 @@ organization_config:
description: Org policy tag scoped grant for project factory.
expression: |
resource.matchTag('${organization.id}/${tag_names.context}', 'project-factory')
sa_pf_vpcsc_ro:
member: ro
role: roles/accesscontextmanager.policyReader
sa_pf_vpcsc_rw:
member: rw
role: roles/accesscontextmanager.policyEditor

View File

@@ -17,11 +17,11 @@
locals {
tfvars = {
perimeters = {
for k, v in try(module.vpc-sc[0].service_perimeters_regular, {}) :
for k, v in try(module.vpc-sc.service_perimeters_regular, {}) :
k => v.id
}
perimeters_bridge = {
for k, v in try(module.vpc-sc[0].service_perimeters_bridge, {}) :
for k, v in try(module.vpc-sc.service_perimeters_bridge, {}) :
k => v.id
}
}

View File

@@ -2,4 +2,4 @@ FAST_STAGE_DESCRIPTION="project factory (org level)"
FAST_STAGE_LEVEL=2
FAST_STAGE_NAME=project-factory
FAST_STAGE_DEPS="0-globals 0-bootstrap 1-resman"
FAST_STAGE_OPTIONAL="2-networking 2-security"
FAST_STAGE_OPTIONAL="1-vpcsc 2-networking 2-security"

View File

@@ -354,16 +354,17 @@ The approach is not shown here but reasonably easy to implement. The main projec
|---|---|:---:|:---:|:---:|:---:|
| [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-bootstrap</code> |
| [billing_account](variables-fast.tf#L26) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object&#40;&#123;&#10; id &#61; string&#10; is_org_level &#61; optional&#40;bool, true&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables-fast.tf#L74) | 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-bootstrap</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-bootstrap</code> |
| [factories_config](variables.tf#L17) | Configuration for YAML-based factories. | <code title="object&#40;&#123;&#10; folders_data_path &#61; optional&#40;string, &#34;data&#47;hierarchy&#34;&#41;&#10; projects_data_path &#61; optional&#40;string, &#34;data&#47;projects&#34;&#41;&#10; budgets &#61; optional&#40;object&#40;&#123;&#10; billing_account &#61; string&#10; budgets_data_path &#61; optional&#40;string, &#34;data&#47;budgets&#34;&#41;&#10; notification_channels &#61; optional&#40;map&#40;any&#41;, &#123;&#125;&#41;&#10; &#125;&#41;&#41;&#10; context &#61; optional&#40;object&#40;&#123;&#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; 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; &#125;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [folder_ids](variables-fast.tf#L39) | Folders created in the resource management stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>1-resman</code> |
| [groups](variables-fast.tf#L47) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-bootstrap</code> |
| [host_project_ids](variables-fast.tf#L56) | Host project for the shared VPC. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>2-networking</code> |
| [locations](variables-fast.tf#L64) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object&#40;&#123;&#10; gcs &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | <code>0-bootstrap</code> |
| [outputs_location](variables.tf#L39) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | <code>string</code> | | <code>null</code> | |
| [service_accounts](variables-fast.tf#L84) | Automation service accounts in name => email format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>1-resman</code> |
| [perimeters](variables-fast.tf#L74) | Optional VPC-SC perimeter ids. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>1-vpcsc</code> |
| [service_accounts](variables-fast.tf#L92) | Automation service accounts in name => email format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>1-resman</code> |
| [stage_name](variables.tf#L45) | FAST stage name. Used to separate output files across different factories. | <code>string</code> | | <code>&#34;2-project-factory&#34;</code> | |
| [tag_values](variables-fast.tf#L92) | FAST-managed resource manager tag values. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>1-resman</code> |
| [tag_values](variables-fast.tf#L100) | FAST-managed resource manager tag values. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>1-resman</code> |
## Outputs

View File

@@ -45,6 +45,7 @@ module "projects" {
var.groups,
var.factories_config.context.iam_principals
)
perimeters = var.perimeters
tag_values = merge(
var.tag_values,
var.factories_config.context.tag_values

View File

@@ -71,6 +71,14 @@ variable "locations" {
default = {}
}
variable "perimeters" {
# tfdoc:variable:source 1-vpcsc
description = "Optional VPC-SC perimeter ids."
type = map(string)
nullable = false
default = {}
}
variable "prefix" {
# tfdoc:variable:source 0-bootstrap
description = "Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants."