Import Existing Resources
นำ resource ที่สร้างใน console (หรือ tool อื่น) มาให้ Terraform manage — โดยไม่ต้องสร้างใหม่
ทำไมต้อง Import?
Real world scenarios:
- มี infrastructure ที่สร้างใน console ก่อนที่จะใช้ Terraform
- ทีมเก่าสร้างไว้ ทีมใหม่อยากเปลี่ยนมาใช้ IaC
- Resource ที่ Terraform ลืม manage (ลบจาก state แล้วลืม config)
วิธี Import — 2 แบบ
แบบเก่า: terraform import CLI (ต้องเขียน config เอง)
แบบใหม่: import block (Terraform 1.5+) ⭐
แบบใหม่: import Block (Recommended)
import {
to = aws_s3_bucket.existing
id = "my-existing-bucket"
}
resource "aws_s3_bucket" "existing" {
bucket = "my-existing-bucket"
}
Workflow
- Generate config (Terraform 1.5+)
terraform plan -generate-config-out=generated.tf
→ Terraform สร้าง config ให้อัตโนมัติจาก existing resource
-
Review generated config
-
Apply
terraform apply
→ Resource เข้า state, ไม่สร้างใหม่
ตัวอย่าง Generate Config
import {
to = aws_s3_bucket.legacy
id = "company-legacy-bucket-2020"
}
$ terraform plan -generate-config-out=generated.tf
Terraform planned the following actions, but then encountered a problem:
Terraform generated configuration for these resources:
+ aws_s3_bucket.legacy
Generated configuration was written to "generated.tf".
# __generated__ by Terraform from "company-legacy-bucket-2020"
resource "aws_s3_bucket" "legacy" {
bucket = "company-legacy-bucket-2020"
force_destroy = false
object_lock_enabled = false
tags = {
"ManagedBy" = "manual"
"Owner" = "data-team"
}
}
→ คัดลอก content ไปใส่ใน main config, ลบ import block
แบบเก่า: terraform import Command
terraform import aws_s3_bucket.existing my-existing-bucket
ต้องเขียน config ก่อน:
resource "aws_s3_bucket" "existing" {
bucket = "my-existing-bucket"
# config ที่ตรงกับ resource จริง
}
แล้วรัน import:
terraform import <RESOURCE_ADDRESS> <RESOURCE_ID>
Resource IDs
แต่ละ resource มี ID format ต่างกัน — อ่านจาก Terraform Registry docs
ตัวอย่าง:
| Resource | ID Format | ตัวอย่าง |
|---|---|---|
aws_s3_bucket | bucket name | my-bucket |
aws_instance | instance ID | i-1234567890abcdef0 |
aws_vpc | VPC ID | vpc-12345678 |
aws_iam_role | role name | MyRole |
aws_route53_zone | zone ID | Z1234567890ABC |
aws_security_group | sg ID | sg-12345678 |
ตัวอย่าง: Import VPC
import {
to = aws_vpc.main
id = "vpc-0a1b2c3d"
}
terraform plan -generate-config-out=generated.tf
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
tags = {
"Name" = "production-vpc"
}
}
ตัวอย่าง: Import Multiple Resources
import {
to = aws_vpc.main
id = "vpc-0a1b2c3d"
}
import {
to = aws_subnet.public[0]
id = "subnet-aaa"
}
import {
to = aws_subnet.public[1]
id = "subnet-bbb"
}
import {
to = aws_security_group.web
id = "sg-xyz"
}
terraform plan -generate-config-out=generated.tf
→ Generate config สำหรับทุก resource ที่ list ไว้
Import เข้า Module
import {
to = module.network.aws_vpc.main
id = "vpc-0a1b2c3d"
}
Import กับ count / for_each
count
import {
to = aws_subnet.public[0]
id = "subnet-aaa"
}
import {
to = aws_subnet.public[1]
id = "subnet-bbb"
}
for_each
import {
to = aws_iam_user.team["alice"]
id = "alice"
}
Import Workflow ทำเป็นขั้นตอน
Common Pitfalls
1. Config ไม่ตรง Reality
หลัง import → terraform plan แสดง diff
→ แก้ config ให้ตรง
2. Computed Attributes
บาง attribute = Terraform คำนวณเอง — ไม่ต้องใส่ใน config:
id,arn,*_idcreated_date,last_modified
3. Default Values
บาง argument มี default ของ provider — ไม่ใส่ก็ได้
4. Tag Drift
ถ้ามี default_tags ใน provider — resource อาจมี tag ที่ไม่ตรง
Bulk Import Tools
มี tool ช่วย import infrastructure ทั้งบ้าน:
Terraformer (by Google)
brew install terraformer
terraformer import aws --resources=vpc,subnet,sg --regions=ap-southeast-1
→ Generate ทั้ง config + state
former2 (web-based)
former2.com — UI ดึง AWS resource → generate Terraform config
CDKTF
CDK for Terraform — เขียน Terraform ด้วย Python/TypeScript + import
Best Practices
✅ DO:
- ใช้ import block (Terraform 1.5+) แทน terraform import CLI
- Review generated.tf อย่างละเอียด
- Plan ก่อน apply เพื่อดู diff
- Import ทีละ component (network ก่อน → compute → app)
❌ DON'T:
- ห้าม import แล้วใช้ทันที (ต้อง verify config ก่อน)
- ห้าม import resource ที่จะ destroy ทันที
- ห้าม import resource ที่ provider ไม่รองรับ (เช็คก่อน)
ตัวอย่าง: Migration Real-World
# Phase 1: Import network
import {
to = aws_vpc.main
id = "vpc-0a1b2c3d"
}
import {
for_each = toset(["subnet-aaa", "subnet-bbb"])
to = aws_subnet.public[index]
id = each.value
}
terraform plan -generate-config-out=network.tf
# Review network.tf
terraform apply
# Phase 2: Import compute
import {
to = aws_instance.web
id = "i-1234567890abcdef0"
}
ทำทีละขั้นตอน — ไม่ import ทุกอย่างพร้อมกัน
สรุป
- Import = นำ existing resource เข้า Terraform state
importblock (1.5+) — แนะนำ-generate-config-outสร้าง config ให้อัตโนมัติ- Resource ID format ต่างกัน — เช็คใน docs
- Tools เช่น Terraformer / former2 / CDKTF ช่วย bulk import
- Plan ก่อน apply เพื่อ verify
ต่อไป → Splitting State Files