Terraform guide
Skill WhiteMuush/Your-Claude-DevOps-Teacher/skills/terraform-guide
Guide Terraform pour l'Infrastructure as Code, modules, state management, workspaces et bonnes pratiques. À utiliser quand l'utilisateur écrit du Terraform, conçoit des modules ou gère de l'infrastructure cloud. Se déclenche aussi avec "terraform", "infrastructure as code", "terraform plan", "terraform apply", "module terraform", "tfstate", "HCL".From its SKILL.md
npx -y skills add WhiteMuush/Your-Claude-DevOps-Teacher --skill terraform-guideAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
8.6 KB, ~2.2k tokens by cl100k_base, as published. Nobody here has run it
Guide Terraform
1. Workflow opérationnel (étapes numérotées)
- Initialiser, configurer le backend et télécharger les providers.
terraform init -upgrade # première fois ou mise à jour providers terraform init -reconfigure # changer de backend sans migrer l'état - Valider, vérifier la syntaxe avant de planifier.
terraform validate terraform fmt -recursive # formater tout le répertoire - Planifier, toujours sauvegarder le plan pour un apply déterministe.
terraform plan -out=tfplan.bin terraform show -json tfplan.bin | jq '.resource_changes[] | select(.change.actions != ["no-op"])' - Appliquer, uniquement depuis le plan sauvegardé.
terraform apply tfplan.bin - Vérifier le drift, détecter les divergences entre state et réalité.
terraform plan -refresh-only # voir ce qui a changé hors Terraform terraform apply -refresh-only # re-synchroniser le state sans modifier les ressources - Détruire proprement, cibler d'abord, jamais en masse sans review.
terraform destroy -target=module.networking.azurerm_subnet.main
2. Structure de projet recommandée
infrastructure/
├── environments/
│ ├── dev/
│ │ ├── main.tf # appels aux modules
│ │ ├── variables.tf
│ │ ├── terraform.tfvars
│ │ └── backend.tf
│ ├── staging/
│ └── production/
├── modules/
│ ├── networking/ # un module = une responsabilité
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── database/
│ └── app-service/
└── shared/
└── versions.tf # contraintes de version providers
Critère de découpage : un module par "domaine fonctionnel" (réseau, stockage, compute). Éviter les modules à 1 ressource (sur-découpage) et les modules "tout en un" (couplage fort).
3. Module réutilisable, exemple complet
# modules/app-service/variables.tf
variable "app_name" { type = string }
variable "environment" {
type = string
validation {
condition = contains(["dev", "staging", "production"], var.environment)
error_message = "Valeurs acceptées : dev, staging, production."
}
}
variable "sku" { type = string; default = "B1" }
variable "location" { type = string }
variable "resource_group_name"{ type = string }
variable "app_settings" { type = map(string); default = {} }
# modules/app-service/main.tf
locals {
common_tags = {
Environment = var.environment
ManagedBy = "terraform"
Application = var.app_name
}
}
resource "azurerm_service_plan" "this" {
name = "plan-${var.app_name}-${var.environment}"
location = var.location
resource_group_name = var.resource_group_name
os_type = "Linux"
sku_name = var.sku
tags = local.common_tags
}
resource "azurerm_linux_web_app" "this" {
name = "app-${var.app_name}-${var.environment}"
location = var.location
resource_group_name = var.resource_group_name
service_plan_id = azurerm_service_plan.this.id
tags = local.common_tags
site_config {
always_on = var.environment == "production"
application_stack { dotnet_version = "8.0" }
}
app_settings = var.app_settings
}
# modules/app-service/outputs.tf
output "app_url" { value = "https://${azurerm_linux_web_app.this.default_hostname}" }
output "app_id" { value = azurerm_linux_web_app.this.id }
output "plan_id" { value = azurerm_service_plan.this.id }
Appel depuis un environnement :
module "api" {
source = "../../modules/app-service"
app_name = "myapi"
environment = "production"
sku = "P1v3"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
}
4. State management
Backend distant avec locking (Azure)
# environments/production/backend.tf
terraform {
backend "azurerm" {
resource_group_name = "rg-terraform-state"
storage_account_name = "stterraformstprod"
container_name = "tfstate"
key = "myapp.production.tfstate"
use_azuread_auth = true # évite les clés de compte (2025+)
}
}
Backend S3 + DynamoDB (AWS)
terraform {
backend "s3" {
bucket = "myco-tfstate-prod"
key = "myapp/production/terraform.tfstate"
region = "eu-west-1"
encrypt = true
dynamodb_table = "terraform-state-lock"
}
}
Commandes de gestion du state
terraform state list # toutes les ressources
terraform state show azurerm_linux_web_app.this # détail d'une ressource
terraform state mv module.old.res module.new.res # renommer sans recréer
terraform state rm azurerm_resource_group.legacy # retirer du state sans détruire
terraform import azurerm_resource_group.legacy /subscriptions/.../rg-name
5. Versions et contraintes providers
# shared/versions.tf, à copier dans chaque environnement
terraform {
required_version = ">= 1.7, < 2.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.110"
}
random = {
source = "hashicorp/random"
version = "~> 3.6"
}
}
}
Verrouiller le .terraform.lock.hcl dans Git, il garantit la reproductibilité des builds.
6. Garde-fous et pièges fréquents
| Piège | Symptôme | Remède |
|---|---|---|
| State en local / commité dans Git | Conflits d'équipe, secrets exposés | Backend distant + .gitignore sur *.tfstate* |
terraform apply sans plan sauvegardé | Apply incohérent si state a changé entre-temps | Toujours -out=tfplan.bin + apply tfplan.bin |
| Hard-coding de secrets dans HCL | Secrets dans Git | var + Key Vault / Secrets Manager ou sensitive = true |
| Modules trop fins (1 ressource) | Overhead de composition, appels imbriqués | Regrouper par domaine fonctionnel |
terraform destroy sans -target | Destruction de toute l'infra | Toujours cibler ou utiliser des workspaces isolés |
| Drift ignoré | État réel diverge du plan | plan -refresh-only en CI hebdomadaire |
Pas de lifecycle.prevent_destroy sur ressources critiques | Suppression accidentelle BDD/stockage | Ajouter prevent_destroy = true sur les ressources stateful |
# Protéger une base de données critique
resource "azurerm_postgresql_flexible_server" "main" {
# ...
lifecycle {
prevent_destroy = true
}
}
7. Bonnes pratiques 2026
- Épingler les versions providers via
.terraform.lock.hcl(commité dans Git). - Secrets : ne jamais les mettre dans
.tfvars; utilisersensitive = true+ injection CI (env varsTF_VAR_*). - Tagging systématique : module
localsaveccommon_tagshérité par toutes les ressources. - Outputs sensibles : marquer
sensitive = truepour éviter les logs en clair. - CI/CD :
terraform planen PR (commentaire automatique),terraform applyuniquement sur merge main. - Workspaces : réservés aux environnements éphémères (feature branches), ne pas les utiliser pour prod/staging (préférer des dossiers séparés avec leur propre state).
- Tflint + Checkov : linting et scan de sécurité avant le plan.
tflint --recursive checkov -d . --framework terraform
8. Commandes de référence rapide
# Init & format
terraform init -upgrade && terraform fmt -recursive && terraform validate
# Plan sécurisé
terraform plan -var-file=environments/prod.tfvars -out=tfplan.bin
# Inspection du plan
terraform show tfplan.bin # lisible humain
terraform show -json tfplan.bin | jq '.' # JSON pour scripts
# State ops
terraform state list
terraform state show <resource_address>
terraform state mv <src> <dst>
terraform state rm <resource_address>
# Import ressource existante
terraform import <resource_address> <cloud_id>
# Drift
terraform plan -refresh-only
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.