Getting Started

Audience: DevOps engineer seeing strata (soon: ruck) for the first time. Goal: install the tool, initialize a config workspace, and validate a config file β€” in under 10 minutes.


Prerequisites

Tool

Version

Why

Python

3.13+

Runtime

pipx or uv

latest

Package install

Terraform

1.6+

Infrastructure provisioning

Azure CLI

latest

Azure authentication

kubectl

latest

AKS cluster management (AKS deployments only)

Not sure which tools you have installed? After initializing a workspace, run:

strata tools status --missing

This lists every external tool strata expects (Terraform, Azure CLI, kubectl, Helm, etc.) that is not currently on your PATH β€” the fastest way to find out what’s missing on day one.


Install

Recommended (isolated install):

pipx install xyz-strata
strata --version

Dev install (from source):

git clone git@github.com:org/strata.git
cd strata
uv sync
uv run strata --version

Dev Container / no PyPI access:

If your repo already uses a Dev Container and you cannot reach PyPI, inject strata directly from the published container image β€” no Python install needed:

# .devcontainer/Dockerfile
FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04

# Copy the pre-built strata venv from the GHCR image
COPY --from=ghcr.io/huybrechtsxyz/strata:latest /app/.venv /opt/strata

ENV PATH="/opt/strata/bin:$PATH"
// .devcontainer/devcontainer.json
{
  "name": "my-repo",
  "build": { "dockerfile": "Dockerfile" },
  "remoteUser": "vscode"
}

Open the repo in VS Code β†’ Reopen in Container β†’ strata --help works immediately.

Air-gapped / private registry:

If you also cannot reach GHCR, mirror the image to your own registry first:

docker pull ghcr.io/huybrechtsxyz/strata:latest
docker tag  ghcr.io/huybrechtsxyz/strata:latest myregistry.example.com/strata:latest
docker push myregistry.example.com/strata:latest

Then reference myregistry.example.com/strata:latest in the COPY --from line above. No outbound internet required at container build time.


Initialize a Workspace

Run strata sln init inside your config repository (the repo that holds your environment YAML files):

cd my-config-repo
strata sln init --name my-workspace

What gets created:

my-config-repo/
β”œβ”€β”€ .strata/
β”‚   β”œβ”€β”€ solution.json      ← workspace registry (solution model)
β”‚   β”œβ”€β”€ cli.yaml           ← your persisted CLI preferences
β”‚   └── logging.yaml       ← log level and output config
└── .devcontainer/
    β”œβ”€β”€ devcontainer.json  ← VS Code Dev Container definition
    └── post-create.sh     ← post-create setup script

VS Code users: After init, use Reopen in Container to get a fully configured dev environment with all tools pre-installed.

Scaffold with a template

Add --template <name> to get a ready-to-edit config folder alongside the workspace state:

strata sln init --name my-aks --template aks

This copies a working set of example config files into the repo root, with my-aks substituted wherever the template uses {{ solution_name }}:

my-config-repo/
β”œβ”€β”€ config/
β”‚   └── my-aks-config.yaml     ← platform configuration (providers, integrations)
β”œβ”€β”€ stack/
β”‚   β”œβ”€β”€ ws-platform.yaml       ← workspace definition
β”‚   β”œβ”€β”€ ns-base.yaml           ← base namespace
β”‚   └── mod-traefik.yaml       ← Traefik Helm module
β”œβ”€β”€ deploy/
β”‚   └── deploy-prd.yaml        ← production deployment descriptor
β”œβ”€β”€ envs/
β”‚   └── env-prd.yaml           ← environment variables (fill in secrets)
└── .strata/                   ← workspace state (as above)

The output tells you exactly what to do next:

βœ…  Solution 'my-aks' initialised
    β€’ Work path    : /path/to/my-config-repo
    β€’ Solution ID  : abc-123
    β€’ Template     : aks
    β€’ Files created: 6

Next steps:
    1. Register your repo:   strata repo add my-aks <git-url> --clone
    2. Add a profile:        strata profile add prd --activate
    3. Validate:             strata validate --file deploy/deploy-prd.yaml
    4. Deploy:               strata deploy run --file deploy/deploy-prd.yaml

Built-in templates:

Name

Description

aks

Azure Kubernetes Service β€” Terraform + Helm starter

compose

Docker Compose / Swarm services starter

Using a local template folder:

strata sln init --name my-ws --template ./my-corporate-template/

The folder must contain a scaffold/ subdirectory with the files to copy. An optional template.yaml declares the template name, description, and substitution variables.

Save your workspace as a template

Once you have a working workspace, capture it as a reusable scaffold for the next project:

strata sln export --name my-corp-base

What it does:

  • Copies all workspace config files into .strata/templates/my-corp-base/scaffold/

  • Replaces the current solution name with {{ solution_name }} throughout β€” ready to substitute on next init

  • Shows every substitution so you can spot false positives

Output:

βœ…  Template 'my-corp-base' exported
    β€’ Output       : .strata/templates/my-corp-base/
    β€’ Files saved  : 6
    β€’ Substitutions: 14 occurrences across 6 files

Use it:
    strata sln init --name new-project --template .strata/templates/my-corp-base/

Use --dry-run to preview without writing. Use --force to overwrite an existing template.

After upgrading strata

When you upgrade the strata package, run sln update to refresh package-owned files (schemas, templates, devcontainer config) in your workspace:

strata sln update

User-owned files (.strata/cli.yaml, .strata/logging.yaml, your README.md, .vscode/ settings) are never overwritten. See strata sln update in the commands reference for the full list of affected files.


File Structure

Config files follow a Kubernetes-style format (apiVersion, kind, meta, spec):

apiVersion: strata.huybrechts.xyz/v1
kind: deployment
meta:
  name: my-environment
  annotations:
    description: Production AKS cluster β€” EU West
spec:
  profile: prd
  workspace: "@xyz-config/config/xyz-config.yaml"
  modules:
    - "@xyz-config/stack/ns-base.yaml"
    - "@xyz-config/stack/mod-traefik.yaml"

Cross-repository file references use @repo-name/path/to/file.yaml notation. The @ prefix tells strata to resolve the path through the registered repo map.

Typical workspace layout:

my-config-repo/
β”œβ”€β”€ stack/          ← reusable module and namespace configs
β”œβ”€β”€ deploy/         ← environment deployment files (one per env)
β”œβ”€β”€ envs/           ← environment-specific variable overrides
└── config/         ← global configuration (workspace-level)

Register Repositories

If your config references files from other repos (Terraform, service configs), register them:

strata repo add xyz-config git@github.com:org/xyz-config.git --branch main --clone
strata repo add xyz-infrastructure git@github.com:org/xyz-infrastructure.git --branch main --clone

Set an Active Profile

Profiles group environment-specific overrides (think: dev, staging, prd):

strata profile add prd --activate
strata profile list

Validate

Before deploying anything, validate your config file:

strata validate --file stack/my-environment.yaml

A clean run exits 0 and prints a summary. A validation failure exits 3 and tells you:

  • which file failed

  • which field is invalid

  • what the valid options are

Run against all files to catch cross-reference errors early:

strata validate --file deploy/my-environment.yaml

Preview Changes

Before deploying, review what would change:

strata build plan -f deploy/my-environment.yaml

This is read-only β€” nothing is modified. It builds artifacts to a temp directory, diffs against the current build, and runs terraform plan against remote state. Review the output, then deploy when satisfied.


Deploy

Once validation passes:

strata deploy run --file deploy/my-environment.yaml

This orchestrates the full lifecycle: resolves @-references, runs Terraform, applies Helm charts, and executes any pre/post scripts. Terraform output streams directly to your terminal.


If Something Goes Wrong

Check the execution log β€” every command execution is logged:

strata log list
strata log list --last

To configure logging behaviour (levels, output format), use strata config log.

Run with verbose output to see every subprocess call and argument:

strata validate --file stack/my-environment.yaml --verbose
strata deploy run --file deploy/my-environment.yaml --verbose

Structured output for automation or debugging:

strata validate --file stack/my-environment.yaml --output json

Diagnose value resolution β€” see exactly where each variable, secret, and feature flag comes from and whether it resolved:

strata values resolve -f deploy/my-environment.yaml
strata values resolve -f deploy/my-environment.yaml -k MY_SECRET  # single key
strata values resolve -f deploy/my-environment.yaml --probe       # also test backend reachability

Exit code 3 means one or more values failed to resolve.


Persist Your Preferences

Stop passing the same flags on every command:

strata config set output json      # always use JSON output
strata config set verbose true     # always show verbose logs
strata config list                 # check what's set

Shell Completion

Enable Tab completion for all commands, subcommands, and options:

Bash β€” add to ~/.bashrc:

eval "$(_STRATA_COMPLETE=bash_source strata)"

Zsh β€” add to ~/.zshrc:

eval "$(_STRATA_COMPLETE=zsh_source strata)"

Fish β€” add to ~/.config/fish/completions/strata.fish:

_STRATA_COMPLETE=fish_source strata | source

Faster startup (generate a static script instead of eval on every shell open):

_STRATA_COMPLETE=bash_source strata > ~/.strata-complete.bash
echo ". ~/.strata-complete.bash" >> ~/.bashrc

After reloading your shell, strata <TAB> completes commands and --<TAB> completes options.


Next Steps

Tip: Use strata new --list to see all built-in config file templates, then strata new namespace my-ns (or any other kind) to scaffold a new YAML file with meta.name pre-filled and all spec fields as editable placeholders.