Workspace
Fonctionnalité en préparation. Cette page décrit l'interface cible pour recueillir vos retours ; rien n'est encore utilisable.
Les workspaces OpenTofu sont en préparation : ce manifeste n'est pas encore accepté par sng apply. Le schéma ci-dessous est celui de la version cible.
apiVersion | tofu.stackngo.io/v1alpha1 |
kind | Workspace |
| Appliqué par | sng apply (à venir) |
| Commandes liées | sng kind get Workspace, sng kind delete Workspace |
À quoi ça sert
Un Workspace applique un module OpenTofu publié en OCI dans votre tenant : la plateforme
exécute init, plan, apply dans un conteneur éphémère, tient le state et son verrou,
publie les outputs dans un secret et détecte la dérive. Guide : Workspaces.
Exemple minimal
apiVersion: tofu.stackngo.io/v1alpha1
kind: Workspace
metadata:
name: pet
spec:
module:
source: oci://ovh-gra-0.registry.dev.stackngo.fr/acme/random-pet
tag: 1.0.0
Exemple complet commenté
apiVersion: tofu.stackngo.io/v1alpha1
kind: Workspace
metadata:
name: app
spec:
module:
source: oci://ovh-gra-0.registry.dev.stackngo.fr/acme/ovh-instance # oci:// obligatoire
digest: sha256:9f1c… # ou tag ; jamais les deux
pullSecretRef: {name: registry-creds} # si le registre exige une authentification
providers:
- {name: ovh-gra} # Provider du tenant
dependsOn:
- {name: network} # ordre d'exécution
vars: # écrit en terraform.tfvars.json
size: s1-2
varsFrom:
- workspaceOutputRef: {name: network, output: subnet_id}
default: subnet-mock # plan possible avant publication du parent, jamais apply
- secretRef: {name: app-secrets, key: ssh-key}
varName: ssh_public_key # renomme la variable
imports:
- {to: ovh_cloud_project_instance.this, id: "i-123"}
outputs:
secretName: app-outputs # défaut : <nom>-outputs
refresh:
interval: 30m # ≥ 1m
mode: plan # plan (dérive) | apply
approval: manual # auto | manual
deletionPolicy: Orphan # Orphan | Destroy
suspend: false
Champs
Règles de validation croisées
module.tagetmodule.digestsont exclusifs ;digestsuit^sha256:[a-f0-9]{64}$.- Dans
varsFrom, exactement une source :secretRefouworkspaceOutputRef;varNameexigesecretRef.key;defaultn'existe qu'avecworkspaceOutputRef. - Dans
imports, exactement un identifiant :idouidFrom. refresh.intervalvaut au moins1m.
Workspace
Workspace applique un module OpenTofu publié en OCI, dans des exécutions propres à votre tenant.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
apiVersion string | tofu.stackngo.io/v1alpha1 | ||
kind string | Workspace | ||
metadata ObjectMeta | Seul metadata.name est à renseigner (nom de la ressource dans votre tenant). | ||
spec WorkspaceSpec | |||
status WorkspaceStatus |
WorkspaceSpec
WorkspaceSpec : module OCI à appliquer et ses entrées.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
module ModuleSource | Module OpenTofu à appliquer : adresse OCI, version (tag) ou empreinte (digest). | ||
providers LocalRef array | Providers : Provider de votre tenant câblés dans le run (bloc provider généré). | Optional: {} | |
dependsOn LocalRef array | DependsOn : Workspace de votre tenant qui doivent être Ready avant tout run (ordre seul). | Optional: {} | |
vars JSON | Vars : valeurs JSON libres, écrites dans terraform.tfvars.json. | Type: object Optional: {} | |
varsFrom VarsFromSource array | VarsFrom : variables secrètes, injectées en TF_VAR_<nom>. Prioritaires sur Vars. | Optional: {} | |
imports ImportSpec array | Imports : ressources existantes adoptées par des blocs import (no-op une fois dans le state). | Optional: {} | |
backend BackendSpec | Où conserver le state. Absent : la plateforme le conserve pour vous. | Optional: {} | |
outputs OutputsSpec | Où publier les outputs du module. | Optional: {} | |
refresh RefreshSpec | Exécution périodique pour détecter la dérive. Absent : aucun run hors changement de manifeste ou de secret. | Optional: {} | |
approval Approval | auto (défaut) applique le plan sans intervention ; manual attend votre approbation du plan. | auto | Enum: [auto manual] Optional: {} |
deletionPolicy DeletionPolicy | Sort de l'infrastructure à la suppression du Workspace : Orphan (défaut) la laisse en place, Destroy la détruit d'abord. | Orphan | Enum: [Orphan Destroy] Optional: {} |
suspend boolean | Suspend : aucun nouveau run tant que vrai. | Optional: {} | |
resources ResourceRequirements | Resources : ressources du conteneur tofu. Absent = valeurs par défaut de la plateforme. | Optional: {} |
WorkspaceStatus
WorkspaceStatus : état observé.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
observedGeneration integer | Dernière version du manifeste prise en compte par la plateforme. | Optional: {} | |
conditions Condition array | Conditions : Ready, Drifted, Planning, Applying, AwaitingApproval, Failed. | Optional: {} | |
lastPlan PlanSummary | Résumé du dernier plan : identifiant, date et nombre de changements. | Optional: {} | |
lastApply ApplySummary | Résumé du dernier apply : date, résultat et message. | Optional: {} | |
activeJob string | ActiveJob : exécution en cours (une seule à la fois par Workspace). | Optional: {} | |
nextRunAt Time | NextRunAt : prochain run périodique. | Optional: {} | |
inputsHash string | InputsHash : empreinte des entrées (spec, secrets, Providers, outputs des parents) du dernier run réussi. | Optional: {} | |
lastRunJob string | LastRunJob : dernière exécution dont le résultat a été pris en compte. | Optional: {} | |
lastRunAt Time | LastRunAt : fin du dernier run. | Optional: {} | |
consecutiveFailures integer | ConsecutiveFailures : échecs consécutifs (backoff des reprises), remis à zéro par un succès. | Optional: {} | |
dependencies DependencyStatus array | Dependencies : état des Workspace parents. | Optional: {} | |
lock LockStatus | Lock : lock de state tenu par un tiers, qui bloque les runs. | Optional: {} |
ModuleSource
ModuleSource : module OpenTofu publié en OCI au format natif (artifactType application/vnd.opentofu.modulepkg, une couche archive/zip).
| Champ | Description | Défaut | Validation |
|---|---|---|---|
source string | Source : adresse oci://<registry>/<repository>, sans tag ni digest. | Pattern: ^oci://[^?@]+$ | |
tag string | Tag de l'artefact. Absent avec digest absent = "latest". | Optional: {} | |
digest string | Digest du manifest (sha256:…), prioritaire sur tout tag. | Pattern: ^sha256:[a-f0-9]\{64\}$ Optional: {} | |
pullSecretRef LocalObjectReference | PullSecretRef : secret d'accès au registre (format dockerconfigjson) de votre tenant. Absent = accès par défaut de la plateforme, en lecture seule, au dépôt des modules partagés. | Optional: {} |
LocalRef
LocalRef : référence par nom à un objet de votre tenant.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
name string | Nom de l'objet dans votre tenant. | MinLength: 1 |
VarsFromSource
VarsFromSource : variables lues dans un secret de votre tenant ou dans les outputs d'un autre de vos Workspace (dépendance façon terragrunt). Exactement une source.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
secretRef SecretVarsRef | Secret de votre tenant et clé qui contiennent la valeur de la variable. | Optional: {} | |
workspaceOutputRef WorkspaceOutputRef | WorkspaceOutputRef : un output d'un autre de vos Workspace. Le Workspace attend que ce parent soit Ready et se relance quand ses outputs changent. | Optional: {} | |
varName string | VarName : nom de la variable. Absent = nom de la clé ou de l'output. | Pattern: ^[A-Za-z_][A-Za-z0-9_-]*$ Optional: {} | |
default string | Default : valeur utilisée tant que le parent n'a pas publié l'output (terragrunt mock_outputs). Elle ne permet qu'un plan, jamais un apply. | Optional: {} |
ImportSpec
ImportSpec : adoption d'une ressource existante par un bloc import déclaratif.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
to string | To : adresse de la ressource dans le module (ex. aws_s3_bucket.assets["logs"]). | Pattern: ^[a-zA-Z_][a-zA-Z0-9_-]*(\[[0-9]+\]|\["[^"\\$%]*"\])?(\.[a-zA-Z_][a-zA-Z0-9_-]*(\[[0-9]+\]|\["[^"\\$%]*"\])?)+$ | |
id string | ID : identifiant de la ressource chez le fournisseur. | MinLength: 1 Optional: {} | |
idFrom ImportIDSource | Identifiant lu dans un Secret ou dans l'output d'un autre Workspace, au lieu de id. | Optional: {} |
BackendSpec
BackendSpec : backend de state. Absent = state conservé par la plateforme.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
s3 S3Backend | Stockage objet propre à votre tenant, joint directement pendant l'exécution avec vos identifiants. | Optional: {} |
OutputsSpec
OutputsSpec : publication des outputs du module.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
secretName string | SecretName : secret de votre tenant, une clé par output (JSON si l'output n'est pas une chaîne). Absent = <name>-outputs. | MinLength: 1 Optional: {} |
RefreshSpec
RefreshSpec : run périodique. Absent = aucun run hors changement de spec ou de secret.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
interval Duration | Interval entre deux runs (Go duration, minimum 1m). | ||
mode RunMode | Mode du run périodique. | plan | Enum: [plan apply] Optional: {} |
Approval
Type sous-jacent : string
Approval : apply automatique ou après approbation du plan.
Règles de validation :
Enum: [auto manual]
| Valeur | Description |
|---|---|
auto | ApprovalAuto : l'apply suit le plan sans intervention. |
manual | ApprovalManual : l'apply attend l'approbation explicite du plan dont l'id figure dans status.lastPlan.id. |
DeletionPolicy
Type sous-jacent : string
DeletionPolicy : sort de l'infrastructure quand le Workspace est supprimé.
Règles de validation :
Enum: [Orphan Destroy]
| Valeur | Description |
|---|---|
Orphan | DeletionOrphan : l'infrastructure et le state restent en place. |
Destroy | DeletionDestroy : un tofu destroy est exécuté avant la suppression, qui attend sa fin. |
PlanSummary
PlanSummary : résultat du dernier plan.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
id string | ID du plan, à fournir pour l'approuver (approval: manual). | ||
at Time | Date du plan. | ||
add integer | Nombre de ressources à créer. | Optional: {} | |
change integer | Nombre de ressources à modifier. | Optional: {} | |
destroy integer | Nombre de ressources à détruire. | Optional: {} | |
import integer | Nombre de ressources à importer. | Optional: {} | |
hash string | Hash des resource_changes : l'apply approuvé est refusé s'il diffère. |
ApplySummary
ApplySummary : résultat du dernier apply.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
at Time | Date de l'apply. | ||
result string | Résultat : Succeeded, Failed, Rejected, Interrupted ou StateLocked. | Enum: [Succeeded Failed Rejected Interrupted StateLocked] | |
message string | Détail du résultat, notamment l'erreur en cas d'échec. | Optional: {} |
DependencyStatus
DependencyStatus : état d'un parent.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
name string | Nom du Workspace parent. | ||
ready boolean | Vrai quand le parent est Ready. | ||
outputsHash string | OutputsHash : empreinte du secret d'outputs du parent pris en compte. | Optional: {} |
LockStatus
LockStatus : lock de state tenu par un tiers, que la plateforme n'a pas levé (détenteur inconnu ou encore actif).
| Champ | Description | Défaut | Validation |
|---|---|---|---|
id string | Identifiant du verrou de state. | ||
who string | Qui tient le verrou. |
SecretVarsRef
SecretVarsRef : secret source de variables.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
name string | Nom du Secret de votre tenant. | MinLength: 1 | |
key string | Key : une seule clé. Absent = chaque clé du secret devient une variable. | Optional: {} |
WorkspaceOutputRef
WorkspaceOutputRef : un output publié par un autre Workspace de votre tenant.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
name string | Name du Workspace parent. | MinLength: 1 | |
output string | Output : nom de l'output du module parent. | Pattern: ^[A-Za-z_][A-Za-z0-9_-]*$ |
ImportIDSource
ImportIDSource : identifiant d'import lu hors de la spec.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
secretRef SecretKeyRef | Secret et clé qui contiennent l'identifiant à importer. | Optional: {} | |
workspaceOutputRef WorkspaceOutputRef | Output d'un autre de vos Workspace qui fournit l'identifiant à importer. | Optional: {} |
S3Backend
S3Backend : bucket de stockage objet de votre tenant (AWS ou compatible).
| Champ | Description | Défaut | Validation |
|---|---|---|---|
endpoint string | Endpoint d'un stockage objet compatible (ex. https://s3.gra.io.cloud.ovh.net). Absent = AWS. | Optional: {} | |
region string | Région du bucket. | MinLength: 1 | |
bucket string | Nom du bucket qui conserve le state. | MinLength: 1 | |
key string | Key de l'objet de state. Absent = une clé propre à votre tenant, terminée par <name>.tfstate. | Optional: {} | |
credentialsSecretRef LocalObjectReference | CredentialsSecretRef : secret aux clés AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY. | ||
lockfile boolean | Lockfile : lock natif par fichier (use_lockfile). Le bucket doit gérer les écritures conditionnelles (AWS oui, OVH Object Storage non). Sans lock, la plateforme exécute quand même les runs d'un Workspace un par un. | Optional: {} |
RunMode
Type sous-jacent : string
RunMode : ce que fait un run périodique.
Règles de validation :
Enum: [plan apply]
| Valeur | Description |
|---|---|
plan | ModePlan : plan seul, détection de dérive (condition Drifted). |
apply | ModeApply : plan puis apply. |
SecretKeyRef
SecretKeyRef : une clé d'un secret de votre tenant.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
name string | Nom du Secret de votre tenant. | MinLength: 1 | |
key string | Clé du Secret qui contient la valeur. | MinLength: 1 |
Statut et conditions
| Condition | True quand |
|---|---|
Ready | Le dernier apply a réussi et aucune entrée n'a changé depuis |
Drifted | Le dernier plan montre des changements non appliqués |
Planning / Applying | Un run est en cours |
AwaitingApproval | Un plan attend votre approbation (approval: manual) |
Failed | Le dernier run a échoué ; consecutiveFailures compte |
reason | Sens | Action |
|---|---|---|
ProviderMismatch | Le Provider cité ne correspond pas aux required_providers du module | Corriger type/source du Provider |
DependencyCycle | Boucle dans dependsOn ou workspaceOutputRef | Casser le cycle |
BlockedByDependents | Suppression en Destroy bloquée par des enfants | Supprimer les enfants d'abord |
ImportTargetMissing | L'adresse to d'un import n'existe pas dans le module | Corriger l'adresse |
PlanChangedSinceApproval | Le plan approuvé ne correspond plus à l'état réel | Réapprouver le nouveau plan |
StateLocked | Verrou tenu par un tiers | contacter le support |
SecretNotFound | Secret de varsFrom, imports ou backend absent | Créer le secret |
status.lastPlan : id, at, add, change, destroy, import, hash.
status.lastApply : at, result (Succeeded, Failed, Rejected, Interrupted,
StateLocked), message. Aussi : nextRunAt, activeJob, lastRunJob, inputsHash,
dependencies[], lock{id, who}.
Ce qui se passe à l'application et à la suppression
- Création : un run démarre dès que les parents sont
Readyet les secrets présents. - Mise à jour : tout changement d'entrée relance un run ;
suspend: trueles suspend. - Suppression : avec
Orphan, le manifeste et son state disparaissent, l'infrastructure créée reste en place ; avecDestroy, l'infrastructure est d'abord détruite, dans l'ordre inverse des dépendances.
Erreurs fréquentes
tag et digest sont exclusifs: choisir l'un des deux.- Plan qui n'avance jamais : un parent n'est pas
Ready, ou undefaultmanque pour planifier avant publication. Interrupted: le run a été arrêté proprement ; le suivant re-planifie sur le state réel, rien à faire.