import ブロック — 既存リソースをTerraform管理下に取り込む(1.5+)

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バケットは bucketaccount_idregion の組み合わせで識別できます。使用できるかはプロバイダーのドキュメントを参照してください。


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_vpcVPC ID"vpc-0abc1234"
aws_subnetサブネットID"subnet-0abc1234"
aws_security_groupセキュリティグループID"sg-0abc1234"
aws_iam_roleロール名"my-role-name"

8. 関連記事


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