Created
November 30, 2025 02:26
-
-
Save mvanholsteijn/7d2afc35b0d8bcb40e66b5877f1039c5 to your computer and use it in GitHub Desktop.
demonstrate policy-access-boundaries with terraform
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| variable domain { | |
| type = string | |
| } | |
| variable billing_account { | |
| type = string | |
| } | |
| data "google_organization" "current" { | |
| domain = var.domain | |
| } | |
| locals { | |
| domain_as_prefix = lower(join("-", reverse(split(".", var.domain)))) | |
| } | |
| resource "google_folder" "business_unit_parent" { | |
| parent = data.google_organization.current.name | |
| display_name = "business-units" | |
| } | |
| resource "google_folder" "business_unit" { | |
| for_each = local.business_units | |
| parent = google_folder.business_unit_parent.name | |
| display_name = each.value | |
| deletion_protection = false | |
| } | |
| resource "google_project" "business_unit" { | |
| for_each = local.business_units | |
| name = each.key | |
| project_id = "${local.domain_as_prefix}-${lower(each.key)}" | |
| folder_id = google_folder.business_unit[each.key].name | |
| billing_account = var.billing_account | |
| deletion_policy = "DELETE" | |
| } | |
| resource "google_project_service" "business_unit" { | |
| for_each = { | |
| for m in setproduct(local.business_units, ["cloud.googleapis.com", "storage.googleapis.com"]) : | |
| "${m[0]}/${m[1]}" => { | |
| project = google_project.business_unit[m[0]].project_id | |
| service = m[1] | |
| } | |
| } | |
| project = each.value.project | |
| service = each.value.service | |
| disable_on_destroy = false | |
| } | |
| resource "google_service_account" "business_unit" { | |
| for_each = local.business_units | |
| account_id = "data-pipeline" | |
| project = google_project.business_unit[each.key].project_id | |
| } | |
| resource google_service_account_iam_binding business_unit_token_creator { | |
| for_each = local.business_units | |
| service_account_id = google_service_account.business_unit[each.key].id | |
| role = "roles/iam.serviceAccountTokenCreator" | |
| members = [ | |
| format("user:%s", data.google_client_openid_userinfo.terraformer.email) | |
| ] | |
| } | |
| data "google_client_openid_userinfo" "terraformer" { | |
| } | |
| resource google_service_account_iam_binding business_unit_user { | |
| for_each = local.business_units | |
| service_account_id = google_service_account.business_unit[each.key].id | |
| role = "roles/iam.serviceAccountUser" | |
| members = [ | |
| format("user:%s", data.google_client_openid_userinfo.terraformer.email) | |
| ] | |
| } | |
| locals { | |
| business_units = toset(["BU-001", "BU-002", "BU-003"]) | |
| data_sharing_contracts = { | |
| "BU-001" = ["BU-001"] | |
| "BU-002" = ["BU-001", "BU-002"], | |
| "BU-003" = ["BU-001", "BU-002", "BU-003"], | |
| } | |
| } | |
| resource "google_storage_bucket" "business_unit" { | |
| for_each = local.business_units | |
| name = "${local.domain_as_prefix}-${lower(each.key)}-data" | |
| project = google_project.business_unit[each.key].project_id | |
| location = "EU" | |
| force_destroy = true | |
| uniform_bucket_level_access = true | |
| } | |
| resource "google_storage_bucket_iam_binding" "business_unit" { | |
| for_each = google_storage_bucket.business_unit | |
| role = "roles/storage.objectAdmin" | |
| members = [ for sa in google_service_account.business_unit : sa.member ] | |
| bucket = each.value.name | |
| } | |
| resource "google_storage_bucket_object" "index" { | |
| for_each = local.business_units | |
| content_type = "application/html" | |
| name = "index.html" | |
| bucket = google_storage_bucket.business_unit[each.key].name | |
| content = <<-EOF | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>Hello from ${each.key}</title> | |
| </head> | |
| <body> | |
| <h1>Hello World from ${each.key}!</h1> | |
| </body> | |
| </html> | |
| EOF | |
| } | |
| resource "google_iam_principal_access_boundary_policy" "business_unit" { | |
| for_each = local.business_units | |
| organization = reverse(split("/", google_folder.business_unit_parent.parent))[0] | |
| display_name = "data sharing contract enforcement for ${each.key}" | |
| location = "global" | |
| principal_access_boundary_policy_id = lower(each.key) | |
| details { | |
| rules { | |
| effect = "ALLOW" | |
| resources = [for business_unit in local.data_sharing_contracts[each.key] : | |
| format("//cloudresourcemanager.googleapis.com/%s", google_folder.business_unit[business_unit].id) | |
| ] | |
| } | |
| } | |
| } | |
| resource "google_iam_folders_policy_binding" "business_unit" { | |
| for_each = local.business_units | |
| folder = google_folder.business_unit[each.key].folder_id | |
| location = "global" | |
| display_name = "data sharing contract enforcement for ${each.key}" | |
| policy_kind = "PRINCIPAL_ACCESS_BOUNDARY" | |
| policy_binding_id = lower(each.key) | |
| policy = google_iam_principal_access_boundary_policy.business_unit[each.key].id | |
| target { | |
| principal_set = format("//cloudresourcemanager.googleapis.com/%s", google_folder.business_unit[each.key].id) | |
| } | |
| } | |
| resource local_file config_gcloud { | |
| filename = "config-gcloud.sh" | |
| file_permission = "0700" | |
| content = join("\n", [ | |
| for business_unit in local.business_units : | |
| join("\n", [ | |
| "gcloud config configurations create ${lower(business_unit)} --no-activate --quiet", | |
| "gcloud config set account $(gcloud config get account --quiet) --configuration ${lower(business_unit)}", | |
| "gcloud config set core/project ${google_project.business_unit[business_unit].project_id} --configuration ${lower(business_unit)} --quiet", | |
| "gcloud config set auth/impersonate_service_account ${google_service_account.business_unit[business_unit].email} --configuration ${lower(business_unit)} --quiet", | |
| ]) | |
| ] | |
| ) | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment