Desired-state configuration, from source to environment. Terrabuild lets you declare a build or deployment outcome and its prerequisites. It coordinates your tools to reach that outcome, reusing valid results according to your policies.
This playground makes the idea concrete. Two applications depend on different libraries, produce images, and feed an optional local deployment simulation. You can change one input, inspect the required work, and see the environment's recorded versions change. It creates no cloud resources and does not start the application containers.
| Experience | Start here |
|---|---|
New to WORKSPACE and PROJECT |
Follow the two-project tutorial, then return here. |
| Want to understand this repository before building | Follow steps 1–2 below; no container execution is needed. |
| Ready for a complete delivery path | Continue through steps 3–6. |
| Want to change the model | Try the guided experiments. |
Install Terrabuild and Git.
Building and packaging also need a running Docker-compatible engine. The optional
deployment exercise lists its additional tool requirement. The report action uses the POSIX printf command, so
these instructions assume macOS or Linux. .NET and Node.js run in configured
containers. The first build downloads images and dependencies.
git clone https://github.com/MagnusOpera/terrabuild-playground.git
cd terrabuild-playground
terrabuild versionThe repository has two source branches:
flowchart LR
cslib["cslib · C# library"] --> api["webapi · .NET application"]
tslib["tslib · TypeScript library"] --> web["webapp · Vue application"]
api --> apiImage["webapi:dist · image"]
web --> webImage["webapp:dist · image"]
apiImage --> plan["infrastructure:plan · selected environment"]
webImage --> plan
plan --> deploy["infrastructure:deploy · record versions"]
Arrows show prerequisite order. The library and application project files describe
source relationships; WORKSPACE describes the target relationships. These files use Terrabuild's own configuration language. FScript implements
extensions; each integrated tool retains its own configuration and responsibilities.
Start with a small repository-owned FScript action:
terrabuild run describe --environment staging
cat src/deploy/delivery.txtThe report names staging and the source-version hashes of webapi and webapp.
It describes the desired source versions; it does not claim images exist or that
they have been deployed. No build or deployment action is required for this report.
Read these three pieces together:
WORKSPACEregisters thedeliveryextension and thedescribepolicy.src/deploy/PROJECTsupplies the environment and project versions.tools/delivery.fsstranslates that action into a command and captures its output indelivery.txt.
Now inspect the complete request:
terrabuild explain deploy --environment stagingRead the graph backwards from infrastructure:deploy: it needs a plan, the plan
needs both application distributions, and the distributions need application and
library builds. explain resolves the graph and extension operations without
executing those operations.
terrabuild run build
terrabuild run buildThe first request performs required builds. The second can reuse successful results because the declared inputs still match. Independent branches can run concurrently.
The shared build policy uses ~managed artifacts: local caching works without an
account, and Insights can share those outputs when connected. ~partition permits
native batching within compatible, connected groups. These are policies for this
example, not new commands you have to learn before building.
Change src/libs/cslib/DayHelpers.cs, then run:
terrabuild explain build
terrabuild run buildThe C# branch should be affected. The TypeScript branch can remain reusable. Keep the edit if you want to follow it into a deployment, or undo that specific edit with your editor.
terrabuild explain dist
terrabuild run distDocker owns the images. Terrabuild retains their successful summaries rather than
storing image layers in its artifact cache. A summary does not prove that an image
still exists after manual Docker cleanup; use terrabuild run dist --force to
recreate it when necessary.
These instructions are for local execution. The included Docker build action also
pushes images when running in CI. Before adapting the example to CI, configure
your own image repository and credentials in extension @docker.
The same model extends beyond builds and images. Request an environment-specific outcome, declare the artifacts it needs, and configure which actions must run on each request. An unchanged build can remain reusable while a deployment observes or changes external state.
The local deployment exercise demonstrates this with a simulation: record staging, compare a repeated request, then record production independently. It introduces the additional tool only when you reach that step.
Alternatively, continue directly with the guided experiments to customize FScript actions, compare batching, and inspect environment sensitivity.
Generated reports, plans, and local deployment state stay in this checkout and are ignored by Git. The deployment example selects state through shared local settings; run environment experiments sequentially in one checkout, or use separate checkouts for concurrent experiments.
To try another cold build, prefer a disposable clone or deliberately force the
selected targets. terrabuild clear --all clears the current user's Terrabuild
cache across repositories, so it is not a playground-only reset.
For users of an earlier playground revision, see the deployment migration note.