Projects (Stage 4)
Repository: gcp-foundations-projects
Purpose
The projects stage is the project factory that creates GCP projects for business units and workloads. It provides a collection of subdirectories, each deploying projects for a specific domain or business unit. Projects are attached to the Shared VPCs created in Stage 3 and placed inside environment folders from Stage 2. This is the final foundation stage before the platform layer takes over.
Subdirectory Structure
Each subdirectory is an independent Terraform root module, typically with per-environment configurations:
| Subdirectory | Purpose | Key Resources |
|---|---|---|
sandbox | Sandbox/experimental projects | Standalone projects for testing |
devex | Developer Experience projects | Backstage infrastructure, DevEx tooling |
devex-gcs | DevEx GCS resources | Storage buckets for DevEx |
devops_1 | DevOps projects | CI/CD infrastructure projects |
databricks | Databricks workspaces | Databricks-specific GCP projects |
data | Data platform projects | Data engineering workload projects |
data-foundations | Data foundations | Core data infrastructure |
gke_hub | GKE Hub/Fleet | GKE multi-cluster management |
gke_argo_iam | GKE + ArgoCD IAM | IAM for GKE with ArgoCD |
pci_dss | PCI-DSS projects | Compliance-specific workloads in fldr-pci-dss |
project-factory | Generic project factory | Configurable project creation |
test | Test projects | Testing and validation |
The single_project Module
The core building block is modules/single_project, which wraps the terraform-google-modules/project-factory/google (~> 18.0) module with Badal-specific defaults and Shared VPC integration.
What It Creates
Key Features
- Project naming:
{project_prefix}-{env_code}-{business_code}-{project_suffix}(e.g.,prj-d-data-analytics) - Shared VPC attachment: Automatically attaches to the base or restricted Shared VPC host project
- Subnet-level permissions: Grants
compute.networkUserrole on specific subnets to pipeline service accounts - VPC Service Controls: Optional perimeter attachment for restricted VPC projects
- Budget alerts: Configurable spend thresholds and Pub/Sub notifications
- Standard labels: environment, application_name, billing_code, primary_contact, secondary_contact, business_code, env_code, vpc_type
Module Interface
module "project" {
source = "../../modules/single_project"
org_id = var.org_id
billing_account = var.billing_account
folder_id = var.folder_id
environment = "development"
business_code = "data"
project_suffix = "analytics"
project_prefix = "prj"
# Shared VPC
shared_vpc_host_project_id = var.base_shared_vpc_host_project_id
shared_vpc_subnets = var.base_shared_vpc_subnets
# VPC Service Controls (for restricted VPC)
vpc_service_control_attach_enabled = false
vpc_service_control_perimeter_name = ""
# APIs
activate_apis = ["compute.googleapis.com", "storage.googleapis.com"]
# CI/CD pipeline access
app_infra_pipeline_service_accounts = var.app_infra_pipeline_service_accounts
sa_roles = {
"my-repo" = [
"roles/compute.instanceAdmin.v1",
"roles/iam.serviceAccountUser",
]
}
# Labels
application_name = "analytics"
primary_contact = "team-lead@badal.io"
secondary_contact = "backup@badal.io"
billing_code = "DATA-001"
}
Business Unit Creation Pattern
Business units in Stage 4 follow a consistent pattern using the platform modules:
- Create BU via
terraform-platform-create-business-unitmodule (or Backstage template) - BU module creates per-environment folders inside foundation env folders
- BU module creates a common folder with WIF host project
- BU module creates a GitHub repo and TFC workspace
- Create Tenant projects inside BU folders via
terraform-platform-create-tenant - Tenant projects are attached to Shared VPCs from Stage 3
Folder Hierarchy Example
fldr-development/
+-- data-80r13/ # BU folder (created by BU module)
| +-- prj-governance-d-f6y39/ # Tenant project
| +-- prj-template-d-b8cbu/ # Tenant project
+-- platform-0r4dp/
| +-- prj-gke-argocd-d-xxxxx/
+-- devex-9c9dl/
+-- prj-backstage-n-mly9n/
Key Modules Available
The modules/ directory provides reusable components:
| Module | Purpose |
|---|---|
single_project | Core project factory with Shared VPC integration |
base_env | Per-environment project orchestrator |
artifacts | Artifact Registry repository creation |
bigquery | BigQuery dataset and table creation |
cloud_run | Cloud Run service deployment |
gce | Compute Engine instance creation |
gke_demo | GKE cluster demo configuration |
infra_pipelines | CI/CD infrastructure pipeline setup |
lb / loadbalancer | Load balancer configuration |
pubsub | Pub/Sub topic and subscription creation |
wif | Workload Identity Federation setup |
databricks | Databricks workspace integration |
databricks-budget | Databricks cost management |
databricks-gcp-infra | GCP infra for Databricks |
databricks-metastore | Unity Catalog metastore |
databricks-network | Databricks network config |
databricks-workspace | Databricks workspace creation |
databricks-user-groups | Databricks SCIM user/group sync |
cais_feed | Cloud Asset Inventory feeds |
pci_dss_logsink_alert | PCI-DSS log sink alerting |
PCI-DSS Compliance Monitoring
The pci_dss subdirectory creates projects in the fldr-pci-dss folder with:
- Exemption from restrictive org policies (inherited from folder)
- Dedicated log sinks for compliance auditing (
pci_dss_logsink_alertmodule) - Monitoring and alerting for PCI-DSS relevant events
- Separate network configuration as needed
How Projects Attach to Shared VPCs
Projects created by single_project are attached to Shared VPCs through the project factory's svpc_host_project_id and shared_vpc_subnets parameters:
Attachment Process
- The
single_projectmodule receives the Shared VPC host project ID and subnet self-links - The project factory module creates the Shared VPC service project attachment
- Pipeline service accounts receive
compute.networkUserrole on specific subnets - Pipeline service accounts receive
compute.networkVieweron the parent folder
VPC Type Selection
Projects specify which VPC type to attach to:
vpc_type Label | Shared VPC Host | Use Case |
|---|---|---|
base | prj-{env}-shared-base | Standard workloads |
restricted | prj-{env}-shared-restricted | Sensitive workloads with VPC-SC |
Directory Structure
gcp-foundations-projects/
+-- modules/
| +-- single_project/ # Core project factory module
| +-- base_env/ # Per-env orchestrator
| +-- artifacts/ # Artifact Registry
| +-- bigquery/ # BigQuery resources
| +-- cloud_run/ # Cloud Run
| +-- gce/ # Compute Engine
| +-- gke_demo/ # GKE demo
| +-- infra_pipelines/ # CI/CD pipelines
| +-- lb/ # Load balancers
| +-- pubsub/ # Pub/Sub
| +-- wif/ # Workload Identity Federation
| +-- databricks*/ # Databricks modules
| +-- pci_dss_logsink_alert/ # PCI-DSS alerting
| +-- cais_feed/ # Cloud Asset Inventory
+-- sandbox/ # Sandbox projects
+-- devex/ # DevEx projects
+-- devex-gcs/ # DevEx storage
+-- devops_1/ # DevOps projects
+-- databricks/ # Databricks workspaces
+-- data/ # Data platform
+-- data-foundations/ # Data foundations
+-- gke_hub/ # GKE Hub/Fleet
+-- gke_argo_iam/ # GKE ArgoCD IAM
+-- pci_dss/ # PCI-DSS projects
+-- project-factory/ # Generic project factory
+-- test/ # Test projects
+-- policy-library/ # OPA policy constraints