DEV Community

Cover image for Why Snap CD: An Extensive Supporting Toolset
Karl Schriek
Karl Schriek

Posted on • Originally published at snapcd.io

Why Snap CD: An Extensive Supporting Toolset

Snap CD ships with a full supporting ecosystem — documentation, a Terraform provider, deployment references, a guided sample, and a migration tool. This article walks through each one.

Documentation

The documentation site at docs.snapcd.io covers three layers:

Quickstart guides — step-by-step walkthroughs for both the Cloud and Self-Hosted editions. From zero to a working deployment in minutes.

Resource reference — detailed pages for every configurable resource: Stacks, Namespaces, Modules, Runners, Module Inputs, Secrets, Identity & Access Management, Agents, Missions, Integrations, Hooks, Flags, and more. Each page explains what the resource is, how it relates to other resources, and how to configure it.

Component documentation — architecture and operational details for the Server, Runner, and Agent (including Sidecars). Covers deployment topology, configuration settings, and the execution model.

Terraform Provider

The Snap CD Terraform Provider lets you manage all Snap CD configuration as code. Stacks, Namespaces, Modules, Runners, Sources, Inputs, Role Assignments, Agents, Missions, Integrations — everything you can configure in the dashboard, you can express in HCL.

resource "snapcd_namespace" "platform" {
  name     = "platform"
  stack_id = snapcd_stack.prod.id
}

resource "snapcd_module" "networking" {
  name             = "networking"
  namespace_id     = snapcd_namespace.platform.id
  source_url       = "https://github.com/example/infra.git"
  source_revision  = "main"
  runner_id        = data.snapcd_runner.platform.id
}

resource "snapcd_module" "compute" {
  name             = "compute"
  namespace_id     = snapcd_namespace.platform.id
  source_url       = "https://github.com/example/infra.git"
  source_revision  = "main"
  runner_id        = data.snapcd_runner.platform.id
}

resource "snapcd_module_input_from_output" "vpc_id" {
  module_id        = snapcd_module.compute.id
  input_kind       = "Param"
  name             = "vpc_id"
  output_module_id = snapcd_module.networking.id
  output_name      = "vpc_id"
}
Enter fullscreen mode Exit fullscreen mode

This is standard Terraform — you plan it, review it, apply it. Your Snap CD configuration lives in version control, goes through code review, and is reproducible across environments. You don't click through a UI to set up a new environment — you copy a Terraform module and change the variables.

The module-within-module pattern

The provider enables a composition pattern: a Snap CD Module that deploys additional Snap CD Modules.

Say you have a platform team that maintains base infrastructure. Application teams each need their own set of Modules that depend on platform Outputs. Rather than manually creating Modules for each team, you write a Terraform module that creates a Snap CD Namespace, creates the application's Modules within it, and wires the Inputs from platform Outputs:

resource "snapcd_namespace" "app" {
  name     = var.app_name
  stack_id = var.stack_id
}

resource "snapcd_module" "database" {
  name         = "database"
  namespace_id = snapcd_namespace.app.id
  source_url   = var.database_source_url
  runner_id    = var.runner_id
}

resource "snapcd_module_input_from_output" "cluster_endpoint" {
  module_id        = snapcd_module.database.id
  input_kind       = "Param"
  name             = "cluster_endpoint"
  output_module_id = var.platform_compute_module_id
  output_name      = "cluster_endpoint"
}
Enter fullscreen mode Exit fullscreen mode

Deploy this through Snap CD itself and you have a self-service system: the platform team defines the pattern once, and new applications are onboarded by adding an entry to a configuration file.

Reference Deployments

Snap CD components ship as Docker images and as zipped binaries on GitHub Releases. Three reference deployment repositories cover every common substrate, each containing a components/ directory with one self-contained sub-deployment per component (Server, Runner, Agent):

Substrate Repository
Docker / Compose schrieksoft/snapcd-deployment-docker
Kubernetes (Kustomize) schrieksoft/snapcd-deployment-kubernetes
Local (native binaries) schrieksoft/snapcd-deployment-local

You can bring up all three components together, or just the one you need — a Runner pointed at the Cloud edition, an Agent attached to a remote Server, etc. The images are version-pinned, the environment variables are documented, and each repo's README walks through both shapes.

These are the same deployment specifications used to run the Snap CD Cloud offering — not simplified demo versions.

Sample Deployment

The sample-deployment repository is a guided walkthrough that creates a realistic set of Snap CD resources using the Terraform Provider. It deploys four Modules with mock resources (no real cloud infrastructure needed) arranged in a dependency graph:

       |-----> cluster  ----- |
vpc ---|                      | ---> app
       |-----> database ----- |
Enter fullscreen mode Exit fullscreen mode

The sample is organized into numbered sections, each introducing a new resource type with inline commentary explaining the reasoning:

  1. Stack and Namespacesnapcd_namespace, snapcd_namespace_input_from_literal, snapcd_namespace_hook
  2. Module and literal Inputssnapcd_module, snapcd_module_input_from_literal (both Param and EnvVar kinds), snapcd_module_hook
  3. Output wiringsnapcd_module_input_from_output (single Output), approval thresholds
  4. Output Setssnapcd_module_input_from_output_set (all Outputs by name match), snapcd_module_terraform_flag
  5. Secrets and non-string typessnapcd_module_input_from_secret, type = "NotString" for numeric values
  6. Agents and Missionssnapcd_agent_namespace_supply, snapcd_namespace_mission (SummarizeJob, AutoDiagnose, ApprovalRecommend)

The goal is to be copied and adapted. After completing the Self-Hosted Quickstart, you can terraform apply the sample and have a working multi-Module environment with dependency wiring, approval gates, hooks, secrets, and AI Missions configured.

Demonolith — monolith migration tool

Demonolith is a Go CLI that refactors a monolithic Terraform/OpenTofu root into independent per-module roots — the first step toward managing them with Snap CD.

The problem it solves: a single-root monolith gets slow, risky, and coupled. A one-line change re-plans everything, and one broken resource can block unrelated ones. Splitting it by hand is error-prone — you need to move resources, carve state, create variable/output boundaries at every cross-module reference, and verify that nothing is inadvertently recreated.

Demonolith automates all of this. You annotate your resources with decorator comments indicating which Module each belongs to:

# @demono:move networking
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

# @demono:move compute
resource "aws_instance" "web" {
  subnet_id = aws_subnet.public.id
}
Enter fullscreen mode Exit fullscreen mode

Then run it:

# Emit carved roots (code only, offline):
demonolith split ./infra

# Also carve state into per-module local files:
demonolith split ./infra --state

# Carve + prove every module plans to zero create/destroy:
demonolith split ./infra --state --proof
Enter fullscreen mode Exit fullscreen mode

The pipeline:

  1. Parse — builds a resource-level reference graph via AST traversal (not regex — it catches refs inside templatefile(), jsonencode(), and index expressions).
  2. Place — resolves decorators into a total assignment. Undecorated resources fall to a configurable remainder module.
  3. Boundary — references crossing module boundaries become variable/output pairs. depends_on-only edges become ordering dependencies (no spurious value wiring).
  4. Cycle gate — refuses impossible splits with a named cycle path.
  5. Emit — writes per-module roots via hclwrite (formatting preserved), rewrites cross-module references to var.<input>, propagates providers and locals.
  6. State carveterraform state mv over local copies. Never touches the real backend.
  7. Proof — walks modules in topological order, threads each producer's extracted outputs into its consumers' inputs (the role Snap CD plays at runtime), and plans each against its carved state. Zero creates and zero destroys = the split is operationally inert.

The carved roots are plain Terraform — valid standalone, with the cross-module edges being exactly the wiring you'd configure in Snap CD via snapcd_module_input_from_output.

See also

Top comments (0)