これは2026/6/10時点の情報です。現在の使い勝手は各自で確認してみてください。
はじめに
クラウドでシステムを構築する場合、IaCを導入することが望ましいです。しかし、初期構築をコンソールで行ってしまい、後からIaC化を行うという場合も少なくありません。
この際、Terraformの場合はterraform importコマンド、またはimportブロックを作って行うのが一般的だと思います。ところが、これをやるにはaws cliなどで対象リソースを絞り込んだり、最悪コンソールより目視で打ち込むといった作業が必要で、かなり手間がかかります。
これを解決してくれる機能として、Terraform v1.14よりterraform queryコマンドが実装されました。
早速使ってみましたが、正直なところ現段階では使い勝手があまり良くないと思いました。
本記事では、terraform queryとimportの比較と、なぜterraform queryが微妙なのかを説明します。
terraform queryの使い方
terraform query自体は、クラウド上にあるリソースの、IDや名前を表示させるコマンドです。機能自体は既存のaws cliでも可能ですが、-generate-config-outと組み合わせることでコードファイルを簡単に作成できるという強みがあります。
ここでは、terraform queryの実行手順を説明します。ここでは、AWSのVPCに対してterrafor queryを実行することを考えます。なお、terraform queryに対応しているかは、Terraform Registry公式の、List Resourcesに記載されているかで判断してください。これはVPCの例です。
- terraform queryは
.tfquery.hclにlistブロックを作成します。また、filterでタグやIDを指定することで、対象リソースを制限することができます。以下はVPCについて記載した例です。ここでは、VPCに対してProjectタグにimport-testと記載されたものを出力するようにしています。
list "aws_vpc" "this" {
provider = aws
config {
filter {
name = "tag:Project"
values = ["import-test"]
}
}
}
-
.tfquery.hclファイルを作成後、ファイルがある場所でterraform queryコマンドを実行します。以下は実行結果です。
list.aws_vpc.this account_id=111...,id=vpc-aaaaa...,region=ap-southeast-2 kato-import-test (vpc-aaaaa...)
- 先ほどqueryで抽出するリソースを確認した後、
teraform query -generate-config-out=vpc.tfを実行することで、コードファイルが作成されます。以下はその例です。
# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.
# __generated__ by Terraform
resource "aws_vpc" "this_0" {
provider = aws
assign_generated_ipv6_cidr_block = false
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = false
enable_dns_support = true
enable_network_address_usage_metrics = false
instance_tenancy = "default"
ipv4_ipam_pool_id = null
ipv4_netmask_length = null
ipv6_ipam_pool_id = null
ipv6_netmask_length = 0
region = "ap-southeast-2"
tags = {
Name = "kato-import-test"
}
tags_all = {
Name = "kato-import-test"
Owner = "kato"
Project = "import-test"
}
}
import {
to = aws_vpc.this_0
provider = aws
identity = {
account_id = "111..."
id = "vpc-aaaaa..."
region = "ap-southeast-2"
}
}
importを使う場合の比較
機能面での比較
terraform queryとterraform importは、どちらも既存リソースのIaC化で使えますが、得意な用途が異なります。
| 観点 | terraform query | terraform import |
|---|---|---|
| 主な目的 | リソース探索・候補抽出・雛形生成 | 既存リソースをstateへ取り込む |
| 事前調査 |
filterである程度絞れる |
IDを事前に把握する必要がある |
| コード生成 |
-generate-config-outで生成可能 |
原則手書き(または別手段で生成) |
| 取り込み確実性 | provider対応状況に依存 | 従来から安定して利用可能 |
| 細かい制御 | まだ制約が多い場面あり | 対象を1件ずつ正確に指定しやすい |
| 向いている作業 | まず全体像を掴む、候補を見つける | 本番stateへ確実に登録する |
AIエージェントを使う場合の比較
現在では、AIエージェントを使いコードを作成することは当たり前となっており、terraform queryおよびimportも例外ではありません。ここでは、AIに書かせるという観点から比較をしていきます。
| 観点 | query中心で進める場合 | import中心で進める場合 |
|---|---|---|
| エージェントの強み | タグや条件から候補を広く探索しやすい | 対象IDが確定していれば作業が直線的 |
| ありがちなミス | 想定外リソースまで拾う | IDの打ち間違い・対応漏れ |
| レビューしやすさ | 生成コードをまとめて確認しやすい | 1件ずつ確認しやすい |
| スピード | 初期調査は速い | 件数が多いと遅くなりやすい |
| 安全性 | 生成物レビューを省くと危険 | 取り込み対象が明確なら比較的安全 |
| 取り込み精度 | listの設定により確実 | 取り込み漏れの可能性がある |
いざ使ってみたが・・・
使い方の章で説明したVPCは上手くいきましたが、一部リソースでは公式ドキュメントと実際の機能に差異があります。以下に例を示します。
セキュリティグループ
公式ドキュメントでのlistブロックの設定例は以下のようになっています。
list "aws_security_group" "example" {
provider = aws
filter {
name = "vpc-id"
values = ["vpc-12345678"]
}
filter {
name = "group-name"
values = ["my-security-group*"]
}
}
ですが、実際には以下のように、configで括らなければエラーとなってしまいます。
list "aws_security_group" "kato_import_test" {
provider = aws
config {
filter {
name = "vpc-id"
values = ["vpc-12345678"]
}
filter {
name = "group-name"
values = ["my-security-group*"]
}
}
}
EBS
公式ドキュメントでは以下のように設定があります。
list "aws_ec2_ebs_volume" "example" {
provider = aws
config {
filter {
name = "availability-zone"
values = ["us-west-2a"]
}
}
}
ですが、使おうとすると以下のようにサポートしていない旨のエラーがでます。
$ terraform query
╷
│ Error: Invalid list resource
│
│ on list.tfquery.hcl line 56, in list "aws_ec2_ebs_volume" "example":
│ 56: list "aws_ec2_ebs_volume" "example" {
│
│ The provider hashicorp/aws does not support list resource "aws_ec2_ebs_volume".
使ってみた感想
aws cliの結果を使いimportを実行するというのはよくやると思いますが、ステップを二段階踏む必要があり、少々面倒です。terraform queryはその問題を解決してくれる点では有望だと思います。
しかし、AIエージェントを活用することを考えると、公式ドキュメントの整備が十分でない点は、大きな課題に感じます。
そのため、現状は従来通りのimportを使う方が良さそうです。