Blog d'Obi Madu
Retour à tous les articles
InfrastructureAIAI Engineering

Tâches Coder, Espaces de travail et OpenCode

Espaces de travail, modèles et provisioners de Coder, et comment les tasks les transforment en environnements d'exécution éphémères pour les agents de codage IA.

Tâches Coder, Espaces de travail et OpenCode

Coder est plus facile à comprendre quand on arrête de le voir seulement comme une plateforme IDE distante. Au cœur, Coder fournit des environnements de développement reproductibles à la demande. Un utilisateur clique sur un bouton ou lance une commande CLI, et Coder provisionne un espace de travail à partir d'un modèle prédéfini. Cet espace peut tourner dans un conteneur Docker, un cluster Kubernetes, une VM cloud ou une autre cible d'infrastructure. Le développeur s'y connecte avec des outils comme VS Code, JetBrains IDEs, un terminal ou un éditeur basé navigateur.

Les tâches Coder (Coder Tasks) s'appuient sur cette même base, mais la réutilisent pour les agents de codage IA. Au lieu de créer un espace pour qu'un développeur humain l'utilise interactivement, une task crée un espace isolé et éphémère pour qu'un agent autonome y tourne. Cette distinction compte. Les tâches Coder ne sont pas une plateforme d'exécution séparée. Ce sont des espaces de travail Coder standard avec une interface orientée agents IA.

Le Modèle Coder de Base

Pour comprendre Coder, il faut trois concepts : les espaces de travail (workspaces), les modèles (templates) et les provisioners.

Un espace de travail est un environnement de développement isolé. C'est l'entité informatique avec laquelle le développeur ou l'agent IA interagit. Un modèle définit comment cet espace est construit. Les modèles Coder sont écrits en Terraform, ce qui signifie qu'ils peuvent décrire des conteneurs locaux, des pods Kubernetes, des VM cloud, des volumes persistants, des agents, des applications exposées, des métadonnées et des paramètres configurables par l'utilisateur.

Un provisioner est le processus qui exécute le code Terraform. Ce détail compte plus qu'il n'y paraît. Les fournisseurs d'infrastructure que vous spécifiez dans vos modèles tournent là où le provisioner tourne, pas à l'intérieur de l'espace nouvellement créé.

Coder server -> Provisioner runs Terraform -> Docker, Kubernetes, or cloud provider creates workspace

Si votre modèle utilise le fournisseur Docker, l'accès à Docker doit être disponible sur la machine qui tourne le provisioner. Si le provisioner lui-même est conteneurisé, ce conteneur a besoin d'un accès direct au socket Docker de l'hôte, à un hôte Docker distant, ou à la connexion Docker que vous avez configurée.

Les Modèles Sont du Terraform avec des Sources de Données Coder

Un modèle minimal déclare généralement le fournisseur Coder, un fournisseur d'infrastructure, des sources de données d'espace, un agent Coder et les ressources qui constituent l'espace.

terraform {
  required_providers {
    coder = {
      source  = "coder/coder"
      version = ">= 2.13"
    }
    docker = {
      source  = "kreuzwerker/docker"
      version = "~> 3.0"
    }
  }
}

provider "docker" {}

data "coder_provisioner" "me" {}
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}

resource "coder_agent" "main" {
  arch = data.coder_provisioner.me.arch
  os   = "linux"
}

L'agent Coder est ce qui permet au serveur Coder de se connecter dans l'espace, d'exposer les applications web en cours, d'exécuter les scripts de démarrage et de rapporter le statut. Le fournisseur d'infrastructure crée l'environnement. Avec Docker, ça veut dire conteneurs et volumes. Avec Kubernetes, pods et persistent volume claims. Avec les fournisseurs cloud, VMs et disques persistants.

Variables Terraform vs. Paramètres Coder

Un des endroits les plus faciles pour se confondre est la différence entre variables Terraform et paramètres Coder.

Les variables Terraform sont définies par l'administrateur du modèle quand le modèle est poussé sur le serveur. Elles sont utiles pour la configuration au niveau infrastructure et pour imposer des valeurs statiques que les utilisateurs ne doivent pas choisir. Les paramètres Coder, en revanche, sont montrés à l'utilisateur quand il crée un espace ou une task. Ils laissent l'utilisateur choisir des choses comme une image de conteneur, une région géographique, la taille du CPU, un modèle LLM, ou un répertoire de travail personnalisé.

ConceptDéfini parDéfini quandIdéal pour
Variable TerraformAdmin du modèlePush du modèleSecrets, valeurs par défaut, config infrastructure
Paramètre CoderUtilisateur finalCréation d'espace ou de tâcheChoix de l'utilisateur

Cet exemple montre les deux côte à côte :

variable "anthropic_api_key" {
  type      = string
  sensitive = true
}

data "coder_parameter" "container_image" {
  name         = "container_image"
  display_name = "Container Image"
  type         = "string"
  default      = "ubuntu:22.04"
  mutable      = false
}

Le bloc coder_parameter est une source de données. Pendant la création de l'espace, il récupère la valeur choisie par l'utilisateur depuis l'interface Coder.

Il y a un détail de sécurité à connaître. Marquer une variable comme sensitive = true empêche les logs Terraform et Coder d'imprimer la valeur, mais cela ne protège pas la valeur une fois qu'elle est dans un espace en cours d'exécution. Si vous injectez un secret dans un conteneur comme variable d'environnement en clair, n'importe qui avec accès shell à ce conteneur peut le lire.

Les Deux Phases de l'Exécution du Modèle

Les modèles Coder se comportent différemment pendant l'import du modèle que pendant la création de l'espace. Pendant coder templates push, Coder analyse le code Terraform, extrait les paramètres définis, construit le formulaire de l'interface, demande les valeurs pour les variables Terraform, et détecte si le modèle supporte les tâches IA.

Pendant la création de l'espace, Coder montre ce formulaire à l'utilisateur, stocke les valeurs de paramètres choisies, exécute terraform apply, et laisse les blocs data "coder_parameter" récupérer ces valeurs en cours d'exécution. Cette division est la raison pour laquelle les paramètres Coder peuvent paraître étranges au début. Ce ne sont pas des variables Terraform normales. Ce sont des valeurs gérées par Coder que Terraform ne lit que pendant la phase apply.

Les paramètres éphémères ajoutent une règle stricte. Si vous déclarez ephemeral = true, ce paramètre doit aussi être marqué comme mutable et doit avoir une valeur par défaut.

data "coder_parameter" "api_key" {
  name      = "api_key"
  type      = "string"
  mutable   = true
  ephemeral = true
  default   = ""
}

Les paramètres éphémères sont utiles quand vous voulez une valeur sensible ou temporaire fournie à la création sans la stocker dans les métadonnées à long terme de l'espace.

Ce Qu'Ajoutent les Tâches Coder

Les tâches Coder fournissent une interface simplifiée pour faire tourner des agents de codage IA dans des espaces isolés. Un utilisateur crée une task avec un prompt en langage naturel. Coder stocke le prompt. Terraform provisionne l'espace. Le modèle récupère le prompt stocké et le passe à l'intégration de l'agent dans l'environnement.

L'utilisateur soumet le prompt de la tâche
        |
        v
Coder stocke le prompt
        |
        v
Terraform provisionne l'espace
        |
        v
L'agent reçoit le prompt et tourne dans l'espace

Chaque task obtient son propre espace. Cela donne à l'agent IA un système de fichiers isolé, un ensemble propre de dépendances, un accès aux outils et un environnement d'exécution. L'espace ne nécessite généralement pas de GPUs parce que l'agent parle avec des APIs LLM externes via le réseau. Un modèle Coder devient capable de tasks quand il définit une ressource coder_ai_task.

resource "coder_ai_task" "task" {
  app_id = module.opencode.task_app_id
}

Le prompt de la task stocké peut être récupéré via la source de données data "coder_task".

data "coder_task" "me" {}

module "opencode" {
  ai_prompt = data.coder_task.me.prompt
}

Du point de vue de l'utilisateur final, démarrer une task peut être aussi simple que cette commande :

coder tasks create \
  --template my-template \
  --parameter container_image="python:3.12" \
  "Refactor the authentication module"

La partie clé est que le prompt de la task devient une entrée d'infrastructure. L'espace est créé autour du travail que l'agent doit accomplir.

Où OpenCode s'Intègre

Le module OpenCode Coder intègre OpenCode dans un espace Coder. Il peut exposer OpenCode comme une application interactive, le tourner en mode tâche en arrière-plan, passer des prompts et configurer l'authentification ou les paramètres de modèle.

Une configuration simple du module ressemble à ça :

module "opencode" {
  source   = "registry.coder.com/coder-labs/opencode/coder"
  version  = "0.1.1"
  agent_id = coder_agent.main.id
  workdir  = "/home/coder/project"
}

Pour l'usage avec tasks, il se connecte à data.coder_task.me.prompt et à la ressource coder_ai_task.

data "coder_task" "me" {}

resource "coder_ai_task" "task" {
  app_id = module.opencode.task_app_id
}

module "opencode" {
  source           = "registry.coder.com/coder-labs/opencode/coder"
  version          = "0.1.1"
  agent_id         = coder_agent.main.id
  workdir          = "/home/coder/project"
  ai_prompt        = data.coder_task.me.prompt
  auth_json        = data.coder_parameter.opencode_auth_json.value
  config_json      = data.coder_parameter.opencode_config_json.value
  opencode_version = "latest"
}

Le module supporte aussi un mode CLI seul si vous voulez OpenCode dans le terminal de l'espace sans l'interface web ni le reporting de tâches.

module "opencode" {
  source       = "registry.coder.com/coder-labs/opencode/coder"
  version      = "0.1.1"
  agent_id     = coder_agent.main.id
  workdir      = "/home/coder"
  report_tasks = false
  cli_app      = true
}

La conclusion : Coder fournit l'espace et gère son cycle de vie, tandis qu'OpenCode fournit l'expérience agent à l'intérieur de cet espace.

Pièges du Fournisseur Docker

Beaucoup de configurations Coder locales s'appuient sur Docker, donc le fournisseur Docker de Terraform devient une grande partie de la logique du modèle. Par défaut, ce fournisseur parle au socket Unix local.

provider "docker" {
  host = "unix:///var/run/docker.sock"
}

Il peut aussi être configuré pour se connecter à un hôte distant via SSH.

provider "docker" {
  host     = "ssh://user@remote-host:22"
  ssh_opts = ["-o", "StrictHostKeyChecking=no"]
}

Le détail critique est que les clés SSH et l'accès Docker doivent exister là où le provisioner tourne. Si le provisioner tourne dans un conteneur, monter votre clé SSH sur votre laptop ne suffit pas. Le conteneur du provisioner a besoin d'un accès monté à elle.

Les permissions du socket Docker sont un autre problème courant. Si Coder tourne dans une sandbox Docker mais a besoin de créer des conteneurs frères via le socket Docker de l'hôte, le conteneur Coder a besoin d'accéder à /var/run/docker.sock avec les permissions de groupe correctes.

services:
  coder:
    image: ghcr.io/coder/coder:latest
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    group_add:
      - "998"

L'ID de groupe doit correspondre au groupe Docker sur la machine hôte.

Le réseau peut aussi surprendre. Si un conteneur d'espace doit atteindre le serveur Coder qui est bindé à localhost sur l'hôte, résoudre localhost depuis l'intérieur du conteneur pointe vers le conteneur lui-même. Un fix courant est d'utiliser host.docker.internal avec un mappage manuel de host gateway.

Images de Base et Cycle de Vie de l'Espace

Les images de base fournies par Coder existent pour une raison. Elles incluent un utilisateur coder préconfiguré, le comportement attendu du répertoire home, les dépendances de l'agent, les fichiers skeleton et les outils de développement courants.

Utiliser une image nue comme ubuntu:latest peut fonctionner, mais ça signifie que vous gérez plus de setup. Vous devez créer l'utilisateur, installer les outils, configurer le répertoire home, et vous assurer que l'agent Coder démarre correctement.

Le cycle de vie de l'espace compte aussi. Certaines ressources ne doivent exister que lorsque l'espace est démarré. Coder expose une métrique start_count, que les modèles associent au méta-argument count de Terraform.

resource "docker_container" "workspace" {
  count = data.coder_workspace.me.start_count
}

module "opencode" {
  count = data.coder_workspace.me.start_count
}

Les volumes persistants sont une préoccupation séparée. Si vous voulez que le répertoire home d'un utilisateur ou les données de l'espace survivent aux arrêts et reconstructions, protégez le volume.

resource "docker_volume" "home" {
  name = "coder-${data.coder_workspace.me.id}-home"

  lifecycle {
    ignore_changes = all
  }
}

Pour Résumer

Coder est un plan de contrôle pour gérer des environnements de développement reproductibles. Terraform est le langage qui décrit ces environnements. Les provisioners exécutent le code Terraform. Les espaces sont les VMs, conteneurs ou pods qui en résultent. Les tasks sont des espaces spécialisés créés autour de prompts d'agents IA.

OpenCode s'intègre dans ce modèle comme un outil qui tourne dans l'espace. Ce n'est pas la couche d'infrastructure elle-même ; c'est la couche agent par-dessus. Une fois que cette séparation est claire, les parties confuses se déboguent plus facilement.

Si une ressource Docker échoue, regardez le provisioner et l'hôte Docker. S'il manque un paramètre utilisateur, tracez le flux des paramètres Coder. Si un prompt de task n'atteint pas l'agent, vérifiez data "coder_task" et le câblage du module. Si un secret apparaît dans un conteneur en cours d'exécution, rappelez-vous que le concept de sensibilité de Terraform n'équivaut pas au secret à l'exécution.

Les tâches Coder sont puissantes parce qu'elles combinent une infrastructure reproductible avec une exécution isolée de l'agent. Le coût de cette puissance est qu'il faut comprendre les deux moitiés : le modèle de provisionnement Coder/Terraform et l'intégration de l'agent qui tourne dans l'espace.

Références