Guardrails: Enforcing Organization Policies
Scenario
Your legal department mandates that all data must reside in the United States or the European Union. Developers should not be able to accidentally deploy a Cloud Storage bucket or a VM in Tokyo (`asia-northeast1`). IAM roles don't restrict regions. You must use Organization Policies (Constraints) applied at the Project level (in this lab) to deny deployment outside of explicitly allowed locations.
- Provision a google_project_organization_policy bound to the GCP project.
- Set the constraint to constraints/gcp.resourceLocations.
- Configure a List Policy that ALLOWS specific values (e.g. `in:us-locations` and `in:eu-locations`).
- Attempt to deploy a google_storage_bucket in an unapproved region to deliberately test the policy blockade.
Additional Context
Org Policies vs IAM: IAM answers "Who can do X?". Org Policies answer "How can X be configured?". Even an `Owner` of a project cannot violate an Organization Policy constraint.
Hierarchy: Organization Policies can be applied on an Organization, a Folder, or a Project. Child notes inherit policies from parents. In Terraform, you use `google_organization_policy`, `google_folder_organization_policy`, or `google_project_organization_policy` respectively.
variables.tf
variable "project_id" { type = string }main.tf
provider "google" {
project = var.project_id
}
# 1. The Resource Location Organization Policy
resource "google_project_organization_policy" "location_restriction" {
project = var.project_id
constraint = "constraints/gcp.resourceLocations"
list_policy {
# Replace default inheritance
inherit_from_parent = false
allow {
# Use GCP Value Groups for whole continents
values = [
"in:us-locations",
"in:eu-locations"
]
}
}
}
# Wait for Org Policy propagation (can sometimes take 60s)
resource "time_sleep" "wait_for_policy" {
depends_on = [google_project_organization_policy.location_restriction]
create_duration = "30s"
}
# 2. Rejection Test!
# This bucket placement SHOULD FAIL because "asia-northeast1" (Tokyo) is not in US or EU.
resource "random_id" "bkt" { byte_length = 4 }
resource "google_storage_bucket" "illegal_bucket" {
name = "tokyo-bucket-${random_id.bkt.hex}"
location = "ASIA" # Or "asia-northeast1"
# Tell terraform to only attempt this after policy is applied
depends_on = [time_sleep.wait_for_policy]
}Workflow Commands
terraform init
# This apply SHOULD ERROR OUT! This means the policy worked.
terraform apply -var="project_id=my-gcp-project-123"
# Example Error: "Violation for constraint 'constraints/gcp.resourceLocations'."
# Fix it by changing location = "ASIA" to location = "US" in main.tf, then re-apply.
