Create a new GCP project configuration for the infrastructure directory. Generates base.yaml, environment files, roles, and permissions following established conventions.
$ARGUMENTS
The user input describes the new project name and its purpose/workloads. Do not ask the user to repeat it unless it is empty.
If empty: ERROR "No project description provided. Usage: /infra-project-setup enrichments - Cloud Functions and Tasks for enrichment agents"
Generate a complete, convention-compliant GCP project configuration at infrastructure/config/projects/<name>/ that can be immediately provisioned via create-project.sh <name> <env> --deploy.
Read CONSTITUTION.md section "Infrastructure Standards" before proceeding. Key points:
Every project has exactly two service accounts:
project-terraform-deployer (deployer): Provisions and manages ALL project resources — APIs, IAM, SAs, Cloud Functions, Cloud Tasks, storage, secrets, everything. Defined via the section in . The root-level SA (in ) impersonates this SA. WIF binding enables keyless CI/CD auth from GitHub Actions. This is NOT defined in — it is created automatically by the bootstrap system.
terraform_deployerbase.yamlterraform-deployerradiant-project-bootstrapservice_accounts:pipeline-runner (runtime): The identity workloads run as at execution time — invoking functions, enqueuing tasks, reading secrets. Runtime-only permissions (invoker/user level, never admin). This IS defined in service_accounts:.
There is NO separate "pipeline-deployment" SA. The project-terraform-deployer handles both infrastructure and application deployment.
infrastructure/config/projects/<name>/
base.yaml # Required: org, region, services, roles, SAs, terraform_deployer
roles.yaml # Optional: project-specific custom IAM roles (if base roles don't suffice)
permissions.yaml # Optional: project-specific permission sets
environments/
dev.yaml # Required: dev environment config
staging.yaml # Required: staging environment config
prod.yaml # Required: prod environment config
Extract:
enrichments, data-pipeline)If the purpose is vague, ask the user what GCP services the project needs.
Read these files to understand the current patterns:
infrastructure/config/base/services.yaml # Available GCP API keys
infrastructure/config/base/permissions.yaml # Available permission sets
infrastructure/config/base/roles.yaml # Base role definitions (if any)
infrastructure/config/projects/irs990-biglake/base.yaml # Real project example
infrastructure/config/projects/example-multi-env/base.yaml # Template example
infrastructure/config/projects/example-multi-env/roles.yaml
infrastructure/config/projects/example-multi-env/environments/dev.yaml
Map the project's purpose to GCP API keys from config/base/services.yaml. Common mappings:
| Workload | Services |
|---|---|
| Serverless compute | cloud-functions, cloud-run |
| Task queues | cloud-tasks |
| Storage | cloud-storage |
| Secrets | secret-manager |
| Data warehouse | bigquery, bigquery-connection, bigquery-storage, biglake |
| Pub/Sub messaging | pubsub |
| Scheduling | cloud-scheduler |
| Artifact storage | artifact-registry |
Always include: resource-manager, iam (required for all projects).
Based on the project's workloads, define:
terraform_deployer section: Permission sets the deployer SA needs to provision and manage ALL project resources (infra + application). Always include iam-service-account-user, resource-manager-viewer, service-usage-viewer. Add admin-level sets for each service the project uses (e.g., cloud-functions-admin, storage-admin, cloud-tasks-admin).
Runtime role and SA: Name the role and SA based on the project's purpose — these are NOT fixed names. Examples: cloud-runner / pipeline-runner (for serverless compute), etl-runner (for data pipelines), data-analyst (for analytics). Permission sets should be runtime execution only — invoker/user level (e.g., cloud-functions-invoker, cloud-tasks-user, secrets-reader). Never admin permissions. A project may have multiple runtime SAs if it has distinct workload identities (see irs990-biglake which has biglake-admin, etl-runner, and data-analyst).
Reference available permission sets in config/base/permissions.yaml. If a needed permission set doesn't exist, note it — do NOT create base permission sets (those are shared infrastructure).
Create the following files:
base.yaml# <Project Display Name>
# Base configuration shared across all environments
# <1-line description of what this project does>
# GCP Organization settings (same for all environments)
org_id: "188734463578"
billing_account: "01DB6F-0C0182-01CFBA"
# Regional settings