terraform-search-import について
既存のクラウドリソースを検索し、Terraform stateへの一括インポート用設定を生成するガイドです。インフラ移行、監査、未管理リソースのTerraform管理への移行を対象に、Providerの対応確認から検索、設定生成、インポート検証までを扱います。
主な機能
- 01既存クラウドリソースの検索
- 02Providerのlist resource対応確認
- 03条件やリージョンによる検索絞り込み
- 04resourceと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 Search と一括インポート
宣言的なクエリを使用して既存のクラウドリソースを検出し、Terraform の state に一括インポートするための設定を生成します。
参考資料:
使用する場面
- 管理対象外のリソースを Terraform の管理下に置く
- 既存のクラウドインフラを監査する
- 手動プロビジョニングから IaC に移行する
- 複数のリージョンやアカウントにわたってリソースを検出する
重要:最初にプロバイダーのサポートを確認してください
開始する前に、対象のリソースタイプがサポートされていることを必ず確認してください:
# 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 を参照してください)
注:サポート対象のリソースは急速に増えています。手動インポートを使用する前に、必ず現在のサポート状況を確認してください。
前提条件
クエリを作成する前に、プロバイダーが対象のリソースタイプの list リソースをサポートしていることを確認してください。
利用可能な list リソースを検出する
ヘルパースクリプトを実行して、プロバイダーでサポートされている 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
または、プロバイダーのスキーマを手動で確認します:
terraform providers schema -json | jq '.provider_schemas | to_entries | map({key: (.key | split("/")[-1]), value: (.value.list_resource_schemas // {} | keys)})'
Terraform Search を使用するには、作業ディレクトリを初期化しておく必要があります。クエリを実行する前に、必要なプロバイダーを含む設定があることを確認してください:
# terraform.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
terraform init を実行してプロバイダーをダウンロードしてから、クエリを実行してください。
Terraform Search ワークフロー(サポート対象のリソースのみ)
- 検索クエリを定義する
listブロックを含む.tfquery.hclファイルを作成します 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 リソース
list リソースのプロバイダーによるサポート状況は、バージョンによって異なります。検出スクリプトを使用して、使用中のプロバイダーバージョンで利用できるリソースを必ず確認してください。
クエリの例
基本的な検出
# 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
}
}
ID によるインポート
生成されるインポートでは、ID ベースのインポートを使用します(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)。プロバイダーを利用できず、init も実行できない場合、概要情報(アドレス、出力、serial/lineage)だけが必要な場合、または Terraform の実行を避ける必要がある場合に限り、生の状態(terraform state pull/terraform.tfstate)を使用します。状態形式バージョン 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