diff --git a/fast/stages/1-resman/README.md b/fast/stages/1-resman/README.md
index ee888637e..ad02969d4 100644
--- a/fast/stages/1-resman/README.md
+++ b/fast/stages/1-resman/README.md
@@ -267,18 +267,18 @@ terraform apply
|---|---|:---:|:---:|:---:|:---:|
| [automation](variables-fast.tf#L19) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 0-bootstrap |
| [billing_account](variables-fast.tf#L42) | Billing account id. If billing account is not part of the same org set `is_org_level` to `false`. To disable handling of billing IAM roles set `no_iam` to `true`. | object({…}) | ✓ | | 0-bootstrap |
-| [logging](variables-fast.tf#L97) | Logging configuration for tenants. | object({…}) | ✓ | | 1-tenant-factory |
-| [organization](variables-fast.tf#L110) | Organization details. | object({…}) | ✓ | | 0-bootstrap |
-| [prefix](variables-fast.tf#L128) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap |
-| [custom_roles](variables-fast.tf#L53) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap |
+| [logging](variables-fast.tf#L98) | Logging configuration for tenants. | object({…}) | ✓ | | 1-tenant-factory |
+| [organization](variables-fast.tf#L111) | Organization details. | object({…}) | ✓ | | 0-bootstrap |
+| [prefix](variables-fast.tf#L129) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap |
+| [custom_roles](variables-fast.tf#L53) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap |
| [environment_names](variables.tf#L20) | Long environment names. | object({…}) | | {…} | |
| [factories_config](variables.tf#L32) | Configuration for the resource factories or external data. | object({…}) | | {} | |
| [fast_stage_2](variables-stages.tf#L17) | FAST stages 2 configurations. | object({…}) | | {} | |
| [fast_stage_3](variables-stages.tf#L97) | FAST stages 3 configurations. | map(object({…})) | | {} | |
-| [groups](variables-fast.tf#L69) | 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. | object({…}) | | {} | 0-bootstrap |
-| [locations](variables-fast.tf#L84) | Optional locations for GCS, BigQuery, and logging buckets created here. | object({…}) | | {} | 0-bootstrap |
+| [groups](variables-fast.tf#L70) | 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. | object({…}) | | {} | 0-bootstrap |
+| [locations](variables-fast.tf#L85) | Optional locations for GCS, BigQuery, and logging buckets created here. | object({…}) | | {} | 0-bootstrap |
| [outputs_location](variables.tf#L43) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | string | | null | |
-| [root_node](variables-fast.tf#L134) | Root node for the hierarchy, if running in tenant mode. | string | | null | 0-bootstrap |
+| [root_node](variables-fast.tf#L135) | Root node for the hierarchy, if running in tenant mode. | string | | null | 0-bootstrap |
| [tag_names](variables.tf#L49) | Customized names for resource management tags. | object({…}) | | {} | |
| [tags](variables.tf#L63) | Custom secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | |
| [top_level_folders](variables-toplevel-folders.tf#L17) | Additional top-level folders. Keys are used for service account and bucket names, values implement the folders module interface with the addition of the 'automation' attribute. | map(object({…})) | | {} | |
diff --git a/fast/stages/1-resman/stage-2-networking.tf b/fast/stages/1-resman/stage-2-networking.tf
index ae8243c34..f4a52601c 100644
--- a/fast/stages/1-resman/stage-2-networking.tf
+++ b/fast/stages/1-resman/stage-2-networking.tf
@@ -96,6 +96,9 @@ module "net-folder" {
(var.custom_roles.service_project_network_admin) = [
module.pf-sa-rw[0].iam_email
]
+ (var.custom_roles.project_iam_viewer) = [
+ module.pf-sa-ro[0].iam_email
+ ]
"roles/compute.networkViewer" = [
module.pf-sa-ro[0].iam_email
]
diff --git a/fast/stages/1-resman/stage-2-security.tf b/fast/stages/1-resman/stage-2-security.tf
index db978c494..36e3d7b65 100644
--- a/fast/stages/1-resman/stage-2-security.tf
+++ b/fast/stages/1-resman/stage-2-security.tf
@@ -60,6 +60,9 @@ module "sec-folder" {
"roles/cloudkms.cryptoKeyEncrypterDecrypter" = [
module.pf-sa-rw[0].iam_email
]
+ (var.custom_roles.project_iam_viewer) = [
+ module.pf-sa-ro[0].iam_email
+ ]
"roles/cloudkms.viewer" = [
module.pf-sa-ro[0].iam_email
]
diff --git a/fast/stages/1-resman/variables-fast.tf b/fast/stages/1-resman/variables-fast.tf
index 065a74c56..e2de3ba7b 100644
--- a/fast/stages/1-resman/variables-fast.tf
+++ b/fast/stages/1-resman/variables-fast.tf
@@ -55,6 +55,7 @@ variable "custom_roles" {
description = "Custom roles defined at the org level, in key => id format."
type = object({
organization_admin_viewer = string
+ project_iam_viewer = string
service_project_network_admin = string
storage_viewer = string
gcve_network_admin = optional(string)
diff --git a/tests/fast/stages/s1_resman/simple.yaml b/tests/fast/stages/s1_resman/simple.yaml
index 7535e164a..8f5667ca7 100644
--- a/tests/fast/stages/s1_resman/simple.yaml
+++ b/tests/fast/stages/s1_resman/simple.yaml
@@ -1446,7 +1446,7 @@ values:
counts:
google_folder: 13
- google_folder_iam_binding: 72
+ google_folder_iam_binding: 74
google_organization_iam_member: 14
google_project_iam_member: 23
google_service_account: 23
@@ -1460,4 +1460,4 @@ counts:
google_tags_tag_value: 11
google_tags_tag_value_iam_binding: 4
modules: 47
- resources: 273
+ resources: 275