Workspaces
In preparation. This page describes the target interface to gather your feedback; nothing is usable yet.
Running OpenTofu modules is in preparation. This page describes the target interface to gather your feedback; the manifests are not accepted yet.
A Workspace declares an OpenTofu module (published as OCI) and its inputs. The platform
runs it for you, in your tenant, and publishes its outputs to a secret. You install
neither OpenTofu, nor a state backend, nor credentials on a machine.
What this changes compared to a local tofu apply
| Locally | With a Workspace |
|---|---|
| The state is on your machine or in a bucket you manage | The state is held by the platform, locked, per Workspace |
| Provider credentials are in your environment | They are in tenant secrets, injected into the run |
You rerun plan to see the drift | refresh.interval detects it and exposes it in the status |
| Dependencies between roots are managed by hand or with terragrunt | dependsOn and workspaceOutputRef chain Workspaces |
Example
apiVersion: tofu.stackngo.io/v1alpha1
kind: Workspace
metadata:
name: network
spec:
module:
source: oci://ovh-gra-0.registry.dev.stackngo.fr/acme/ovh-network
tag: 1.4.0
providers: [{name: ovh-gra}]
vars:
cidr: 10.20.0.0/16
refresh: {interval: 30m, mode: plan}
apiVersion: tofu.stackngo.io/v1alpha1
kind: Workspace
metadata:
name: app
spec:
module:
source: oci://ovh-gra-0.registry.dev.stackngo.fr/acme/ovh-instance
digest: sha256:9f1c… # digest rather than tag for a frozen version
providers: [{name: ovh-gra}]
dependsOn: [{name: network}]
vars: {size: s1-2}
varsFrom:
- workspaceOutputRef: {name: network, output: subnet_id}
default: subnet-mock # allows a plan before network has published
- secretRef: {name: app-secrets, key: ssh-key}
varName: ssh_public_key
refresh: {interval: 1h, mode: apply}
approval: manual
deletionPolicy: Orphan
Inputs
module.source: anoci://…reference, withtagordigest(never both; neither =latest).pullSecretRefif the registry requires authentication.vars: a free-form object, written as is toterraform.tfvars.json.varsFrom: a variable fed by a secret key (secretRef), or by an output of another Workspace of the tenant (workspaceOutputRef).varNamerenames;defaultgives a fallback value to plan before the parent has published (never to apply).providers: the tenant'sProviderresources to use, by name.imports: adopt existing resources (to= address in the module,idoridFroma secret).
Outputs
The module's outputs are written to a tenant secret, <name>-outputs by default
(spec.outputs.secretName), one key per output. A non-text output is JSON-encoded.
It is this secret that another Workspace reads via workspaceOutputRef, and that an App can
inject as an environment variable.
Refresh and drift
refresh.interval (at least 1m) reruns a periodic run:
mode: plan: detects drift without changing anything; theDriftedcondition switches toTrueandstatus.lastPlancounts additions, changes and destructions.mode: apply: reapplies to correct the drift.
A run is also triggered by any input change: spec, referenced secret, Provider, output of a parent.
Manual approval
With approval: manual, a plan that contains changes stops and waits. The
AwaitingApproval condition gives the plan identifier (status.lastPlan.id); approve it from the console or with the API. The apply re-plans and refuses if the result has changed in the meantime
(PlanChangedSinceApproval).
A state lock held by a third party blocks the runs (StateLocked, holder in status.lock);
if it is orphaned, contact support.
Dependencies
dependsOn enforces the order; workspaceOutputRef additionally creates a data link. A child
waits until its parents are Ready. When a parent's outputs change, its children
replay. Cycles are detected (DependencyCycle). With deletionPolicy: Destroy,
destruction happens in reverse order: a parent waits for its children to disappear.
Deletion
deletionPolicy | Effect of sng kind delete Workspace app |
|---|---|
Orphan (default) | The manifest and the state are removed; the created resources stay in place |
Destroy | tofu destroy is run first; refused if imports remain, unless explicitly authorized (planned) |
Read the state
The state of a Workspace will be displayed by sng. It will carry lastPlan (identifier, counters, hash), lastApply (date, result
Succeeded, Failed, Rejected, Interrupted, StateLocked), nextRunAt,
consecutiveFailures, and lock if a third-party lock blocks.