关于 terraform-search-import
Terraform Search and Bulk Import 技能指导用户发现现有云资源,并生成导入 Terraform state 的配置,适用于基础设施迁移、审计和资源接管。它先检查 Provider 对 list resource 的支持,再提供查询、生成配置及验证导入状态的流程。
主要功能
- 01查询已存在的云资源
- 02检查 Provider 的 list resource 支持
- 03按条件和区域筛选资源
- 04生成 resource 与 import 配置
- 05验证导入后的 Terraform state
适用场景
- 01将未纳管资源纳入 Terraform
- 02审计现有云基础设施
- 03从手动配置迁移到 IaC
- 04跨区域或账户发现资源
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ hashicorp/ agent-skills --skill terraform-search-import安装后在 Claude Code 中输入/terraform-search-import确认已加载。
附带文件references/MANUAL-IMPORT.mdscripts/list_resources.sh
详细介绍
Terraform 搜索和批量导入
使用声明式查询发现现有云资源,并生成配置以批量导入 Terraform 状态。
参考资料:
使用场景
- 将未受管理的资源纳入 Terraform 管理
- 审计现有云基础设施
- 从手动预配迁移到 IaC
- 跨多个区域/账户发现资源
重要:先检查 Provider 支持情况
开始之前,必须确认目标资源类型受支持:
# Check what list resources are available
./scripts/list_resources.sh aws # Specific provider
./scripts/list_resources.sh # All configured providers
决策树
-
确定目标资源类型(例如 aws_s3_bucket、aws_instance)
-
检查是否受支持:运行
./scripts/list_resources.sh <provider> -
选择工作流:
- ** 如果受支持**:检查可用的 Terraform 版本。
- ** 如果 Terraform 版本高于 1.14.0**:使用 Terraform Search 工作流(见下文)
- ** 如果不受支持或 Terraform 版本低于 1.14.0 **:使用手动发现工作流(参见 references/MANUAL-IMPORT.md)
注意:受支持资源的范围正在迅速扩大。使用手动导入前,务必确认当前支持情况。
先决条件
编写查询之前,请确认 Provider 支持针对目标资源类型列出资源。
发现可用的 List 资源
运行辅助脚本,从 Provider 中提取受支持的 List 资源:
# From a directory with provider configuration (runs terraform init if needed)
./scripts/list_resources.sh aws # Specific provider
./scripts/list_resources.sh # All configured providers
或者手动查询 Provider 架构:
terraform providers schema -json | jq '.provider_schemas | to_entries | map({key: (.key | split("/")[-1]), value: (.value.list_resource_schemas // {} | keys)})'
Terraform Search 需要已初始化的工作目录。运行查询前,请确保已配置所需 Provider:
# terraform.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
运行 terraform init 下载 Provider,然后继续执行查询。
Terraform Search 工作流(仅适用于受支持的资源)
- 创建
.tfquery.hcl文件,并使用list块定义搜索查询 - 运行
terraform query发现匹配的资源 - 使用
-generate-config-out=<file>生成配置 - 检查并完善生成的
resource和import块 - 运行
terraform plan和terraform apply进行导入
查询文件结构
查询文件使用 .tfquery.hcl 扩展名,并支持:
- 用于身份验证的
provider块 - 用于资源发现的
list块 - 用于参数化的
variable和locals块
# discovery.tfquery.hcl
provider "aws" {
region = "us-west-2"
}
list "aws_instance" "all" {
provider = aws
}
List 块语法
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
}
受支持的 List 资源
各个版本对 Provider 的 List 资源支持情况各不相同。务必使用发现脚本检查特定 Provider 版本支持哪些资源。
查询示例
基本发现
# Find all EC2 instances in configured region
list "aws_instance" "all" {
provider = aws
}
筛选发现
# 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"]
}
}
}
多区域发现
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
}
}
参数化查询
variable "target_environment" {
type = string
default = "staging"
}
list "aws_instance" "by_env" {
provider = aws
config {
filter {
name = "tag:Environment"
values = [var.target_environment]
}
}
}
运行查询
# 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'
查询输出格式
list.aws_instance.all account_id=123456789012,id=i-0abc123,region=us-west-2 web-server
列:<query_address> <identity_attributes> <name_tag>
生成的配置
-generate-config-out 标志会创建:
# __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"
}
}
生成后的清理
生成的配置包含所有属性。请按以下步骤清理:
- 移除计算得出的/只读属性
- 用变量替换硬编码值
- 添加恰当的资源命名
- 整理到适当的文件中
# 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
}
}
按标识导入
生成的导入使用基于标识的导入方式(Terraform 1.12+):
import {
to = aws_instance.web
provider = aws
identity = {
account_id = "123456789012"
id = "i-0abc123"
region = "us-west-2"
}
}
验证导入的状态
运行 terraform apply 导入资源后,请验证实际写入状态的内容。
优先使用有文档说明、稳定且更节省令牌的命令,而不是读取原始状态
文件:
# Confirm resources are now managed (also confirms addresses)
terraform state list
# Inspect resolved attribute values for imported resources
terraform show -json | jq '.values.root_module.resources[] | {address, type, name}'
terraform show -json 需要安装提供程序(terraform init),因为它会根据提供程序架构呈现值。仅在以下情况下才回退到原始状态
(terraform state pull / terraform.tfstate): 提供程序不可用且无法运行
init、你只需要粗略信息(地址、输出、serial/lineage),或
你必须避免执行 Terraform。不要将原始版本 4 状态格式解析为稳定的接口。注意: 状态在所有格式中都以明文包含敏感值 — 切勿将状态内容输出到日志或命令输出中。
最佳实践
查询设计
- 先从宽泛查询开始,然后添加筛选条件以缩小结果范围
- 使用
limit,避免输出内容过多 - 生成配置前先测试查询
配置管理
- 应用前检查所有生成的代码
- 删除不必要的默认值
- 使用一致的命名约定
- 添加适当的变量抽象
故障排除
| 问题 | 解决方案 |
|---|---|
| "No list resources found" | 检查提供程序版本是否支持列表资源 |
| 查询返回空结果 | 验证区域和筛选值 |
| 生成的配置有错误 | 删除计算属性,修复已弃用的参数 |
| 导入失败 | 确保资源尚未存在于状态中 |
完整示例
# 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 apply