
Terraform Search Import
- 3.4k installs
- 781 repo stars
- Updated August 4, 2026
- hashicorp/agent-skills
terraform-search-import is a HashiCorp skill that discovers existing cloud resources with Terraform Search list queries and bulk imports them into Terraform state.
About
Terraform Search and Bulk Import is a HashiCorp agent skill for bringing unmanaged cloud infrastructure under Terraform control using declarative list queries and identity-based bulk import. Before any workflow starts, you must verify the target provider supports list resources via list_resources.sh or terraform providers schema, and confirm Terraform is at least version 1.14. Supported resources follow a five-step path: write .tfquery.hcl files with list blocks, run terraform query, generate configuration with -generate-config-out, review generated resource and import blocks, then plan and apply. Query files support provider blocks, filtered discovery by tags or instance types, multi-region for_each patterns, and parameterized variables. Generated output includes full resource attributes plus import blocks using identity fields for Terraform 1.12 and newer. Post-generation cleanup removes computed attributes, replaces hardcoded values with variables, and organizes files. When list resources are unsupported or Terraform is below 1.14, the skill routes to the manual discovery workflow in MANUAL-IMPORT.md. Best practices emphasize starting broad, using limit, testing queries before.
- Requires Terraform 1.14+ and provider list resource support verified before starting.
- Five-step workflow: .tfquery.hcl queries, terraform query, generate config, review, plan and apply.
- Supports filtered, multi-region, and parameterized list blocks with provider-specific config.
- Generates identity-based import blocks alongside resource configuration for bulk adoption.
- Falls back to manual discovery when list resources or Terraform version are unsupported.
Terraform Search Import by the numbers
- 3,395 all-time installs (skills.sh)
- +167 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #49 of 1,435 DevOps & CI/CD skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
terraform-search-import capabilities & compatibility
- Capabilities
- provider list resource discovery via list_resour · declarative .tfquery.hcl list block authoring wi · terraform query execution and generate config o · identity based import block generation for terra · manual discovery fallback routing when list reso
- Works with
- aws · terraform · azure
- Use cases
- devops · ci cd
What terraform-search-import says it does
Discover existing cloud resources using declarative queries and generate configuration for bulk import into Terraform state.
BEFORE starting, you MUST verify the target resource type is supported
Generated imports use identity-based import (Terraform 1.12+)
npx skills add https://github.com/hashicorp/agent-skills --skill terraform-search-importAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 3.4k |
|---|---|
| repo stars | ★ 781 |
| Security audit | 3 / 3 scanners passed |
| Last updated | August 4, 2026 |
| Repository | hashicorp/agent-skills ↗ |
How do I find unmanaged cloud resources across regions and accounts and import them into Terraform without hand-writing every resource block?
Discover existing cloud resources with Terraform Search list queries and bulk import them into Terraform state with generated resource and import blocks.
Who is it for?
Platform engineers migrating manual cloud provisioning to IaC who can run Terraform 1.14+ with list-resource-capable providers.
Skip if: Skip when the provider lacks list resource support, Terraform is below 1.14, or you only need greenfield module authoring.
When should I use this skill?
User wants to bulk import existing infrastructure, audit cloud resources, or migrate unmanaged resources to Terraform using search queries.
What you get
Generated resource and import blocks from terraform query -generate-config-out, reviewed configuration, and imported infrastructure under Terraform management.
- discovery.tfquery.hcl files
- generated resource and import blocks
- cleaned Terraform configuration
By the numbers
- [object Object]
- [object Object]
Files
Terraform Search and Bulk Import
Discover existing cloud resources using declarative queries and generate configuration for bulk import into Terraform state.
References:
When to Use
- Bringing unmanaged resources under Terraform control
- Auditing existing cloud infrastructure
- Migrating from manual provisioning to IaC
- Discovering resources across multiple regions/accounts
IMPORTANT: Check Provider Support First
BEFORE starting, you MUST verify the target resource type is supported:
# Check what list resources are available
./scripts/list_resources.sh aws # Specific provider
./scripts/list_resources.sh # All configured providersDecision Tree
1. Identify target resource type (e.g., aws_s3_bucket, aws_instance) 2. Check if supported: Run ./scripts/list_resources.sh <provider> 3. Choose workflow:
- If supported: Check for terraform version available.
- If terraform version is above 1.14.0 Use Terraform Search workflow (below)
- If not supported or terraform version is below 1.14.0 : Use Manual Discovery workflow (see references/MANUAL-IMPORT.md)
Note: The list of supported resources is rapidly expanding. Always verify current support before using manual import.
Prerequisites
Before writing queries, verify the provider supports list resources for your target resource type.
Discover Available List Resources
Run the helper script to extract supported list resources from your provider:
# From a directory with provider configuration (runs terraform init if needed)
./scripts/list_resources.sh aws # Specific provider
./scripts/list_resources.sh # All configured providersOr manually query the provider schema:
terraform providers schema -json | jq '.provider_schemas | to_entries | map({key: (.key | split("/")[-1]), value: (.value.list_resource_schemas // {} | keys)})'Terraform Search requires an initialized working directory. Ensure you have a configuration with the required provider before running queries:
# terraform.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}Run terraform init to download the provider, then proceed with queries.
Terraform Search Workflow (Supported Resources Only)
1. Create .tfquery.hcl files with list blocks defining search queries 2. Run terraform query to discover matching resources 3. Generate configuration with -generate-config-out=<file> 4. Review and refine generated resource and import blocks 5. Run terraform plan and terraform apply to import
Query File Structure
Query files use .tfquery.hcl extension and support:
providerblocks for authenticationlistblocks for resource discoveryvariableandlocalsblocks for parameterization
# discovery.tfquery.hcl
provider "aws" {
region = "us-west-2"
}
list "aws_instance" "all" {
provider = aws
}List Block Syntax
list "<list_type>" "<symbolic_name>" {
provider = <provider_reference> # Required
# Optional: filter configuration (provider-specific)
# The `config` block schema is provider-specific. Discover available options using `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>" # AWS-specific
}
# Optional: limit results
limit = 100
}Supported List Resources
Provider support for list resources varies by version. Always check what's available for your specific provider version using the discovery script.
Query Examples
Basic Discovery
# Find all EC2 instances in configured region
list "aws_instance" "all" {
provider = aws
}Filtered Discovery
# Find instances by tag
list "aws_instance" "production" {
provider = aws
config {
filter {
name = "tag:Environment"
values = ["production"]
}
}
}
# Find instances by type
list "aws_instance" "large" {
provider = aws
config {
filter {
name = "instance-type"
values = ["t3.large", "t3.xlarge"]
}
}
}Multi-Region Discovery
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
}
}Parameterized Queries
variable "target_environment" {
type = string
default = "staging"
}
list "aws_instance" "by_env" {
provider = aws
config {
filter {
name = "tag:Environment"
values = [var.target_environment]
}
}
}Running Queries
# Execute queries and display results
terraform query
# Generate configuration file
terraform query -generate-config-out=imported.tf
# Pass variables
terraform query -var='target_environment=production'Query Output Format
list.aws_instance.all account_id=123456789012,id=i-0abc123,region=us-west-2 web-serverColumns: <query_address> <identity_attributes> <name_tag>
Generated Configuration
The -generate-config-out flag creates:
# __generated__ by Terraform
resource "aws_instance" "all_0" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
# ... all attributes
}
import {
to = aws_instance.all_0
provider = aws
identity = {
account_id = "123456789012"
id = "i-0abc123"
region = "us-west-2"
}
}Post-Generation Cleanup
Generated configuration includes all attributes. Clean up by:
1. Remove computed/read-only attributes 2. Replace hardcoded values with variables 3. Add proper resource naming 4. Organize into appropriate files
# Before: generated
resource "aws_instance" "all_0" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
arn = "arn:aws:ec2:..." # Remove - computed
id = "i-0abc123" # Remove - computed
# ... many more attributes
}
# After: cleaned
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 by Identity
Generated imports use identity-based import (Terraform 1.12+):
import {
to = aws_instance.web
provider = aws
identity = {
account_id = "123456789012"
id = "i-0abc123"
region = "us-west-2"
}
}Best Practices
Query Design
- Start broad, then add filters to narrow results
- Use
limitto prevent overwhelming output - Test queries before generating configuration
Configuration Management
- Review all generated code before applying
- Remove unnecessary default values
- Use consistent naming conventions
- Add proper variable abstraction
Troubleshooting
| Issue | Solution |
|---|---|
| "No list resources found" | Check provider version supports list resources |
| Query returns empty | Verify region and filter values |
| Generated config has errors | Remove computed attributes, fix deprecated arguments |
| Import fails | Ensure resource not already in state |
Complete Example
# main.tf - Initialize provider
terraform {
required_version = ">= 1.14"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0" # Always use latest version
}
}
}
# discovery.tfquery.hcl - Define queries
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
}# Execute workflow
terraform init
terraform query
terraform query -generate-config-out=generated.tf
# Review and clean generated.tf
terraform plan
terraform applyManual Terraform Import Reference
Use this workflow when your target resource type isn't supported by Terraform Search.
1. Discover Resources Using Provider CLI
AWS CLI examples:
# RDS instances (not yet supported by Terraform Search)
aws rds describe-db-instances --query 'DBInstances[].DBInstanceIdentifier'
# DynamoDB tables (not yet supported by Terraform Search)
aws dynamodb list-tables --query 'TableNames[]'
# API Gateway REST APIs (not yet supported by Terraform Search)
aws apigateway get-rest-apis --query 'items[].id'
# SNS topics (not yet supported by Terraform Search)
aws sns list-topics --query 'Topics[].TopicArn'2. Create Resource Blocks Manually
# Example for RDS instance
resource "aws_db_instance" "existing_db" {
identifier = "my-existing-db"
# Add other required attributes
}
# Example for DynamoDB table
resource "aws_dynamodb_table" "existing_table" {
name = "my-existing-table"
# Add other required attributes
}
# Example for SNS topic
resource "aws_sns_topic" "existing_topic" {
name = "my-existing-topic"
}3. Create Import Blocks (Config-Driven Import)
# Example for RDS instance
resource "aws_db_instance" "existing_db" {
identifier = "my-existing-db"
# Add other required attributes
}
import {
to = aws_db_instance.existing_db
id = "my-existing-db"
}
# Example for DynamoDB table
resource "aws_dynamodb_table" "existing_table" {
name = "my-existing-table"
# Add other required attributes
}
import {
to = aws_dynamodb_table.existing_table
id = "my-existing-table"
}4. Run Import Plan
# Plan the import to see what will happen
terraform plan
# Apply to import the resources
terraform applyBulk Import Script Example
For multiple resources of the same type:
#!/bin/bash
# bulk-import-dynamodb.sh
# Get all table names
tables=$(aws dynamodb list-tables --query 'TableNames[]' --output text)
# Generate import configuration
cat > dynamodb-imports.tf << 'EOF'
# DynamoDB Table Resources and Imports
EOF
for table in $tables; do
# Create resource and import blocks
cat >> dynamodb-imports.tf << EOF
resource "aws_dynamodb_table" "table_${table//[-.]/_}" {
name = "$table"
}
import {
to = aws_dynamodb_table.table_${table//[-.]/_}
id = "$table"
}
EOF
done
echo "Generated dynamodb-imports.tf with import blocks"
echo "Run 'terraform plan' to review, then 'terraform apply' to import"#!/bin/bash
# Copyright IBM Corp. 2025, 2026
# SPDX-License-Identifier: MPL-2.0
# Extract list resources supported by Terraform providers
# Usage: ./list_resources.sh [provider_name]
# Requires: terraform, jq
# Note: Run from an initialized Terraform directory (terraform init)
set -e
PROVIDER=$1
# Ensure terraform is initialized
if [ ! -d ".terraform" ]; then
echo "Initializing Terraform..." >&2
terraform init -upgrade > /dev/null 2>&1
fi
# Get provider schema and extract list_resource_schemas
if [ -n "$PROVIDER" ]; then
# Specific provider
provider_key=$(terraform providers schema -json 2>/dev/null | jq -r '.provider_schemas | keys[]' | grep "/${PROVIDER}$" || true)
if [ -n "$provider_key" ]; then
terraform providers schema -json 2>/dev/null | jq -r \
"{\"$PROVIDER\": (.provider_schemas.\"${provider_key}\" | .list_resource_schemas // {} | keys | sort)}"
else
echo "{\"$PROVIDER\": []}"
fi
else
# All providers
terraform providers schema -json 2>/dev/null | jq -r '
.provider_schemas
| to_entries
| map({key: (.key | split("/")[-1]), value: (.value.list_resource_schemas // {} | keys | sort)})
| from_entries
'
fi
Related skills
Forks & variants (1)
Terraform Search Import has 1 known copy in the catalog totaling 29 installs. They canonicalize to this original listing.
- hashicorp - 29 installs
How it compares
Use terraform-search-import for declarative discovery and bulk import of live resources; use greenfield modules when no existing cloud estate exists.
FAQ
What Terraform version is required?
Terraform 1.14 or newer is required for the Terraform Search list block workflow.
How do I check if my resource type is supported?
Run ./scripts/list_resources.sh for the provider or query provider list_resource_schemas before writing queries.
What does -generate-config-out produce?
It creates resource blocks plus identity-based import blocks you must review and clean before terraform plan and apply.
Is Terraform Search Import safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.