1. 概要
terraform importコマンド(従来の方法)importブロック(Terraform 1.5+の新機能)- 2つの方法の比較
- どちらを選ぶべきか
Terraform管理外で作成されたAWSリソースをTerraformで管理したい場合、「インポート」が必要です。Terraform 1.5で導入されたimportブロックはより安全で再現性の高いアプローチを提供します。
2. importコマンド(従来の方法)
# 書式
$ terraform import <リソースアドレス> <リソースID>
# EC2インスタンスをインポート
$ terraform import aws_instance.web i-1234567890abcdef0
# S3バケットをインポート
$ terraform import aws_s3_bucket.app_data my-bucket-name
# セキュリティグループをインポート
$ terraform import aws_security_group.alb sg-0123456789abcdef0
# moduleのリソースをインポート
$ terraform import module.network.aws_vpc.main vpc-0123456789abcdef0
手順:
- コードに空のリソースブロックを書く
terraform importを実行してstateに取り込むterraform state showで現在の属性値を確認する- コードに属性値を書き写す
terraform planでdiffがゼロになることを確認する
# ステップ1: 空のリソースブロック(仮)
resource "aws_instance" "web" {
# importコマンド実行後にstate showで確認した値を書く
}
問題点:
- 手動で属性値をコードに書き写す手間がかかる
- スクリプト化・CI化が難しい
- 複数リソースを一括インポートするのが煩雑
3. importブロック(Terraform 1.5+、推奨)
terraform {
required_version = ">= 1.5"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
variable "environment" {
description = "環境名"
type = string
default = "dev"
}
# importブロック: どのリソースをどのIDでインポートするか宣言
import {
to = aws_instance.web
id = "i-1234567890abcdef0"
}
# リソースブロック: インポート後に管理したい設定を書く
resource "aws_instance" "web" {
ami = "ami-0123456789abcdef0"
instance_type = "t3.micro"
root_block_device {
volume_size = 20
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${var.environment}-web"
Environment = var.environment
ManagedBy = "terraform"
}
}
Terraform 1.5+の-generate-config-outオプション:
# コードを自動生成する(1.5+)
$ terraform plan -generate-config-out=generated.tf
# 生成されたコードを確認
$ cat generated.tf
-generate-config-outを使うと、インポートするリソースの属性値を自動でコードに書き出してくれます。
4. 複数リソースの一括インポート
# importブロックは複数書ける
import {
to = aws_vpc.main
id = "vpc-0123456789abcdef0"
}
import {
to = aws_subnet.private["ap-northeast-1a"]
id = "subnet-0123456789abcdef0"
}
import {
to = aws_subnet.private["ap-northeast-1c"]
id = "subnet-abcdef0123456789"
}
import {
to = aws_security_group.web
id = "sg-0123456789abcdef0"
}
コマンドだと4回実行する必要がある操作を、ブロックで宣言的に記述できます。
5. 2つの方法の比較
| 比較 | importコマンド | importブロック(1.5+) |
|---|---|---|
| バージョン要件 | すべてのバージョン | Terraform 1.5+ |
| コードへの記録 | 残らない | コードで宣言 |
| CI/CD対応 | 難しい | terraform planで確認可能 |
| 複数リソース | コマンドを何度も実行 | ブロックを並べるだけ |
| コードの自動生成 | なし | -generate-config-outで可能 |
| レビュー | planに表示されない | planで変更内容を確認できる |
| importブロックの後処理 | — | apply後にブロックを削除する |
6. 関連記事
- import ブロック — 既存リソースをTerraform管理下に — importブロックの詳細
- moved ブロック — stateを安全に移動する — リソース移動の宣言的な方法
- terraform state コマンド完全ガイド — state操作の基本
- state管理とは — tfstateファイルの役割・基本操作
- terraform init / plan / apply / destroy — 基本コマンド
- resourceブロック — 基本構文と使い方
7. まとめ
importコマンドは歴史的な方法。手動での属性値の書き写しが必要importブロック(1.5+)はコードに宣言でき、planでレビュー可能、CI/CD対応- Terraform 1.5+を使っているならimportブロック +
-generate-config-outが推奨 - importブロックはapply後に削除する(state管理が完了したら不要)
動作確認バージョン: Terraform >= 1.5(importブロック) 公式ドキュメント: https://developer.hashicorp.com/terraform/language/import