Skip to content

Config Schema

The stacksolo.config.json file (located in .stacksolo/) defines your entire infrastructure.

{
"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"
}]
}
}]
}
}

Type: string (required)

The project name. Used for namespacing resources.

{ "project": { "name": "my-app" } }

Type: string (required)

Your Google Cloud project ID.

{ "project": { "gcpProjectId": "my-gcp-project-123" } }

Type: string (default: "us-central1")

GCP region for deploying resources.

{ "project": { "region": "us-west1" } }

Type: "cdktf" (default: "cdktf")

The infrastructure-as-code backend. Currently only CDKTF is supported.

Type: string[] (optional)

List of plugins to load. Plugins are npm packages.

{
"project": {
"plugins": [
"@stacksolo/plugin-gcp-cdktf",
"@stacksolo/plugin-kernel"
]
}
}

StackSolo supports referencing outputs from other resources in environment variables. This enables service-to-service communication without hardcoding URLs.

References use the @type/name.property format:

SyntaxDescriptionResolves To
@function/nameFunction URL (default)Cloud Function HTTPS URL
@function/name.urlFunction URL (explicit)Cloud Function HTTPS URL
@container/nameContainer URL (default)Cloud Run service URL
@container/name.urlContainer URL (explicit)Cloud Run service URL
@secret/nameSecret valueSecret Manager secret (latest version)
{
"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"
}
}
]
}
{
"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"
}
}]
}]
}
  1. During deployment, StackSolo builds a dependency graph from references
  2. Referenced resources are deployed first
  3. References are resolved to CDKTF code references (e.g., ${authFunction.url})
  4. Terraform substitutes actual URLs at apply time

This means you don’t need to know URLs in advance—they’re injected automatically.

TypePropertiesDefault Property
functionurl, nameurl
containerurl, nameurl
secret(value)(value)
bucketname, url, selfLinkname
databaseconnectionString, privateIp, publicIp, instanceName, nameconnectionString
cachehost, port, connectionString, authStringhost
topicname, idname
queuename, idname

Configuration for Cloudflare DNS integration. Requires @stacksolo/plugin-cloudflare.

Type: string (required)

Your Cloudflare Zone ID (found in Cloudflare dashboard, Overview tab).

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"
}
}
}

For projects that need shared infrastructure services using NATS for messaging.

Type: string (required)

Name of the kernel service.

Type: string (optional)

Firebase project ID for authentication. Defaults to gcpProjectId.

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"
}
}
}

For projects using GCP-native services (Pub/Sub instead of NATS).

Type: string (required)

Name of the GCP kernel service.

Type: string (required)

Firebase project ID for authentication.

Type: string (required)

GCS bucket for file operations.

{
"project": {
"gcpKernel": {
"name": "gcp-kernel",
"firebaseProjectId": "my-firebase-project",
"storageBucket": "my-app-storage"
}
}
}

Networks group related services together.

Type: string (required)

Network identifier.

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:

PropertyTypeDefaultDescription
namestring-Bucket name (required)
locationstringregionBucket location
storageClassstringSTANDARDStorage class
versioningbooleanfalseEnable versioning
uniformBucketLevelAccessbooleantrueUniform IAM access
publicAccessbooleanfalseAllow public access

Cloud Functions Gen2 definitions.

Type: string (required)

Function name. Source code expected in functions/<name>/.

Type: string (default: "nodejs20")

Runtime environment: nodejs18, nodejs20, python39, python310, python311, python312.

Type: string (default: "handler")

The exported function name.

Type: string (default: "256MB")

Memory allocation: 128MB, 256MB, 512MB, 1GB, 2GB, 4GB, 8GB.

Type: number (default: 60)

Timeout in seconds (max: 540 for Gen2).

Type: boolean (default: false)

Whether the function is publicly accessible.

Type: string (optional)

Custom source directory. Defaults to functions/<name>.

{
"functions": [{
"name": "api",
"runtime": "nodejs20",
"entryPoint": "api",
"memory": "512MB",
"timeout": 120,
"allowUnauthenticated": true
}]
}

Type: object (optional)

Event trigger configuration for non-HTTP functions.

PropertyTypeDescription
typestringTrigger type: http (default), storage, pubsub
bucketstringBucket name (required for storage triggers)
eventstringEvent type: finalize (default), delete, archive, metadataUpdate
topicstringPub/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:

EventDescription
finalizeFile created or overwritten (default)
deleteFile deleted
archiveFile archived (versioned buckets)
metadataUpdateFile metadata changed

Static site / frontend deployments.

Type: string (required)

UI name. Source code expected in apps/<name>/.

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).

Type: string (default: auto-detected)

Framework: vue, react, sveltekit, html.

Type: string (optional)

Custom source directory. Defaults to apps/<name>.

Type: string (default: "npm run build")

Command to build the UI.

Type: string (optional)

Build output directory. Defaults to dist (or build for SvelteKit).

{
"uis": [{
"name": "docs",
"hosting": "gcs",
"framework": "vue",
"sourceDir": "./apps/docs"
}]
}
{
"uis": [{
"name": "web",
"hosting": "firebase",
"framework": "vue",
"sourceDir": "./apps/web"
}]
}

Cloud Run container deployments.

Type: string (required)

Container name. Source code expected in containers/<name>/.

Type: string (optional)

Custom source directory.

Type: number (default: 8080)

Port the container listens on.

{
"containers": [{
"name": "worker",
"port": 8080
}]
}

HTTP(S) load balancer with path-based routing and optional HTTPS/SSL support.

Type: string (required)

Load balancer name.

Type: string (optional, required for IAP)

Custom domain for HTTPS. DNS must point to the load balancer IP after deployment.

Type: boolean (default: false, required for IAP)

Enable HTTPS with a Google-managed SSL certificate. Requires domain to be set.

Type: boolean (default: false)

Redirect all HTTP traffic to HTTPS. Recommended when enableHttps is true.

Type: object (optional)

Automatic DNS configuration. Requires @stacksolo/plugin-cloudflare.

PropertyTypeDefaultDescription
providerstring-DNS provider (cloudflare)
proxiedbooleantrueEnable Cloudflare proxy (CDN, DDoS protection)

Type: Route[] (required)

Path-based routing rules.

Type: string (required)

URL path pattern. Supports /* for prefix matching.

Type: string (required)

Backend service name (must match a function, ui, or container name).

{
"loadBalancer": {
"name": "gateway",
"routes": [
{ "path": "/api/*", "backend": "api" },
{ "path": "/*", "backend": "web" }
]
}
}
{
"loadBalancer": {
"name": "gateway",
"domain": "app.example.com",
"enableHttps": true,
"redirectHttpToHttps": true,
"routes": [
{ "path": "/api/*", "backend": "api" },
{ "path": "/*", "backend": "web" }
]
}
}
{
"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.


Optional web-based admin panel.

Type: boolean (default: false)

Enable the web admin UI during stacksolo dev.

Type: number (default: 3000)

Port for the admin UI.

{
"project": {
"webAdmin": {
"enabled": true,
"port": 3001
}
}
}

Protect backend services with Identity-Aware Proxy. Requires @stacksolo/plugin-zero-trust.

Protect web backends with Google login.

PropertyTypeRequiredDescription
namestringYesConfiguration name
backendstringYesBackend name to protect (must match a function, container, or ui)
allowedMembersstring[]YesWho can access (see formats below)
supportEmailstringYesEmail for OAuth consent screen
applicationTitlestringNoTitle shown on login screen
user:alice@example.com # Individual user
group:team@example.com # Google Group
domain:example.com # Entire domain

SSH/TCP access to VMs without public IPs.

PropertyTypeRequiredDescription
namestringYesConfiguration name
targetInstancestringYesVM instance name
targetZonestringYesZone (e.g., us-central1-a)
allowedMembersstring[]YesWho can access
allowedPortsnumber[]NoPorts to allow (default: [22])
networkstringNoVPC 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]
}]
}
}

{
"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" }
]
}
}]
}
}

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:

ResourceAccess
/api/*Public (anyone)
/admin/*IAP protected (mycompany.com domain + contractor)
/* (docs)Public (anyone)
dev-vm SSHIAP tunnel (engineering group)
prod-db PostgreSQLIAP tunnel (dba group)

After deployment:

Terminal window
# Public API - just works
curl https://my-saas.example.com/api/health
# Admin panel - visit in browser, Google login required
open https://my-saas.example.com/admin
# SSH to dev VM
gcloud compute ssh dev-vm --zone=us-central1-a --tunnel-through-iap
# Connect to prod database
gcloud compute start-iap-tunnel prod-db 5432 \
--zone=us-central1-a \
--local-host-port=localhost:5432
psql -h localhost -p 5432 -U postgres