Environments (Stage 2)
Repository: gcp-foundations-envs
Purpose
The environments stage creates the three environment folders and per-environment shared infrastructure projects. Each environment gets its own folder under the organization root (or parent folder) along with dedicated monitoring, secrets, and KMS projects. This stage implements a branch-per-environment deployment model where each environment has its own Git branch.
Three Environments
| Environment | Code | Branch | Folder |
|---|---|---|---|
| Development | d | development | fldr-development |
| Non-Production | n | non-production | fldr-non-production |
| Production | p | production | fldr-production |
The environment code (single character) is used throughout the platform for naming conventions in projects, subnets, and other resources.
Per-Environment Resources
Each environment creates the following resources using the env_baseline module:
Projects Per Environment
| Project | APIs Enabled | Purpose |
|---|---|---|
prj-{code}-monitoring | Logging, Monitoring, Billing Budgets | Environment-specific monitoring workspace |
prj-{code}-secrets | Logging, Secret Manager | Environment-specific secret storage |
prj-{code}-kms | Logging, Cloud KMS, Billing Budgets | Environment-specific encryption keys |
All projects use:
- Random 4-character project ID suffixes
terraform-google-modules/project-factory/google(~> 18.0)- Deprivileged default service accounts
- Budget alerts (configurable thresholds)
- Standard labels (
environment,application_name,env_code)
Complete Project Inventory
| Project | Environment | Purpose |
|---|---|---|
prj-d-monitoring-* | Development | Dev monitoring |
prj-d-secrets-* | Development | Dev secrets |
prj-d-kms-* | Development | Dev KMS |
prj-n-monitoring-* | Non-Production | Non-prod monitoring |
prj-n-secrets-* | Non-Production | Non-prod secrets |
prj-n-kms-* | Non-Production | Non-prod KMS |
prj-p-monitoring-* | Production | Production monitoring |
prj-p-secrets-* | Production | Production secrets |
prj-p-kms-* | Production | Production KMS |
Branch-Per-Environment Deployment Model
The environments stage uses a branch-based deployment model where each environment has a dedicated long-lived Git branch:
How It Works
- Each branch (
development,non-production,production) contains the same module code but calls it with environment-specific parameters - The
envs/{environment}/main.tffile in each branch passes the environment name and code:
# envs/development/main.tf
module "env" {
source = "../../modules/env_baseline"
env = "development"
environment_code = "d"
monitoring_workspace_users = var.monitoring_workspace_users
remote_state_bucket = var.remote_state_bucket
tfc_org_name = var.tfc_org_name
}
- CI/CD is triggered per-branch -- merging to the
developmentbranch applies changes only to the development environment - This ensures production changes must be explicitly promoted through the branch hierarchy
Environment Codes
| Code | Environment | Usage |
|---|---|---|
d | development | Project names, subnet names, resource labels |
n | non-production | Project names, subnet names, resource labels |
p | production | Project names, subnet names, resource labels |
b | bootstrap | Used only in Stage 0 |
c | common | Used for shared/common resources in Stages 1, 3 |
Tag Bindings
Each environment folder receives a tag binding that associates it with the corresponding environment tag value:
resource "google_tags_tag_binding" "folder_env" {
parent = "//cloudresourcemanager.googleapis.com/${google_folder.env.id}"
tag_value = local.tags["environment_${var.env}"]
}
This enables tag-based IAM conditions and policy enforcement. A 60-second delay is introduced after folder creation to allow propagation before binding.
Module: env_baseline
The env_baseline module encapsulates all per-environment resource creation:
| File | Purpose |
|---|---|
folders.tf | Environment folder + tag binding |
monitoring.tf | Monitoring project |
secrets.tf | Secrets project |
kms.tf | KMS project |
iam.tf | IAM bindings for the environment |
remote.tf | Remote state data sources (bootstrap, org) |
outputs.tf | Folder ID, project IDs for downstream stages |
assured_workload.tf | Assured Workloads configuration |
Key Outputs
| Output | Description | Consumed By |
|---|---|---|
env_folder | Environment folder ID | 3-networks, 4-projects |
monitoring_project_id | Monitoring project ID | 4-projects |
env_secrets_project_id | Secrets project ID | 4-projects |
env_kms_project_id | KMS project ID | 4-projects |
Directory Structure
gcp-foundations-envs/
+-- envs/
| +-- development/
| | +-- main.tf # env=development, code=d
| | +-- outputs.tf
| | +-- backend.tf
| | +-- providers.tf
| | +-- variables.tf
| +-- non-production/
| | +-- main.tf # env=non-production, code=n
| | +-- outputs.tf
| | +-- backend.tf
| | +-- providers.tf
| | +-- variables.tf
| +-- production/
| +-- main.tf # env=production, code=p
| +-- outputs.tf
| +-- backend.tf
| +-- providers.tf
| +-- variables.tf
+-- modules/
+-- env_baseline/
+-- folders.tf
+-- monitoring.tf
+-- secrets.tf
+-- kms.tf
+-- iam.tf
+-- remote.tf
+-- outputs.tf
+-- variables.tf
+-- versions.tf