Parent stack

Parent stack — one YAML, every service

Declarative server + client stacks. server.yaml describes shared infrastructure; client.yaml describes a service that uses it. Three deployment types: cloud-compose, single-image, static.

Shared infrastructure in one file
server.yaml declares the provisioner, resources (Mongo Atlas, RDS, S3, ECR, Helm operators), and registrars. The whole platform in one place.
Services as child stacks
client.yaml references the parent’s resources via ${resource:mongo.uri}. SC wires it at deploy time — no glue code.
Three deployment types
Pick cloud-compose, single-image, or static per service. The cloud target is a template, not a rewrite.
Secrets are first-class
Reference ${secret:my_key} in any client.yaml. SSH-key multi-key encryption (RSA or Ed25519); ciphertext in git, plaintext at deploy.

What it does

A parent stack declares what your team shares — databases, queues, container registries, DNS zone, ACM certs, secrets store. A child stack declares a service that uses some of those resources and how it runs. The whole thing is two YAML files plus an encrypted secrets.yaml.

1
2
3
4
5
6
7
# First time: scaffold and provision the parent
sc init
sc secrets init --generate
sc provision -s my-infra -e prod

# Deploy a child service that uses it
sc deploy -s my-service -e prod

The shape of a stack

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# .sc/stacks/my-infra/server.yaml — the parent
provisioner:
  type: pulumi
  config:
    state-storage:    { type: s3-bucket, ... }
    secrets-provider: { type: passphrase, ... }

# Compute templates the platform offers
templates:
  lambda:      { type: aws-lambda }
  static-site: { type: aws-static-website }
  api-fargate: { type: ecs-fargate }

resources:
  # ── account-wide resources (shared across all envs) ────────────
  registrar:
    type: cloudflare
    config: { credentials: "${secret:CLOUDFLARE_API_TOKEN}", ... }

  # ── per-environment defaults + resources ───────────────────────
  resources:
    staging:
      template: lambda                    # default template for this env
      resources:
        mongodb: { type: mongodb-atlas, config: { ... } }
        redis:   { type: kubernetes-helm-redis-operator, config: { ... } }
    prod:
      template: lambda
      resources:
        mongodb: { type: mongodb-atlas, config: { ... } }
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# .sc/stacks/my-service/client.yaml — a child
stacks:
  prod:
    type: single-image
    template: lambda
    parent: my-org/my-infra
    config:
      domain: api.my-org.com
      uses: [mongodb, redis]
      env:
        MONGO_URI: "${resource:mongodb.uri}"
        REDIS_URL: "${resource:redis.url}"

sc deploy -s my-service -e prod wires the resources, decrypts secrets, builds the Docker image, deploys to the chosen cloud, sets up DNS, attaches an SSL cert. One command.

How it’s different

ToolWhat it doesWhat SC does differently
TerraformDeclarative IaC; you write modulesSC describes services; the cloud template is a flag, not a module rewrite
PulumiImperative IaC in your languageSC uses Pulumi underneath; you don’t write Pulumi code
Helmk8s-shaped chart templatingSC supports Kubernetes templates (kubernetes-cloudrun, k8s Helm DB operators), but isn’t k8s-coupled
Heroku / FlyOpinionated PaaSOwned-by-you infra with PaaS-like ergonomics; resources and templates are open primitives

Real-world: Forge

Our flagship product, Forge, is described in one parent stack at forge/.sc/stacks/infra/server.yaml plus several child stacks across multiple repos. Every Forge component — the AI gateway, the conductor, the runtime workers, the sessions store — is a client.yaml that references the parent. We dogfood the model.

Ship your infrastructure on autopilot.

Try the SC parent stack in your own repo, or see what we built on top of it — Forge, our flagship AI workflow engine for teams.