Skip to content

Commit a9ac0f4

Browse files
authored
Add variable to resman to control top-level folder IAM (#2196)
1 parent 33ffe2d commit a9ac0f4

File tree

12 files changed

+158
-51
lines changed

12 files changed

+158
-51
lines changed

fast/stages/1-resman/README.md

Lines changed: 13 additions & 12 deletions
Large diffs are not rendered by default.

fast/stages/1-resman/branch-data-platform.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module "branch-dp-folder" {
2121
count = var.fast_features.data_platform ? 1 : 0
2222
parent = "organizations/${var.organization.id}"
2323
name = "Data Platform"
24+
iam = var.folder_iam.data_platform
2425
tag_bindings = {
2526
context = try(
2627
module.organization.tag_values["${var.tag_names.context}/data"].id, null

fast/stages/1-resman/branch-gcve.tf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2022 Google LLC
2+
* Copyright 2024 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ module "branch-gcve-folder" {
2121
count = var.fast_features.gcve ? 1 : 0
2222
parent = "organizations/${var.organization.id}"
2323
name = "GCVE"
24+
iam = var.folder_iam.gcve
2425
tag_bindings = {
2526
context = try(
2627
module.organization.tag_values["${var.tag_names.context}/gcve"].id, null

fast/stages/1-resman/branch-gke.tf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2022 Google LLC
2+
* Copyright 2024 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ module "branch-gke-folder" {
2121
count = var.fast_features.gke ? 1 : 0
2222
parent = "organizations/${var.organization.id}"
2323
name = "GKE"
24+
iam = var.folder_iam.gke
2425
tag_bindings = {
2526
context = try(
2627
module.organization.tag_values["${var.tag_names.context}/gke"].id, null

fast/stages/1-resman/branch-networking.tf

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,29 @@
1616

1717
# tfdoc:file:description Networking stage resources.
1818

19+
locals {
20+
# FAST-specific IAM
21+
_network_folder_fast_iam = {
22+
# read-write (apply) automation service account
23+
"roles/logging.admin" = [module.branch-network-sa.iam_email]
24+
"roles/owner" = [module.branch-network-sa.iam_email]
25+
"roles/resourcemanager.folderAdmin" = [module.branch-network-sa.iam_email]
26+
"roles/resourcemanager.projectCreator" = [module.branch-network-sa.iam_email]
27+
"roles/compute.xpnAdmin" = [module.branch-network-sa.iam_email]
28+
# read-only (plan) automation service account
29+
"roles/viewer" = [module.branch-network-r-sa.iam_email]
30+
"roles/resourcemanager.folderViewer" = [module.branch-network-r-sa.iam_email]
31+
}
32+
# deep-merge FAST-specific IAM with user-provided bindings in var.folder_iam
33+
_network_folder_iam = merge(
34+
var.folder_iam.network,
35+
{
36+
for role, principals in local._network_folder_fast_iam :
37+
role => distinct(concat(principals, lookup(var.folder_iam.network, role, [])))
38+
}
39+
)
40+
}
41+
1942
module "branch-network-folder" {
2043
source = "../../../modules/folder"
2144
parent = "organizations/${var.organization.id}"
@@ -27,17 +50,7 @@ module "branch-network-folder" {
2750
"roles/editor",
2851
]
2952
}
30-
iam = {
31-
# read-write (apply) automation service account
32-
"roles/logging.admin" = [module.branch-network-sa.iam_email]
33-
"roles/owner" = [module.branch-network-sa.iam_email]
34-
"roles/resourcemanager.folderAdmin" = [module.branch-network-sa.iam_email]
35-
"roles/resourcemanager.projectCreator" = [module.branch-network-sa.iam_email]
36-
"roles/compute.xpnAdmin" = [module.branch-network-sa.iam_email]
37-
# read-only (plan) automation service account
38-
"roles/viewer" = [module.branch-network-r-sa.iam_email]
39-
"roles/resourcemanager.folderViewer" = [module.branch-network-r-sa.iam_email]
40-
}
53+
iam = local._network_folder_iam
4154
tag_bindings = {
4255
context = try(
4356
module.organization.tag_values["${var.tag_names.context}/networking"].id, null

fast/stages/1-resman/branch-sandbox.tf

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2023 Google LLC
2+
* Copyright 2024 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,17 +16,31 @@
1616

1717
# tfdoc:file:description Sandbox stage resources.
1818

19-
module "branch-sandbox-folder" {
20-
source = "../../../modules/folder"
21-
count = var.fast_features.sandbox ? 1 : 0
22-
parent = "organizations/${var.organization.id}"
23-
name = "Sandbox"
24-
iam = {
19+
locals {
20+
# FAST-specific IAM
21+
_sandbox_folder_fast_iam = !var.fast_features.sandbox ? {} : {
2522
"roles/logging.admin" = [module.branch-sandbox-sa.0.iam_email]
2623
"roles/owner" = [module.branch-sandbox-sa.0.iam_email]
2724
"roles/resourcemanager.folderAdmin" = [module.branch-sandbox-sa.0.iam_email]
2825
"roles/resourcemanager.projectCreator" = [module.branch-sandbox-sa.0.iam_email]
2926
}
27+
# deep-merge FAST-specific IAM with user-provided bindings in var.folder_iam
28+
_sandbox_folder_iam = merge(
29+
var.folder_iam.sandbox,
30+
{
31+
for role, principals in local._sandbox_folder_fast_iam :
32+
role => distinct(concat(principals, lookup(var.folder_iam.sandbox, role, [])))
33+
}
34+
)
35+
}
36+
37+
38+
module "branch-sandbox-folder" {
39+
source = "../../../modules/folder"
40+
count = var.fast_features.sandbox ? 1 : 0
41+
parent = "organizations/${var.organization.id}"
42+
name = "Sandbox"
43+
iam = local._sandbox_folder_iam
3044
org_policies = {
3145
"sql.restrictPublicIp" = { rules = [{ enforce = false }] }
3246
"compute.vmExternalIpAccess" = { rules = [{ allow = { all = true } }] }

fast/stages/1-resman/branch-security.tf

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,28 @@
1616

1717
# tfdoc:file:description Security stage resources.
1818

19+
locals {
20+
# FAST-specific IAM
21+
_security_folder_fast_iam = {
22+
"roles/logging.admin" = [module.branch-security-sa.iam_email]
23+
"roles/owner" = [module.branch-security-sa.iam_email]
24+
"roles/resourcemanager.folderAdmin" = [module.branch-security-sa.iam_email]
25+
"roles/resourcemanager.projectCreator" = [module.branch-security-sa.iam_email]
26+
# read-only (plan) automation service account
27+
"roles/viewer" = [module.branch-security-r-sa.iam_email]
28+
"roles/resourcemanager.folderViewer" = [module.branch-security-r-sa.iam_email]
29+
}
30+
31+
# deep-merge FAST-specific IAM with user-provided bindings in var.folder_iam
32+
_security_folder_iam = merge(
33+
var.folder_iam.security,
34+
{
35+
for role, principals in local._security_folder_fast_iam :
36+
role => distinct(concat(principals, lookup(var.folder_iam.security, role, [])))
37+
}
38+
)
39+
}
40+
1941
module "branch-security-folder" {
2042
source = "../../../modules/folder"
2143
parent = "organizations/${var.organization.id}"
@@ -27,16 +49,7 @@ module "branch-security-folder" {
2749
"roles/editor"
2850
]
2951
}
30-
iam = {
31-
# read-write (apply) automation service account
32-
"roles/logging.admin" = [module.branch-security-sa.iam_email]
33-
"roles/owner" = [module.branch-security-sa.iam_email]
34-
"roles/resourcemanager.folderAdmin" = [module.branch-security-sa.iam_email]
35-
"roles/resourcemanager.projectCreator" = [module.branch-security-sa.iam_email]
36-
# read-only (plan) automation service account
37-
"roles/viewer" = [module.branch-security-r-sa.iam_email]
38-
"roles/resourcemanager.folderViewer" = [module.branch-security-r-sa.iam_email]
39-
}
52+
iam = local._security_folder_iam
4053
tag_bindings = {
4154
context = try(
4255
module.organization.tag_values["${var.tag_names.context}/security"].id, null

fast/stages/1-resman/branch-teams.tf

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,31 @@
1717
# tfdoc:file:description Team stage resources.
1818

1919
# TODO(ludo): add support for CI/CD
20-
21-
module "branch-teams-folder" {
22-
source = "../../../modules/folder"
23-
count = var.fast_features.teams ? 1 : 0
24-
parent = "organizations/${var.organization.id}"
25-
name = "Teams"
26-
iam = {
20+
locals {
21+
# FAST-specific IAM
22+
_teams_folder_fast_iam = !var.fast_features.teams ? {} : {
2723
"roles/logging.admin" = [module.branch-teams-sa.0.iam_email]
2824
"roles/owner" = [module.branch-teams-sa.0.iam_email]
2925
"roles/resourcemanager.folderAdmin" = [module.branch-teams-sa.0.iam_email]
3026
"roles/resourcemanager.projectCreator" = [module.branch-teams-sa.0.iam_email]
3127
"roles/compute.xpnAdmin" = [module.branch-teams-sa.0.iam_email]
3228
}
29+
# deep-merge FAST-specific IAM with user-provided bindings in var.folder_iam
30+
_teams_folder_iam = merge(
31+
var.folder_iam.teams,
32+
{
33+
for role, principals in local._teams_folder_fast_iam :
34+
role => distinct(concat(principals, lookup(var.folder_iam.teams, role, [])))
35+
}
36+
)
37+
}
38+
39+
module "branch-teams-folder" {
40+
source = "../../../modules/folder"
41+
count = var.fast_features.teams ? 1 : 0
42+
parent = "organizations/${var.organization.id}"
43+
name = "Teams"
44+
iam = local._teams_folder_iam
3345
tag_bindings = {
3446
context = try(
3547
module.organization.tag_values["${var.tag_names.context}/teams"].id, null

fast/stages/1-resman/branch-tenants.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ module "tenant-tenants-folder" {
3333
source = "../../../modules/folder"
3434
parent = "organizations/${var.organization.id}"
3535
name = "Tenants"
36+
iam = var.folder_iam.tenants
3637
tag_bindings = {
3738
context = module.organization.tag_values["${var.tag_names.context}/tenant"].id
3839
}

fast/stages/1-resman/variables.tf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,22 @@ variable "fast_features" {
180180
nullable = false
181181
}
182182

183+
variable "folder_iam" {
184+
description = "Authoritative IAM for top-level folders."
185+
type = object({
186+
data_platform = optional(map(list(string)), {})
187+
gcve = optional(map(list(string)), {})
188+
gke = optional(map(list(string)), {})
189+
sandbox = optional(map(list(string)), {})
190+
security = optional(map(list(string)), {})
191+
network = optional(map(list(string)), {})
192+
teams = optional(map(list(string)), {})
193+
tenants = optional(map(list(string)), {})
194+
})
195+
nullable = false
196+
default = {}
197+
}
198+
183199
variable "groups" {
184200
# tfdoc:variable:source 0-bootstrap
185201
# https://cloud.google.com/docs/enterprise/setup-checklist

0 commit comments

Comments
 (0)