terraform-search-import

Par hashicorp · agent-skills

Découvrez les ressources cloud existantes à l'aide des requêtes de recherche Terraform et importez-les en masse dans la gestion Terraform. À utiliser pour placer une infrastructure non gérée sous contrôle Terraform, auditer des ressources cloud ou migrer vers l'IaC.

npx skills add https://github.com/hashicorp/agent-skills --skill terraform-search-import

Recherche Terraform et Import en Masse

Découvrez les ressources cloud existantes à l'aide de requêtes déclaratives et générez une configuration pour importer en masse dans l'état Terraform.

Références :

Quand l'utiliser

  • Placer des ressources non gérées sous contrôle Terraform
  • Auditer l'infrastructure cloud existante
  • Migrer de l'approvisionnement manuel vers l'IaC
  • Découvrir des ressources sur plusieurs régions/comptes

IMPORTANT : Vérifier le Support du Provider en Premier

AVANT de commencer, vous DEVEZ vérifier que le type de ressource cible est supporté :

# Vérifier quelles ressources list sont disponibles
./scripts/list_resources.sh aws      # Provider spécifique
./scripts/list_resources.sh          # Tous les providers configurés

Arbre de Décision

  1. Identifier le type de ressource cible (ex. aws_s3_bucket, aws_instance)

  2. Vérifier si supporté : Exécuter ./scripts/list_resources.sh <provider>

  3. Choisir le workflow :

    • Si supporté : Vérifier la version Terraform disponible.
    • Si la version Terraform est supérieure à 1.14.0 : Utiliser le workflow Terraform Search (ci-dessous)
    • Si non supporté ou version Terraform inférieure à 1.14.0 : Utiliser le workflow Découverte Manuelle (voir references/MANUAL-IMPORT.md)

    Note : La liste des ressources supportées s'étend rapidement. Toujours vérifier le support actuel avant d'utiliser l'import manuel.

Prérequis

Avant d'écrire des requêtes, vérifiez que le provider supporte les ressources list pour votre type de ressource cible.

Découvrir les Ressources List Disponibles

Exécutez le script helper pour extraire les ressources list supportées de votre provider :

# Depuis un répertoire avec configuration provider (lance terraform init si nécessaire)
./scripts/list_resources.sh aws      # Provider spécifique
./scripts/list_resources.sh          # Tous les providers configurés

Ou interrogez manuellement le schéma du provider :

terraform providers schema -json | jq '.provider_schemas | to_entries | map({key: (.key | split("/")[-1]), value: (.value.list_resource_schemas // {} | keys)})'

Terraform Search nécessite un répertoire de travail initialisé. Assurez-vous d'avoir une configuration avec le provider requis avant d'exécuter les requêtes :

# terraform.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

Exécutez terraform init pour télécharger le provider, puis procédez aux requêtes.

Workflow Terraform Search (Ressources Supportées Uniquement)

  1. Créer des fichiers .tfquery.hcl avec des blocs list définissant les requêtes de recherche
  2. Exécuter terraform query pour découvrir les ressources correspondantes
  3. Générer la configuration avec -generate-config-out=<file>
  4. Examiner et affiner les blocs resource et import générés
  5. Exécuter terraform plan et terraform apply pour importer

Structure du Fichier de Requête

Les fichiers de requête utilisent l'extension .tfquery.hcl et supportent :

  • Les blocs provider pour l'authentification
  • Les blocs list pour la découverte de ressources
  • Les blocs variable et locals pour la paramétrisation
# discovery.tfquery.hcl
provider "aws" {
  region = "us-west-2"
}

list "aws_instance" "all" {
  provider = aws
}

Syntaxe du Bloc List

list "<list_type>" "<symbolic_name>" {
  provider = <provider_reference>  # Requis

  # Optionnel : configuration de filtre (spécifique au provider)
  # Le schéma du bloc `config` est spécifique au provider. Découvrez les options disponibles avec `terraform providers schema -json | jq '.provider_schemas."registry.terraform.io/hashicorp/<provider>".list_resource_schemas."<resource_type>"'`

  config {
    filter {
      name   = "<filter_name>"
      values = ["<value1>", "<value2>"]
    }
    region = "<region>"  # Spécifique à AWS
  }
  # Optionnel : limiter les résultats
  limit = 100
}

Ressources List Supportées

Le support du provider pour les ressources list varie selon la version. Vérifiez toujours ce qui est disponible pour votre version de provider spécifique en utilisant le script de découverte.

Exemples de Requêtes

Découverte Basique

# Trouver toutes les instances EC2 dans la région configurée
list "aws_instance" "all" {
  provider = aws
}

Découverte Filtrée

# Trouver les instances par tag
list "aws_instance" "production" {
  provider = aws

  config {
    filter {
      name   = "tag:Environment"
      values = ["production"]
    }
  }
}

# Trouver les instances par type
list "aws_instance" "large" {
  provider = aws

  config {
    filter {
      name   = "instance-type"
      values = ["t3.large", "t3.xlarge"]
    }
  }
}

Découverte Multi-Régions

provider "aws" {
  region = "us-west-2"
}

locals {
  regions = ["us-west-2", "us-east-1", "eu-west-1"]
}

list "aws_instance" "all_regions" {
  for_each = toset(local.regions)
  provider = aws

  config {
    region = each.value
  }
}

Requêtes Paramétrées

variable "target_environment" {
  type    = string
  default = "staging"
}

list "aws_instance" "by_env" {
  provider = aws

  config {
    filter {
      name   = "tag:Environment"
      values = [var.target_environment]
    }
  }
}

Exécuter les Requêtes

# Exécuter les requêtes et afficher les résultats
terraform query

# Générer un fichier de configuration
terraform query -generate-config-out=imported.tf

# Passer des variables
terraform query -var='target_environment=production'

Format de Sortie des Requêtes

list.aws_instance.all   account_id=123456789012,id=i-0abc123,region=us-west-2   web-server

Colonnes : <query_address> <identity_attributes> <name_tag>

Configuration Générée

Le flag -generate-config-out crée :

# __generated__ by Terraform
resource "aws_instance" "all_0" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  # ... tous les attributs
}

import {
  to       = aws_instance.all_0
  provider = aws
  identity = {
    account_id = "123456789012"
    id         = "i-0abc123"
    region     = "us-west-2"
  }
}

Nettoyage Post-Génération

La configuration générée inclut tous les attributs. Nettoyez en :

  1. Supprimer les attributs calculés/lecture seule
  2. Remplacer les valeurs en dur par des variables
  3. Ajouter des noms de ressources appropriés
  4. Organiser dans les fichiers appropriés
# Avant : généré
resource "aws_instance" "all_0" {
  ami                    = "ami-0c55b159cbfafe1f0"
  instance_type          = "t2.micro"
  arn                    = "arn:aws:ec2:..."  # Supprimer - calculé
  id                     = "i-0abc123"        # Supprimer - calculé
  # ... beaucoup d'autres attributs
}

# Après : nettoyé
resource "aws_instance" "web_server" {
  ami           = var.ami_id
  instance_type = var.instance_type
  subnet_id     = var.subnet_id

  tags = {
    Name        = "web-server"
    Environment = var.environment
  }
}

Import par Identité

Les imports générés utilisent l'import basé sur l'identité (Terraform 1.12+) :

import {
  to       = aws_instance.web
  provider = aws
  identity = {
    account_id = "123456789012"
    id         = "i-0abc123"
    region     = "us-west-2"
  }
}

Vérifier l'État Importé

Après avoir exécuté terraform apply pour importer les ressources, vérifiez ce qui s'est réellement retrouvé dans l'état. Préférez les commandes documentées, stables et plus efficaces en tokens que de lire le fichier d'état brut :

# Confirmer que les ressources sont désormais gérées (confirme aussi les adresses)
terraform state list

# Inspecter les valeurs d'attribut résolues pour les ressources importées
terraform show -json | jq '.values.root_module.resources[] | {address, type, name}'

terraform show -json nécessite que les providers soient installés (terraform init), car il restitue les valeurs selon les schémas du provider. Retombez sur l'état brut (terraform state pull / terraform.tfstate) uniquement quand les providers ne sont pas disponibles et que init ne peut pas s'exécuter, vous n'avez besoin que d'informations générales (adresses, outputs, serial/lineage), ou vous devez éviter d'exécuter Terraform. Évitez de parser le format d'état version-4 brut comme interface stable. Note : l'état contient des valeurs sensibles en texte brut dans tous les formats — ne jamais afficher le contenu de l'état dans les logs ou la sortie.

Bonnes Pratiques

Conception des Requêtes

  • Commencer large, puis ajouter des filtres pour affiner les résultats
  • Utiliser limit pour éviter une sortie accablante
  • Tester les requêtes avant de générer la configuration

Gestion de la Configuration

  • Examiner tout le code généré avant d'appliquer
  • Supprimer les valeurs par défaut inutiles
  • Utiliser des conventions de nommage cohérentes
  • Ajouter une abstraction appropriée des variables

Dépannage

Problème Solution
« Aucune ressource list trouvée » Vérifier que la version du provider supporte les ressources list
La requête retourne vide Vérifier la région et les valeurs de filtre
La configuration générée a des erreurs Supprimer les attributs calculés, corriger les arguments dépréciés
L'import échoue S'assurer que la ressource n'est pas déjà dans l'état

Exemple Complet

# main.tf - Initialiser le provider
terraform {
  required_version = ">= 1.14"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"  # Toujours utiliser la dernière version
    }
  }
}

# discovery.tfquery.hcl - Définir les requêtes
provider "aws" {
  region = "us-west-2"
}

list "aws_instance" "team_instances" {
  provider = aws

  config {
    filter {
      name   = "tag:Owner"
      values = ["platform"]
    }
    filter {
      name   = "instance-state-name"
      values = ["running"]
    }
  }

  limit = 50
}
# Exécuter le workflow
terraform init
terraform query
terraform query -generate-config-out=generated.tf
# Examiner et nettoyer generated.tf
terraform plan
terraform apply

Skills similaires