Aller au contenu principal

Workspace

À venir

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.

apiVersiontofu.stackngo.io/v1alpha1
kindWorkspace
Appliqué parsng apply (à venir)
Commandes liéessng 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.tag et module.digest sont exclusifs ; digest suit ^sha256:[a-f0-9]{64}$.
  • Dans varsFrom, exactement une source : secretRef ou workspaceOutputRef ; varName exige secretRef.key ; default n'existe qu'avec workspaceOutputRef.
  • Dans imports, exactement un identifiant : id ou idFrom.
  • refresh.interval vaut au moins 1m.

Workspace​

Workspace applique un module OpenTofu publié en OCI, dans des exécutions propres à votre tenant.

ChampDescriptionDéfautValidation
apiVersion stringtofu.stackngo.io/v1alpha1
kind stringWorkspace
metadata ObjectMetaSeul metadata.name est à renseigner (nom de la ressource dans votre tenant).
spec WorkspaceSpec
status WorkspaceStatus

WorkspaceSpec​

WorkspaceSpec : module OCI à appliquer et ses entrées.

ChampDescriptionDéfautValidation
module ModuleSourceModule OpenTofu à appliquer : adresse OCI, version (tag) ou empreinte (digest).
providers LocalRef arrayProviders : Provider de votre tenant câblés dans le run (bloc provider généré).Optional: {}
dependsOn LocalRef arrayDependsOn : Workspace de votre tenant qui doivent être Ready avant tout run (ordre seul).Optional: {}
vars JSONVars : valeurs JSON libres, écrites dans terraform.tfvars.json.Type: object
Optional: {}
varsFrom VarsFromSource arrayVarsFrom : variables secrètes, injectées en TF_VAR_<nom>. Prioritaires sur Vars.Optional: {}
imports ImportSpec arrayImports : ressources existantes adoptées par des blocs import (no-op une fois dans le state).Optional: {}
backend BackendSpecOù conserver le state. Absent : la plateforme le conserve pour vous.Optional: {}
outputs OutputsSpecOù publier les outputs du module.Optional: {}
refresh RefreshSpecExécution périodique pour détecter la dérive. Absent : aucun run hors changement de manifeste ou de secret.Optional: {}
approval Approvalauto (défaut) applique le plan sans intervention ; manual attend votre approbation du plan.autoEnum: [auto manual]
Optional: {}
deletionPolicy DeletionPolicySort de l'infrastructure à la suppression du Workspace : Orphan (défaut) la laisse en place, Destroy la détruit d'abord.OrphanEnum: [Orphan Destroy]
Optional: {}
suspend booleanSuspend : aucun nouveau run tant que vrai.Optional: {}
resources ResourceRequirementsResources : ressources du conteneur tofu. Absent = valeurs par défaut de la plateforme.Optional: {}

WorkspaceStatus​

WorkspaceStatus : état observé.

ChampDescriptionDéfautValidation
observedGeneration integerDernière version du manifeste prise en compte par la plateforme.Optional: {}
conditions Condition arrayConditions : Ready, Drifted, Planning, Applying, AwaitingApproval, Failed.Optional: {}
lastPlan PlanSummaryRésumé du dernier plan : identifiant, date et nombre de changements.Optional: {}
lastApply ApplySummaryRésumé du dernier apply : date, résultat et message.Optional: {}
activeJob stringActiveJob : exécution en cours (une seule à la fois par Workspace).Optional: {}
nextRunAt TimeNextRunAt : prochain run périodique.Optional: {}
inputsHash stringInputsHash : empreinte des entrées (spec, secrets, Providers, outputs des parents)
du dernier run réussi.
Optional: {}
lastRunJob stringLastRunJob : dernière exécution dont le résultat a été pris en compte.Optional: {}
lastRunAt TimeLastRunAt : fin du dernier run.Optional: {}
consecutiveFailures integerConsecutiveFailures : échecs consécutifs (backoff des reprises), remis à zéro par un succès.Optional: {}
dependencies DependencyStatus arrayDependencies : état des Workspace parents.Optional: {}
lock LockStatusLock : 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).

ChampDescriptionDéfautValidation
source stringSource : adresse oci://<registry>/<repository>, sans tag ni digest.Pattern: ^oci://[^?@]+$
tag stringTag de l'artefact. Absent avec digest absent = "latest".Optional: {}
digest stringDigest du manifest (sha256:…), prioritaire sur tout tag.Pattern: ^sha256:[a-f0-9]\{64\}$
Optional: {}
pullSecretRef LocalObjectReferencePullSecretRef : 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.

ChampDescriptionDéfautValidation
name stringNom 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.

ChampDescriptionDéfautValidation
secretRef SecretVarsRefSecret de votre tenant et clé qui contiennent la valeur de la variable.Optional: {}
workspaceOutputRef WorkspaceOutputRefWorkspaceOutputRef : 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 stringVarName : nom de la variable. Absent = nom de la clé ou de l'output.Pattern: ^[A-Za-z_][A-Za-z0-9_-]*$
Optional: {}
default stringDefault : 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.

ChampDescriptionDéfautValidation
to stringTo : 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 stringID : identifiant de la ressource chez le fournisseur.MinLength: 1
Optional: {}
idFrom ImportIDSourceIdentifiant 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.

ChampDescriptionDéfautValidation
s3 S3BackendStockage objet propre à votre tenant, joint directement pendant l'exécution avec vos identifiants.Optional: {}

OutputsSpec​

OutputsSpec : publication des outputs du module.

ChampDescriptionDéfautValidation
secretName stringSecretName : 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.

ChampDescriptionDéfautValidation
interval DurationInterval entre deux runs (Go duration, minimum 1m).
mode RunModeMode du run périodique.planEnum: [plan apply]
Optional: {}

Approval​

Type sous-jacent : string

Approval : apply automatique ou après approbation du plan.

Règles de validation :

  • Enum: [auto manual]
ValeurDescription
autoApprovalAuto : l'apply suit le plan sans intervention.
manualApprovalManual : 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]
ValeurDescription
OrphanDeletionOrphan : l'infrastructure et le state restent en place.
DestroyDeletionDestroy : un tofu destroy est exécuté avant la suppression, qui attend sa fin.

PlanSummary​

PlanSummary : résultat du dernier plan.

ChampDescriptionDéfautValidation
id stringID du plan, à fournir pour l'approuver (approval: manual).
at TimeDate du plan.
add integerNombre de ressources à créer.Optional: {}
change integerNombre de ressources à modifier.Optional: {}
destroy integerNombre de ressources à détruire.Optional: {}
import integerNombre de ressources à importer.Optional: {}
hash stringHash des resource_changes : l'apply approuvé est refusé s'il diffère.

ApplySummary​

ApplySummary : résultat du dernier apply.

ChampDescriptionDéfautValidation
at TimeDate de l'apply.
result stringRésultat : Succeeded, Failed, Rejected, Interrupted ou StateLocked.Enum: [Succeeded Failed Rejected Interrupted StateLocked]
message stringDétail du résultat, notamment l'erreur en cas d'échec.Optional: {}

DependencyStatus​

DependencyStatus : état d'un parent.

ChampDescriptionDéfautValidation
name stringNom du Workspace parent.
ready booleanVrai quand le parent est Ready.
outputsHash stringOutputsHash : 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).

ChampDescriptionDéfautValidation
id stringIdentifiant du verrou de state.
who stringQui tient le verrou.

SecretVarsRef​

SecretVarsRef : secret source de variables.

ChampDescriptionDéfautValidation
name stringNom du Secret de votre tenant.MinLength: 1
key stringKey : une seule clé. Absent = chaque clé du secret devient une variable.Optional: {}

WorkspaceOutputRef​

WorkspaceOutputRef : un output publié par un autre Workspace de votre tenant.

ChampDescriptionDéfautValidation
name stringName du Workspace parent.MinLength: 1
output stringOutput : 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.

ChampDescriptionDéfautValidation
secretRef SecretKeyRefSecret et clé qui contiennent l'identifiant à importer.Optional: {}
workspaceOutputRef WorkspaceOutputRefOutput d'un autre de vos Workspace qui fournit l'identifiant à importer.Optional: {}

S3Backend​

S3Backend : bucket de stockage objet de votre tenant (AWS ou compatible).

ChampDescriptionDéfautValidation
endpoint stringEndpoint d'un stockage objet compatible (ex. https://s3.gra.io.cloud.ovh.net). Absent = AWS.Optional: {}
region stringRégion du bucket.MinLength: 1
bucket stringNom du bucket qui conserve le state.MinLength: 1
key stringKey de l'objet de state. Absent = une clé propre à votre tenant, terminée par <name>.tfstate.Optional: {}
credentialsSecretRef LocalObjectReferenceCredentialsSecretRef : secret aux clés AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY.
lockfile booleanLockfile : 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]
ValeurDescription
planModePlan : plan seul, détection de dérive (condition Drifted).
applyModeApply : plan puis apply.

SecretKeyRef​

SecretKeyRef : une clé d'un secret de votre tenant.

ChampDescriptionDéfautValidation
name stringNom du Secret de votre tenant.MinLength: 1
key stringClé du Secret qui contient la valeur.MinLength: 1

Statut et conditions​

ConditionTrue quand
ReadyLe dernier apply a réussi et aucune entrée n'a changé depuis
DriftedLe dernier plan montre des changements non appliqués
Planning / ApplyingUn run est en cours
AwaitingApprovalUn plan attend votre approbation (approval: manual)
FailedLe dernier run a échoué ; consecutiveFailures compte
reasonSensAction
ProviderMismatchLe Provider cité ne correspond pas aux required_providers du moduleCorriger type/source du Provider
DependencyCycleBoucle dans dependsOn ou workspaceOutputRefCasser le cycle
BlockedByDependentsSuppression en Destroy bloquée par des enfantsSupprimer les enfants d'abord
ImportTargetMissingL'adresse to d'un import n'existe pas dans le moduleCorriger l'adresse
PlanChangedSinceApprovalLe plan approuvé ne correspond plus à l'état réelRéapprouver le nouveau plan
StateLockedVerrou tenu par un tierscontacter le support
SecretNotFoundSecret de varsFrom, imports ou backend absentCré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 Ready et les secrets présents.
  • Mise à jour : tout changement d'entrée relance un run ; suspend: true les suspend.
  • Suppression : avec Orphan, le manifeste et son state disparaissent, l'infrastructure créée reste en place ; avec Destroy, 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 un default manque pour planifier avant publication.
  • Interrupted : le run a été arrêté proprement ; le suivant re-planifie sur le state réel, rien à faire.

Voir aussi​