Serveur MCP Terraform : installation, outils et sécurité
En bref : le serveur MCP Terraform est le serveur Model Context Protocol officiel de HashiCorp. Il permet à un assistant IA (Claude Code, Copilot dans VS Code, Cursor, etc.) de consulter la documentation à jour des providers, des modules et des politiques du Terraform Registry. Avec un jeton, il peut aussi travailler avec les workspaces et les runs de HCP Terraform ou Terraform Enterprise. Il n'exécute pas votre CLI terraform locale et ne lit pas votre état local. Lancez-le avec Docker (hashicorp/terraform-mcp-server:1.4.1), commencez sans jeton, et n'activez ENABLE_TF_OPERATIONS que si une validation humaine fiable existe.
Le défaut le plus courant des assistants IA avec Terraform n'a rien de spectaculaire. Il est banal : ils écrivent des arguments de provider renommés deux versions majeures plus tôt, ou inventent des variables de module qui n'ont jamais existé. Un serveur MCP règle une bonne partie du problème en laissant le modèle chercher l'information au lieu de s'en souvenir. Il ouvre aussi une porte vers votre infrastructure : ce guide consacre donc autant de place aux permissions qu'à l'installation. Nous avons lancé la version 1.4.1 en local le 24 octobre 2026, et les listes d'outils et sorties ci-dessous viennent de cette session.
Dernière vérification : 24 octobre 2026 (terraform-mcp-server v1.4.1, publiée le 23 octobre 2026). Le projet publie souvent : consultez le changelog avant de copier une configuration.
Qu'est-ce que le serveur MCP Terraform ?
C'est un programme open source (licence MPL-2.0) de HashiCorp qui parle le Model Context Protocol et expose les API du Terraform Registry et de HCP Terraform sous forme d'« outils » qu'un assistant IA peut appeler. MCP est un protocole ouvert qui relie des applications d'IA à des outils et des données externes. L'assistant (le client MCP) découvre les outils proposés par un serveur, puis les appelle avec des arguments structurés et reçoit des résultats structurés.
Concrètement, quand vous demandez « comment activer le versioning d'un bucket S3 avec le provider AWS ? », l'assistant peut appeler search_provider_docs puis get_provider_details et répondre à partir de la documentation de la version actuelle du provider, plutôt que de données d'entraînement qui ont peut-être un an.
Le projet a beaucoup avancé en 2026 : la v1.0.0 est sortie le 9 juin 2026, puis les v1.4.0 et v1.4.1 le même jour, le 23 octobre 2026. Il fonctionne en stdio (le client le lance comme processus local) ou en HTTP streamable (un serveur partagé pour une équipe).
Avec quoi communique-t-il, et que ne touche-t-il pas ?
Il parle à deux API : le Terraform Registry public (sans identifiants) et, avec un TFE_TOKEN, l'API de HCP Terraform ou de Terraform Enterprise. Il ne lance jamais terraform plan sur votre machine et ne voit jamais vos fichiers d'état locaux. C'est le point le plus mal compris, d'où ce schéma :
Deux conséquences :
- Le mode registry seul est peu risqué. Sans jeton, le serveur ne peut que lire de la documentation publique. Il ne peut rien modifier, nulle part.
- Avec un jeton, le risque est celui du jeton. Chaque action sur un workspace, une variable ou un run passe par l'API de HCP Terraform avec les permissions de ce jeton. Si le jeton peut appliquer des runs en production, l'assistant aussi.
Votre flux Terraform local est une autre question. Un agent comme Claude Code peut exécuter des commandes shell, y compris terraform apply, si vous l'y autorisez. Le serveur MCP n'ajoute pas cette capacité, et ne l'empêche pas non plus. Nous y revenons dans la partie sécurité, car c'est là que se sont produits les incidents connus.
Quels outils expose-t-il ?
Sans jeton, vous obtenez 9 outils du registry, en lecture seule. Avec un TFE_TOKEN valide s'ajoutent les outils du registry privé et un vaste ensemble terraform pour les organisations, projets, équipes, workspaces, runs, variables, versions d'état, policy sets et Stacks. Voici la réponse à tools/list lors de notre test sans jeton :
| Toolset | Exemples d'outils | Prérequis |
|---|---|---|
registry |
search_provider_docs, get_provider_details, get_provider_capabilities, get_latest_provider_version, search_modules, get_module_details, get_latest_module_version, search_policies, get_policy_details |
Aucun |
registry-private |
search_private_modules, get_private_module_details, search_private_providers, get_private_provider_details |
TFE_TOKEN |
terraform (lecture) |
whoami, get_token_permissions, list_terraform_orgs, list_workspaces, get_workspace_details, list_runs, get_run_details, get_plan_logs, get_plan_json_output, list_state_versions |
TFE_TOKEN |
terraform (écriture) |
create_workspace, update_workspace, create_run, create_workspace_variable, create_variable_set, attach_variable_set_to_workspaces, create_team, grant_team_access |
TFE_TOKEN |
terraform (destructif) |
action_run (apply, discard, cancel), delete_workspace_safely, force_unlock_workspace, delete_project, delete_team, create_run avec auto_approve ou is_destroy |
TFE_TOKEN et ENABLE_TF_OPERATIONS=true |
Trois détails relevés en comparant la documentation au serveur réel :
- Les outils du registry portent des annotations MCP comme
readOnlyHint: trueetdestructiveHint: false. Certains clients s'en servent pour décider quand demander une confirmation. - La page de référence de HashiCorp nomme l'outil de recherche
search_providers, mais la v1.4.1 l'enregistre sous le nomsearch_provider_docs. C'est important si vous filtrez les outils par nom avec--tools: prenez les noms renvoyés partools/list, pas ceux d'une page de documentation. - Le serveur propose aussi des ressources MCP : le guide de style Terraform (
/terraform/style-guide) et un guide de développement de modules (/terraform/module-development). Indiquer le guide de style à l'assistant est un moyen simple d'obtenir un formatage et un nommage cohérents.
Un appel réel, pour mémoire : get_latest_provider_version avec namespace=hashicorp, name=aws a renvoyé 6.70.0 le 24 octobre 2026. Tout l'intérêt du serveur tient dans cette valeur : un modèle entraîné il y a quelques mois ne la connaît pas.
Comment l'installer et le lancer ?
Le plus simple est Docker : docker run -i --rm hashicorp/terraform-mcp-server:1.4.1. C'est le client MCP qui lance cette commande, vous n'avez normalement pas à le faire à la main. Épinglez une version plutôt que latest, pour qu'une mise à jour ne change jamais vos outils à votre insu.
docker pull hashicorp/terraform-mcp-server:1.4.1
Si vous préférez un binaire natif (pas de Docker sur le poste), installez-le avec Go ou téléchargez un binaire publié :
go install github.com/hashicorp/terraform-mcp-server/cmd/terraform-mcp-server@v1.4.1
terraform-mcp-server stdio --toolsets=registry
Pour vérifier que le serveur fonctionne avant de brancher un client IA, envoyez-lui vous-même la poignée de main MCP. C'est ainsi que nous avons produit la capture ci-dessus :
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| docker run -i --rm hashicorp/terraform-mcp-server:1.4.1
Le serveur répond à chaque requête par une ligne JSON. Sans jeton, son journal sur stderr indique Session has no valid TFE client - TFE tools will not be available. C'est exactement ce que l'on veut pour un premier test.
Comment le brancher à Claude Code, VS Code ou Cursor ?
Chaque client a besoin de la même chose : une commande de démarrage (docker run -i --rm ...) ou l'URL d'un serveur partagé. Seul le format de configuration change.
Claude Code
# registry seul, disponible dans tous vos projets
claude mcp add terraform -s user -t stdio -- \
docker run -i --rm hashicorp/terraform-mcp-server:1.4.1
claude mcp list # vérifier la connexion
Le -- sépare les options de Claude Code de la commande qui lance le serveur. Dans une session, /mcp affiche l'état des serveurs. Pour partager la configuration avec l'équipe, utilisez --scope project : cela écrit un .mcp.json à la racine du projet, que vous pouvez commiter. N'y mettez jamais de jeton.
Pour fournir un jeton HCP Terraform sans l'écrire dans les arguments de docker, passez-le par l'environnement :
claude mcp add --transport stdio --env TFE_TOKEN="$TFE_TOKEN" terraform-hcp -- \
docker run -i --rm -e TFE_TOKEN hashicorp/terraform-mcp-server:1.4.1
-e TFE_TOKEN sans valeur demande à Docker de recopier la variable depuis l'environnement dans lequel Claude Code le lance. Sachez que claude mcp add --env enregistre la valeur dans le fichier de configuration de Claude Code, sur le disque. Utilisez un jeton à durée courte et à faibles privilèges (voir plus bas), pas votre jeton personnel d'administrateur.
VS Code (mode agent)
Créez .vscode/mcp.json dans le workspace. VS Code demande le jeton au démarrage et ne l'enregistre pas dans le fichier :
{
"servers": {
"terraform": {
"command": "docker",
"args": ["run", "-i", "--rm",
"-e", "TFE_TOKEN=${input:tfe_token}",
"hashicorp/terraform-mcp-server:1.4.1"]
}
},
"inputs": [
{"type": "promptString", "id": "tfe_token",
"description": "Jeton API HCP Terraform", "password": true}
]
}
Pour un usage registry seul, supprimez la ligne -e et le bloc inputs.
Cursor
Ajoutez le serveur dans ~/.cursor/mcp.json, ou via Settings → Cursor Settings → MCP :
{
"mcpServers": {
"terraform": {
"command": "docker",
"args": ["run", "-i", "--rm", "hashicorp/terraform-mcp-server:1.4.1"]
}
}
}
Le README fournit aussi des exemples prêts à l'emploi pour Claude Desktop, Amazon Q Developer, Kiro, Codex CLI et Gemini. Ils suivent tous le même principe.
Comment le connecter à HCP Terraform ou Terraform Enterprise ?
Définissez TFE_TOKEN (et TFE_ADDRESS pour Terraform Enterprise, par exemple https://tfe.example.com). Le serveur enregistre alors les toolsets du registry privé et terraform. L'adresse par défaut est https://app.terraform.io.
Le choix du jeton est la vraie décision de sécurité :
- Un jeton d'équipe, pour une équipe qui a un accès en lecture aux workspaces que l'assistant doit voir. Cela suffit pour des questions du type « explique-moi ce plan en échec » ou « qu'est-ce qui a changé au dernier run ».
- Un jeton d'équipe avec l'accès « plan » si vous voulez que l'assistant lance des runs spéculatifs ou plan-only.
- Évitez les jetons utilisateur personnels et les jetons d'organisation. Un jeton utilisateur porte toutes vos permissions, dans toutes vos organisations. Un jeton d'organisation agit au niveau de l'organisation : il sert à automatiser l'organisation elle-même, pas à un assistant au quotidien.
Une fois connecté, demandez d'abord à l'assistant d'appeler whoami puis get_token_permissions. C'est un contrôle rapide et honnête de ce qu'il peut réellement faire.
create_run avec le type par défaut plan_and_apply est disponible sans ENABLE_TF_OPERATIONS. HCP Terraform attend quand même une confirmation avant d'appliquer, sauf si le workspace a l'auto-apply activé. Dans ce cas, le plan s'applique tout seul. Vérifiez l'auto-apply sur chaque workspace sur lequel le jeton peut écrire.
Que fait ENABLE_TF_OPERATIONS ?
Cette variable débloque les outils destructifs : appliquer, annuler ou rejeter des runs (action_run), supprimer workspaces, projets et équipes, forcer le déverrouillage d'un workspace, et créer des runs avec auto_approve ou is_destroy. Elle vaut false par défaut, et la documentation de HashiCorp avertit que ces outils « peuvent modifier ou détruire définitivement des ressources d'infrastructure ».
Notre recommandation est simple : laissez ENABLE_TF_OPERATIONS désactivé sur les postes de développement. Si vous voulez un flux d'apply assisté par IA, construisez-le autour de l'étape d'approbation de HCP Terraform (les runs attendent la confirmation d'un humain), de politiques Sentinel ou OPA, et d'un jeton limité aux workspaces hors production. Notez que la variable ne protège pas tout ce qui change un comportement. update_workspace, les outils de variables et grant_team_access fonctionnent sans elle : la portée du jeton reste votre principal contrôle.
Peut-on laisser un agent IA lancer terraform apply ?
C'est possible, mais il ne faut pas le faire en production sans qu'un humain relise le plan. Les incidents publics de 2026 ne venaient pas de bugs de MCP : un agent avait un accès shell, de vrais identifiants et le mauvais fichier d'état. L'un d'eux est bien documenté par l'ingénieur concerné. En février 2026, un agent de développement IA qui travaillait sur une configuration Terraform a décompressé une ancienne archive et remplacé le fichier d'état courant par une version plus ancienne qui décrivait la production. Il a ensuite lancé terraform destroy. Le VPC de production, la base RDS, le cluster ECS, les load balancers et les snapshots RDS automatiques ont été supprimés. Le support AWS a restauré la base à partir d'un snapshot environ 24 heures plus tard.
Les mesures adoptées ensuite par l'auteur valent d'être copiées, quels que soient vos outils :
- Les agents ne lancent plus de commandes Terraform. Un humain exécute et relit chaque plan et chaque action destructrice.
- Un état distant (S3) au lieu d'un fichier d'état sur un seul portable.
- La protection contre la suppression dans Terraform et dans AWS, et des sauvegardes qui vivent hors du cycle de vie de Terraform.
- Un test de restauration chaque nuit, pour que « nous avons des sauvegardes » soit un fait et pas un espoir.
Dans Claude Code, vous pouvez imposer le premier point avec des règles de permission qui refusent les commandes dangereuses, par exemple dans .claude/settings.json :
{
"permissions": {
"deny": [
"Bash(terraform apply *)",
"Bash(terraform destroy *)",
"Bash(terraform state *)",
"Bash(terraform import *)"
]
}
}
Les règles de refus comparent la commande telle qu'elle est écrite : terraform -chdir=prod apply ou un script intermédiaire passent au travers. Voyez-les comme une ceinture de sécurité, pas comme un bac à sable : la vraie frontière, ce sont les identifiants auxquels l'agent a accès. Combinez ces règles avec le serveur MCP en mode registry seul, et l'assistant reste très utile (écrire et relire du HCL à partir de la documentation à jour) sans pouvoir modifier l'infrastructure. Le même principe vaut pour Kubernetes : dans notre guide de migration d'ingress-nginx vers Gateway API, l'assistant relit les HTTPRoute générées mais ne les applique jamais. Et prenez un snapshot des serveurs avant tout changement automatisé, comme expliqué dans notre guide de mise à jour vers Ubuntu 26.04.
Comment faire tourner un serveur partagé pour une équipe ?
Lancez-le en mode streamable-http derrière TLS. Chaque utilisateur envoie son propre jeton dans l'en-tête Authorization, et vous restreignez l'accès avec une liste d'organisations autorisées et des origines CORS. L'exemple centralisé de HashiCorp ressemble à ceci (nous n'avons raccourci que les chemins) :
docker run -p 8080:8080 \
-e TRANSPORT_MODE=streamable-http \
-e TRANSPORT_HOST=0.0.0.0 \
-e TFE_ADDRESS=https://tfe.example.com \
-e MCP_TLS_CERT_FILE=/certs/server.pem \
-e MCP_TLS_KEY_FILE=/certs/server-key.pem \
-e MCP_ORGANIZATION_ALLOWLIST=acme \
-e MCP_ALLOWED_ORIGINS=https://ide.example.com \
-v /etc/mcp/certs:/certs:ro \
hashicorp/terraform-mcp-server:1.4.1
claude mcp add --transport http terraform https://mcp.example.com:8080/mcp
Ce qui compte en production, d'après la documentation :
- Le serveur écoute par défaut sur
127.0.0.1. TLS est obligatoire pour un déploiement accessible au-delà de localhost. - Les jetons doivent passer par les en-têtes (
Authorization: Bearer ...ouTFE_TOKEN). Une requête avec un jeton dans l'URL est rejetée avec une erreur HTTP 400. - Les clients ne peuvent pas modifier
TFE_ADDRESS: personne ne peut rediriger vos jetons vers un autre serveur. - Les limites de débit par défaut sont de 10 requêtes/s au global (rafale de 20) et 5/s par session (rafale de 10). Un point de terminaison
/healthexiste, et les métriques OpenTelemetry sont optionnelles. - Derrière un proxy, gardez
MCP_REMOTE_IP_METHOD=RemoteAddr, sauf si votre propre proxy définitX-Forwarded-For. Dans ce cas, réglezMCP_XFF_TRUSTED_HOPSsur le nombre exact de proxys.
Quels prompts et quels usages fonctionnent bien ?
Servez-vous-en là où des faits à jour comptent : mises à jour de providers, choix de modules, explication de plans, recherche de politiques. Des demandes comme celles-ci poussent l'assistant à appeler un outil au lieu de deviner :
- « Vérifie la dernière version du provider
hashicorp/awset liste les changements cassants de son guide de mise à jour qui touchentaws_s3_bucket. » - « Cherche des modules vérifiés pour un VPC AWS, compare les deux premiers selon leurs entrées et sorties, et recommande-en un pour trois sous-réseaux privés. »
- « Récupère le JSON du plan du dernier run du workspace
network-staginget explique chaque ressource qui sera remplacée, pas seulement modifiée. » - « Quelles politiques Sentinel existent pour le CIS sur AWS ? Montre le détail de l'une d'elles sur le chiffrement S3. »
- « Réécris ce module selon la ressource du guide de style Terraform. »
Demandez les sources dans la réponse (nom de l'outil et identifiant du document). Si l'assistant répond sans appeler d'outil, il devine.
Quelles sont les limites et les risques ?
Il améliore l'exactitude, pas le jugement. Le contenu du registry peut être faux ou malveillant, les résultats varient selon le modèle et le client, et tout ce qui dispose d'un jeton est une intégration à privilèges. En détail :
- Injection de prompt par le contenu. Les README de modules et la documentation sont des textes tiers qui arrivent directement dans le contexte du modèle. Traitez la sortie des outils comme n'importe quelle donnée non fiable, et gardez un humain entre « le modèle a lu un README » et « le modèle a modifié l'infrastructure ». La note de sécurité du README le dit : « Do not use the MCP server with untrusted MCP clients or LLMs » (n'utilisez pas le serveur MCP avec des clients MCP ou des LLM non fiables).
- Taille du contexte. Les pages de documentation des providers sont longues. Demander « tout sur le provider AWS » remplit la fenêtre de contexte et dégrade les réponses. Posez des questions précises.
- Aucune vision locale. Le serveur ne voit ni vos fichiers
.tfni votre état local. C'est l'assistant qui les lit (si le client le permet), et il peut confondre vos contraintes de version avec « la dernière version ». - Limites de débit du Registry public et du mode HTTP, qui peuvent ralentir les longues sessions d'agent.
- Des résultats variables. HashiCorp le dit elle-même : les résultats « sont générés dynamiquement et peuvent varier selon la requête, le modèle et le client MCP connecté ». Relisez tout avant que cela n'arrive dans une pull request.
FAQ
Le serveur MCP Terraform est-il gratuit ?
Oui. Il est open source sous licence Mozilla Public License 2.0 et l'image Docker est publique. L'utilisation de HCP Terraform ou de Terraform Enterprise est facturée séparément, selon votre propre offre.
Fonctionne-t-il sans Docker ?
Oui. Installez le binaire avec go install github.com/hashicorp/terraform-mcp-server/cmd/terraform-mcp-server@v1.4.1 ou téléchargez une version publiée, puis indiquez terraform-mcp-server stdio à votre client.
Faut-il un compte HCP Terraform ?
Non. Sans jeton, il sert les outils du Terraform Registry public (providers, modules, politiques). Le jeton n'est nécessaire que pour les registries privés et la gestion des workspaces ou des runs.
Peut-il lancer terraform plan sur mon code local ?
Non. Il n'exécute pas la CLI Terraform. Il peut créer des runs dans des workspaces HCP Terraform ou Terraform Enterprise via leur API, si le jeton le permet.
Est-il sûr ?
En mode registry seul, le risque est faible, car il ne lit que de la documentation publique. Avec un jeton, il est aussi puissant que ce jeton. Utilisez un jeton d'équipe en lecture seule, laissez ENABLE_TF_OPERATIONS désactivé et l'auto-apply coupé sur les workspaces accessibles.
Comment limiter les outils visibles par l'assistant ?
Lancez le serveur avec --toolsets=registry (ou registry,registry-private), ou autorisez des outils précis avec --tools=search_provider_docs,get_provider_details. Les deux options ne peuvent pas être combinées.
Quels clients MCP sont pris en charge ?
Tout client qui implémente MCP en stdio ou en HTTP streamable. Le README donne des exemples pour VS Code, Cursor, Claude Desktop, Claude Code, Amazon Q Developer, Kiro, Codex CLI, Gemini et IBM Bob.
Sources
- GitHub : hashicorp/terraform-mcp-server (README, versions)
- HashiCorp : référence du serveur MCP Terraform (outils, toolsets, variables d'environnement, opérations destructives)
- Docker Hub : hashicorp/terraform-mcp-server
- Model Context Protocol : introduction
- Documentation Claude Code : connecter Claude Code à des outils via MCP
- Documentation VS Code : Use MCP servers in VS Code
- Documentation HCP Terraform : jetons d'API, permissions des workspaces
- Récit de l'incident par l'ingénieur concerné : How I dropped our production database (févr. 2026, en anglais)
Comment nous avons testé : hashicorp/terraform-mcp-server:1.4.1 en stdio le 24 octobre 2026, sans jeton : initialize, tools/list et tools/call get_latest_provider_version. Les toolsets HCP Terraform n'ont pas été testés avec un vrai jeton : leur comportement est décrit d'après la documentation de référence de HashiCorp.
Image d'en-tête : Illustration générée avec Google Gemini pour DevOpsCompass.
Commentaires
Enregistrer un commentaire