1. 概要
importブロックとは何か(1.5以降の宣言型import)- 基本構文と使い方
terraform planでimport計画を確認するgenerated_config_outでHCLを自動生成する- 旧コマンド
terraform importとの違い
Terraform管理外で手動作成した既存リソース(AWSコンソールで作ったEC2やS3など)を、Terraformのstate管理下に取り込むのがimportブロックです。Terraform 1.5以降、コード内に宣言的に書けるようになりました。
2. importブロック vs terraform importコマンド
| 比較 | importブロック(1.5+) | terraform importコマンド |
|---|---|---|
| 書き方 | .tfファイルに宣言 | CLIコマンドで実行 |
| plan確認 | terraform planで事前確認可能 | できない(即実行) |
| レビュー | PRでコードレビューできる | 難しい |
| HCL自動生成 | generated_config_outオプションで可能 | 不可 |
| チーム共有 | .tfファイルとして共有できる | 手順書に書く必要がある |
3. 基本構文
import {
to = <リソースアドレス>
id = "<既存リソースのID>"
}
toはTerraform内でのリソースアドレス、idはAWS(または他のプロバイダー)での既存リソースのIDです。
identity属性について(最新版): プロバイダーによっては、単一IDではなく複数の属性でリソースを一意識別するidentity属性をサポートしています。例えばAWS S3バケットはbucket、account_id、regionの組み合わせで識別できます。使用できるかはプロバイダーのドキュメントを参照してください。
4. S3バケットをimportする
既存のS3バケットmy-existing-bucketをTerraform管理下に取り込みます。
ステップ1: importブロックを書く
terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
variable "environment" {
description = "環境名"
type = string
default = "dev"
}
# 既存バケットをimportする宣言
import {
to = aws_s3_bucket.existing
id = "my-existing-bucket"
}
# importしたリソースのHCL定義(既存リソースの設定に合わせる)
resource "aws_s3_bucket" "existing" {
bucket = "my-existing-bucket"
tags = {
Name = "my-existing-bucket"
Environment = var.environment
ManagedBy = "terraform"
}
}
ステップ2: planで確認する
$ terraform plan
Terraform will perform the following actions:
# aws_s3_bucket.existing will be imported
+ resource "aws_s3_bucket" "existing" {
+ bucket = "my-existing-bucket"
+ id = "my-existing-bucket"
...
}
Plan: 1 to import, 0 to add, 0 to change, 0 to destroy.
ステップ3: applyで取り込む
$ terraform apply
aws_s3_bucket.existing: Importing... [id=my-existing-bucket]
aws_s3_bucket.existing: Import complete [id=my-existing-bucket]
Apply complete! Resources: 1 imported, 0 added, 0 changed, 0 destroyed.
5. generated_config_out でHCLを自動生成する
既存リソースのHCL定義を一から書くのは大変です。-generated-config-outオプションを使うと、Terraformがリソースの現在の設定からHCLを自動生成します。
# まずimportブロックだけを書く(resourceブロックは不要)
import {
to = aws_instance.existing_server
id = "i-0abc1234def56789"
}
# HCLを自動生成(generated.tfに出力される)
$ terraform plan -generate-config-out=generated.tf
生成されたgenerated.tfを確認・編集してからapplyします。
6. EC2インスタンスをimportする実例
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
# 既存EC2インスタンスのimport宣言
import {
to = aws_instance.legacy_server
id = "i-0abc1234def56789" # AWSコンソールで確認したインスタンスID
}
resource "aws_instance" "legacy_server" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = "t3.micro"
root_block_device {
volume_size = 20
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${var.environment}-legacy"
Environment = var.environment
ManagedBy = "terraform"
}
}
7. 主要リソースのimport ID一覧
| リソース | ID形式 | 例 |
|---|---|---|
aws_s3_bucket | バケット名 | "my-bucket" |
aws_instance | インスタンスID | "i-0abc1234def56789" |
aws_vpc | VPC ID | "vpc-0abc1234" |
aws_subnet | サブネットID | "subnet-0abc1234" |
aws_security_group | セキュリティグループID | "sg-0abc1234" |
aws_iam_role | ロール名 | "my-role-name" |
8. 関連記事
- state管理とは — tfstateファイルの役割とリスク
- moved ブロック — stateのアドレス変更をリファクタリングに活用
- data(データソース)の使い方 — 既存リソースの参照方法
- terraform importコマンド vs importブロック比較
- terraform state コマンド完全ガイド
- resourceブロック — 基本構文と使い方
9. まとめ
importブロックはTerraform 1.5以降で利用可能.tfファイルに宣言的に書け、terraform planで事前確認できるfrom(旧コマンド)と異なり、PRでのコードレビューや共有が容易-generate-config-outオプションでHCLの自動生成が可能apply後はimportブロックを削除してよい(stateに取り込まれたため)
動作確認バージョン: Terraform >= 1.5 公式ドキュメント: https://developer.hashicorp.com/terraform/language/import