Config Schema
The stacksolo.config.json file (located in .stacksolo/) defines your entire infrastructure.
Full Schema
Section titled “Full Schema”{ "project": { "name": "string", "gcpProjectId": "string", "region": "string", "backend": "cdktf", "plugins": ["string"],
"kernel": { "name": "string", "firebaseProjectId": "string", "gcsBucket": "string" },
"gcpKernel": { "name": "string", "firebaseProjectId": "string", "storageBucket": "string" },
"webAdmin": { "enabled": true, "port": 3000 },
"networks": [{ "name": "string", "storageBuckets": [{ "name": "string", "location": "string" }], "functions": [{ "name": "string", "runtime": "nodejs20", "entryPoint": "string", "memory": "256MB", "timeout": 60, "allowUnauthenticated": true, "sourceDir": "string", "trigger": { "type": "http | storage | pubsub", "bucket": "string", "event": "finalize" } }], "uis": [{ "name": "string", "hosting": "gcs | firebase", "framework": "vue", "sourceDir": "string", "buildCommand": "npm run build", "buildOutputDir": "dist" }], "containers": [{ "name": "string", "sourceDir": "string", "port": 8080 }], "loadBalancer": { "name": "string", "domain": "string", "enableHttps": true, "redirectHttpToHttps": true, "routes": [{ "path": "string", "backend": "string" }] } }] }}Project Properties
Section titled “Project Properties”Type: string (required)
The project name. Used for namespacing resources.
{ "project": { "name": "my-app" } }gcpProjectId
Section titled “gcpProjectId”Type: string (required)
Your Google Cloud project ID.
{ "project": { "gcpProjectId": "my-gcp-project-123" } }region
Section titled “region”Type: string (default: "us-central1")
GCP region for deploying resources.
{ "project": { "region": "us-west1" } }backend
Section titled “backend”Type: "cdktf" (default: "cdktf")
The infrastructure-as-code backend. Currently only CDKTF is supported.
plugins
Section titled “plugins”Type: string[] (optional)
List of plugins to load. Plugins are npm packages.
{ "project": { "plugins": [ "@stacksolo/plugin-gcp-cdktf", "@stacksolo/plugin-kernel" ] }}Cross-Resource References
Section titled “Cross-Resource References”StackSolo supports referencing outputs from other resources in environment variables. This enables service-to-service communication without hardcoding URLs.
Reference Syntax
Section titled “Reference Syntax”References use the @type/name.property format:
| Syntax | Description | Resolves To |
|---|---|---|
@function/name | Function URL (default) | Cloud Function HTTPS URL |
@function/name.url | Function URL (explicit) | Cloud Function HTTPS URL |
@container/name | Container URL (default) | Cloud Run service URL |
@container/name.url | Container URL (explicit) | Cloud Run service URL |
@secret/name | Secret value | Secret Manager secret (latest version) |
Example: Container calling a Function
Section titled “Example: Container calling a Function”{ "networks": [{ "name": "main", "functions": [{ "name": "mcp", "entryPoint": "handler", "allowUnauthenticated": true }], "containers": [{ "name": "api", "env": { "MCP_URL": "@function/mcp.url" } }] }]}At deploy time, @function/mcp.url is resolved to the actual Cloud Function URL. The container receives the real URL as an environment variable.
Example: Function calling another Function
Section titled “Example: Function calling another Function”{ "functions": [ { "name": "processor", "entryPoint": "handler" }, { "name": "orchestrator", "entryPoint": "handler", "env": { "PROCESSOR_URL": "@function/processor.url" } } ]}Example: Multiple cross-references
Section titled “Example: Multiple cross-references”{ "networks": [{ "name": "main", "functions": [ { "name": "auth", "entryPoint": "handler" }, { "name": "payments", "entryPoint": "handler" } ], "containers": [{ "name": "api", "env": { "AUTH_SERVICE_URL": "@function/auth.url", "PAYMENTS_SERVICE_URL": "@function/payments.url", "DATABASE_PASSWORD": "@secret/db-password" } }] }]}How It Works
Section titled “How It Works”- During deployment, StackSolo builds a dependency graph from references
- Referenced resources are deployed first
- References are resolved to CDKTF code references (e.g.,
${authFunction.url}) - Terraform substitutes actual URLs at apply time
This means you don’t need to know URLs in advance—they’re injected automatically.
Supported Reference Types
Section titled “Supported Reference Types”| Type | Properties | Default Property |
|---|---|---|
function | url, name | url |
container | url, name | url |
secret | (value) | (value) |
bucket | name, url, selfLink | name |
database | connectionString, privateIp, publicIp, instanceName, name | connectionString |
cache | host, port, connectionString, authString | host |
topic | name, id | name |
queue | name, id | name |
Cloudflare
Section titled “Cloudflare”Configuration for Cloudflare DNS integration. Requires @stacksolo/plugin-cloudflare.
cloudflare.zoneId
Section titled “cloudflare.zoneId”Type: string (required)
Your Cloudflare Zone ID (found in Cloudflare dashboard, Overview tab).
cloudflare.apiToken
Section titled “cloudflare.apiToken”Type: string (required)
Cloudflare API token with “Edit zone DNS” permission. Use @secret/ syntax for secure storage.
{ "project": { "cloudflare": { "zoneId": "your-zone-id", "apiToken": "@secret/cloudflare-api-token" } }}Kernel (NATS-based)
Section titled “Kernel (NATS-based)”For projects that need shared infrastructure services using NATS for messaging.
kernel.name
Section titled “kernel.name”Type: string (required)
Name of the kernel service.
kernel.firebaseProjectId
Section titled “kernel.firebaseProjectId”Type: string (optional)
Firebase project ID for authentication. Defaults to gcpProjectId.
kernel.gcsBucket
Section titled “kernel.gcsBucket”Type: string (optional)
GCS bucket for file storage. Auto-generated if not specified.
{ "project": { "kernel": { "name": "kernel", "firebaseProjectId": "my-firebase-project", "gcsBucket": "my-app-files" } }}GCP Kernel (Cloud Native)
Section titled “GCP Kernel (Cloud Native)”For projects using GCP-native services (Pub/Sub instead of NATS).
gcpKernel.name
Section titled “gcpKernel.name”Type: string (required)
Name of the GCP kernel service.
gcpKernel.firebaseProjectId
Section titled “gcpKernel.firebaseProjectId”Type: string (required)
Firebase project ID for authentication.
gcpKernel.storageBucket
Section titled “gcpKernel.storageBucket”Type: string (required)
GCS bucket for file operations.
{ "project": { "gcpKernel": { "name": "gcp-kernel", "firebaseProjectId": "my-firebase-project", "storageBucket": "my-app-storage" } }}Networks
Section titled “Networks”Networks group related services together.
network.name
Section titled “network.name”Type: string (required)
Network identifier.
network.storageBuckets
Section titled “network.storageBuckets”Type: BucketConfig[] (optional)
Cloud Storage buckets scoped to this network. Useful for function triggers.
{ "networks": [{ "name": "main", "storageBuckets": [ { "name": "uploads", "location": "us-central1" }, { "name": "processed" } ], "functions": [{ "name": "processor", "trigger": { "type": "storage", "bucket": "uploads", "event": "finalize" } }] }]}Each bucket supports these properties:
| Property | Type | Default | Description |
|---|---|---|---|
name | string | - | Bucket name (required) |
location | string | region | Bucket location |
storageClass | string | STANDARD | Storage class |
versioning | boolean | false | Enable versioning |
uniformBucketLevelAccess | boolean | true | Uniform IAM access |
publicAccess | boolean | false | Allow public access |
Functions
Section titled “Functions”Cloud Functions Gen2 definitions.
function.name
Section titled “function.name”Type: string (required)
Function name. Source code expected in functions/<name>/.
function.runtime
Section titled “function.runtime”Type: string (default: "nodejs20")
Runtime environment: nodejs18, nodejs20, python39, python310, python311, python312.
function.entryPoint
Section titled “function.entryPoint”Type: string (default: "handler")
The exported function name.
function.memory
Section titled “function.memory”Type: string (default: "256MB")
Memory allocation: 128MB, 256MB, 512MB, 1GB, 2GB, 4GB, 8GB.
function.timeout
Section titled “function.timeout”Type: number (default: 60)
Timeout in seconds (max: 540 for Gen2).
function.allowUnauthenticated
Section titled “function.allowUnauthenticated”Type: boolean (default: false)
Whether the function is publicly accessible.
function.sourceDir
Section titled “function.sourceDir”Type: string (optional)
Custom source directory. Defaults to functions/<name>.
{ "functions": [{ "name": "api", "runtime": "nodejs20", "entryPoint": "api", "memory": "512MB", "timeout": 120, "allowUnauthenticated": true }]}function.trigger
Section titled “function.trigger”Type: object (optional)
Event trigger configuration for non-HTTP functions.
| Property | Type | Description |
|---|---|---|
type | string | Trigger type: http (default), storage, pubsub |
bucket | string | Bucket name (required for storage triggers) |
event | string | Event type: finalize (default), delete, archive, metadataUpdate |
topic | string | Pub/Sub topic name (for pubsub triggers) |
Storage trigger example:
{ "functions": [{ "name": "pdf-processor", "runtime": "nodejs20", "entryPoint": "handler", "memory": "1GB", "timeout": 300, "trigger": { "type": "storage", "bucket": "uploads", "event": "finalize" } }]}When a file is uploaded to the uploads bucket, the function is automatically invoked with the file information.
Storage event types:
| Event | Description |
|---|---|
finalize | File created or overwritten (default) |
delete | File deleted |
archive | File archived (versioned buckets) |
metadataUpdate | File metadata changed |
Static site / frontend deployments.
ui.name
Section titled “ui.name”Type: string (required)
UI name. Source code expected in apps/<name>/.
ui.hosting
Section titled “ui.hosting”Type: "gcs" | "firebase" (default: "gcs")
Hosting provider:
gcs- Cloud Storage bucket with CDN (default). Good for static sites and admin panels.firebase- Firebase Hosting. Recommended for apps using Firebase Auth (avoids cross-origin cookie issues with OAuth).
ui.framework
Section titled “ui.framework”Type: string (default: auto-detected)
Framework: vue, react, sveltekit, html.
ui.sourceDir
Section titled “ui.sourceDir”Type: string (optional)
Custom source directory. Defaults to apps/<name>.
ui.buildCommand
Section titled “ui.buildCommand”Type: string (default: "npm run build")
Command to build the UI.
ui.buildOutputDir
Section titled “ui.buildOutputDir”Type: string (optional)
Build output directory. Defaults to dist (or build for SvelteKit).
GCS Hosting Example
Section titled “GCS Hosting Example”{ "uis": [{ "name": "docs", "hosting": "gcs", "framework": "vue", "sourceDir": "./apps/docs" }]}Firebase Hosting Example
Section titled “Firebase Hosting Example”{ "uis": [{ "name": "web", "hosting": "firebase", "framework": "vue", "sourceDir": "./apps/web" }]}Containers
Section titled “Containers”Cloud Run container deployments.
container.name
Section titled “container.name”Type: string (required)
Container name. Source code expected in containers/<name>/.
container.sourceDir
Section titled “container.sourceDir”Type: string (optional)
Custom source directory.
container.port
Section titled “container.port”Type: number (default: 8080)
Port the container listens on.
{ "containers": [{ "name": "worker", "port": 8080 }]}Load Balancer
Section titled “Load Balancer”HTTP(S) load balancer with path-based routing and optional HTTPS/SSL support.
loadBalancer.name
Section titled “loadBalancer.name”Type: string (required)
Load balancer name.
loadBalancer.domain
Section titled “loadBalancer.domain”Type: string (optional, required for IAP)
Custom domain for HTTPS. DNS must point to the load balancer IP after deployment.
loadBalancer.enableHttps
Section titled “loadBalancer.enableHttps”Type: boolean (default: false, required for IAP)
Enable HTTPS with a Google-managed SSL certificate. Requires domain to be set.
loadBalancer.redirectHttpToHttps
Section titled “loadBalancer.redirectHttpToHttps”Type: boolean (default: false)
Redirect all HTTP traffic to HTTPS. Recommended when enableHttps is true.
loadBalancer.dns
Section titled “loadBalancer.dns”Type: object (optional)
Automatic DNS configuration. Requires @stacksolo/plugin-cloudflare.
| Property | Type | Default | Description |
|---|---|---|---|
provider | string | - | DNS provider (cloudflare) |
proxied | boolean | true | Enable Cloudflare proxy (CDN, DDoS protection) |
loadBalancer.routes
Section titled “loadBalancer.routes”Type: Route[] (required)
Path-based routing rules.
route.path
Section titled “route.path”Type: string (required)
URL path pattern. Supports /* for prefix matching.
route.backend
Section titled “route.backend”Type: string (required)
Backend service name (must match a function, ui, or container name).
Basic Example (HTTP only)
Section titled “Basic Example (HTTP only)”{ "loadBalancer": { "name": "gateway", "routes": [ { "path": "/api/*", "backend": "api" }, { "path": "/*", "backend": "web" } ] }}HTTPS Example (required for IAP)
Section titled “HTTPS Example (required for IAP)”{ "loadBalancer": { "name": "gateway", "domain": "app.example.com", "enableHttps": true, "redirectHttpToHttps": true, "routes": [ { "path": "/api/*", "backend": "api" }, { "path": "/*", "backend": "web" } ] }}With Automatic Cloudflare DNS
Section titled “With Automatic Cloudflare DNS”{ "project": { "cloudflare": { "zoneId": "your-zone-id", "apiToken": "@secret/cloudflare-api-token" }, "networks": [{ "loadBalancer": { "name": "gateway", "domain": "app.example.com", "enableHttps": true, "dns": { "provider": "cloudflare", "proxied": true }, "routes": [{ "path": "/*", "backend": "api" }] } }] }}When dns.provider: cloudflare is set, the deployment automatically creates a DNS A record pointing your domain to the load balancer IP.
Web Admin
Section titled “Web Admin”Optional web-based admin panel.
webAdmin.enabled
Section titled “webAdmin.enabled”Type: boolean (default: false)
Enable the web admin UI during stacksolo dev.
webAdmin.port
Section titled “webAdmin.port”Type: number (default: 3000)
Port for the admin UI.
{ "project": { "webAdmin": { "enabled": true, "port": 3001 } }}Zero Trust (IAP)
Section titled “Zero Trust (IAP)”Protect backend services with Identity-Aware Proxy. Requires @stacksolo/plugin-zero-trust.
zeroTrust.iapWebBackends
Section titled “zeroTrust.iapWebBackends”Protect web backends with Google login.
| Property | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Configuration name |
backend | string | Yes | Backend name to protect (must match a function, container, or ui) |
allowedMembers | string[] | Yes | Who can access (see formats below) |
supportEmail | string | Yes | Email for OAuth consent screen |
applicationTitle | string | No | Title shown on login screen |
allowedMembers formats
Section titled “allowedMembers formats”user:alice@example.com # Individual usergroup:team@example.com # Google Groupdomain:example.com # Entire domainzeroTrust.iapTunnels
Section titled “zeroTrust.iapTunnels”SSH/TCP access to VMs without public IPs.
| Property | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Configuration name |
targetInstance | string | Yes | VM instance name |
targetZone | string | Yes | Zone (e.g., us-central1-a) |
allowedMembers | string[] | Yes | Who can access |
allowedPorts | number[] | No | Ports to allow (default: [22]) |
network | string | No | VPC network name (default: default) |
{ "zeroTrust": { "iapWebBackends": [{ "name": "admin-protection", "backend": "admin", "allowedMembers": ["domain:mycompany.com"], "supportEmail": "admin@mycompany.com" }], "iapTunnels": [{ "name": "dev-ssh", "targetInstance": "dev-vm", "targetZone": "us-central1-a", "allowedMembers": ["group:developers@mycompany.com"], "allowedPorts": [22, 3306] }] }}Example: Full Config
Section titled “Example: Full Config”{ "project": { "name": "my-saas", "gcpProjectId": "my-gcp-project", "region": "us-central1", "backend": "cdktf", "plugins": ["@stacksolo/plugin-gcp-cdktf"],
"kernel": { "name": "kernel", "firebaseProjectId": "my-firebase-project" },
"webAdmin": { "enabled": true },
"networks": [{ "name": "main", "functions": [ { "name": "api", "entryPoint": "api", "allowUnauthenticated": true }, { "name": "webhook", "entryPoint": "handler", "timeout": 300 } ], "uis": [ { "name": "web", "framework": "vue" } ], "loadBalancer": { "name": "gateway", "routes": [ { "path": "/api/*", "backend": "api" }, { "path": "/webhook/*", "backend": "webhook" }, { "path": "/*", "backend": "web" } ] } }] }}Example: Full Config with Zero Trust
Section titled “Example: Full Config with Zero Trust”Public API + protected admin panel + SSH access to dev VM.
{ "project": { "name": "my-saas", "gcpProjectId": "my-gcp-project", "region": "us-central1", "backend": "cdktf", "plugins": [ "@stacksolo/plugin-gcp-cdktf", "@stacksolo/plugin-zero-trust" ],
"networks": [{ "name": "main", "functions": [ { "name": "api", "entryPoint": "api", "allowUnauthenticated": true } ], "containers": [ { "name": "admin", "port": 3000 } ], "uis": [ { "name": "docs", "framework": "vue" } ], "loadBalancer": { "name": "gateway", "domain": "my-saas.example.com", "enableHttps": true, "redirectHttpToHttps": true, "routes": [ { "path": "/api/*", "backend": "api" }, { "path": "/admin/*", "backend": "admin" }, { "path": "/*", "backend": "docs" } ] } }],
"zeroTrust": { "iapWebBackends": [ { "name": "admin-protection", "backend": "admin", "allowedMembers": [ "domain:mycompany.com", "user:contractor@gmail.com" ], "supportEmail": "admin@mycompany.com", "applicationTitle": "Admin Dashboard" } ], "iapTunnels": [ { "name": "dev-ssh", "targetInstance": "dev-vm", "targetZone": "us-central1-a", "allowedMembers": ["group:engineering@mycompany.com"], "allowedPorts": [22] }, { "name": "db-access", "targetInstance": "prod-db", "targetZone": "us-central1-a", "allowedMembers": ["group:dba@mycompany.com"], "allowedPorts": [5432] } ] } }}What this creates:
| Resource | Access |
|---|---|
/api/* | Public (anyone) |
/admin/* | IAP protected (mycompany.com domain + contractor) |
/* (docs) | Public (anyone) |
dev-vm SSH | IAP tunnel (engineering group) |
prod-db PostgreSQL | IAP tunnel (dba group) |
After deployment:
# Public API - just workscurl https://my-saas.example.com/api/health
# Admin panel - visit in browser, Google login requiredopen https://my-saas.example.com/admin
# SSH to dev VMgcloud compute ssh dev-vm --zone=us-central1-a --tunnel-through-iap
# Connect to prod databasegcloud compute start-iap-tunnel prod-db 5432 \ --zone=us-central1-a \ --local-host-port=localhost:5432psql -h localhost -p 5432 -U postgres