Skip to main content

Modify State

state mv, state rm, -replace — เครื่องมือแก้ state ตอน refactor หรือซ่อมแซม

⚠️ ก่อนเริ่ม: Backup!

terraform state pull > backup-$(date +%Y%m%d-%H%M%S).tfstate

ทุก state operation มี risk — backup ก่อนเสมอ

terraform state mv

ย้าย resource ใน state — ไม่แตะ resource จริง

Use Case 1: Rename Resource

# ก่อน
resource "aws_instance" "old_name" { ... }

# หลัง
resource "aws_instance" "new_name" { ... }
# Rename ใน state
terraform state mv aws_instance.old_name aws_instance.new_name

→ Plan แสดง: No changes (ไม่ destroy + recreate)

ถ้าไม่ใช้ state mv → Terraform จะ destroy old + create new!

Use Case 2: Move เข้า Module

# ก่อน
resource "aws_vpc" "main" { ... }

# หลัง
module "network" {
source = "./modules/network"
# ใน module มี resource "aws_vpc" "main"
}
terraform state mv aws_vpc.main module.network.aws_vpc.main

Use Case 3: Move ระหว่าง State Files

# จาก current state → state file อื่น
terraform state mv \
-state-out=../newproject/terraform.tfstate \
aws_instance.web \
aws_instance.web

ใช้ตอน:

  • Split single state เป็น multiple
  • Refactor project structure

Use Case 4: count → for_each

# ก่อน — count
resource "aws_subnet" "public" {
count = 2
...
}

# หลัง — for_each
resource "aws_subnet" "public" {
for_each = toset(["a", "b"])
...
}
terraform state mv 'aws_subnet.public[0]' 'aws_subnet.public["a"]'
terraform state mv 'aws_subnet.public[1]' 'aws_subnet.public["b"]'

terraform state rm

ลบ resource ออกจาก state — ไม่ลบ resource จริง

terraform state rm aws_instance.web

→ Resource ใน cloud ยังอยู่ — Terraform แค่เลิก track

Use Cases

1. Resource ถูกลบ Manual ใน Console

# Resource ใน cloud ถูกลบไปแล้ว — แต่ state ยังมี
$ terraform plan
Error: Resource X not found

# แก้:
terraform state rm aws_instance.deleted

2. ย้าย Manage ไป Tool อื่น

# ตัดสินใจ manage ผ่าน CloudFormation แทน
terraform state rm aws_s3_bucket.legacy

3. Resource ที่ Re-import เข้า Module

terraform state rm aws_vpc.main
# แล้ว import เข้า module

4. Bulk Remove

# ลบทุก resource ใน module
terraform state rm 'module.legacy.*'

# ลบทุก resource ใน count
terraform state rm 'aws_instance.web[*]'

terraform apply -replace

Force replace resource — destroy + recreate ครั้งถัดไป apply

terraform apply -replace="aws_instance.web"

Use Cases

1. Resource Corrupt / Misconfigured

# Instance อยู่ใน weird state — รื้อสร้างใหม่
terraform apply -replace="aws_instance.broken"

2. Force Update Argument ที่ไม่ replace

# user_data ไม่ trigger replace แต่อยาก re-run
terraform apply -replace="aws_instance.web"

3. Multiple Resources

terraform apply \
-replace="aws_instance.web" \
-replace="aws_instance.api"

taint / untaint (deprecated)

ของเก่า:

terraform taint aws_instance.web
terraform apply

ใหม่:

terraform apply -replace="aws_instance.web"

terraform import

นำ existing resource เข้า state (ดูเพิ่ม):

terraform import aws_s3_bucket.existing my-bucket-name

หรือใช้ import block (1.5+):

import {
to = aws_s3_bucket.existing
id = "my-bucket-name"
}

ตัวอย่าง: Refactor Workflow

Scenario: Rename Resource

# ก่อน
resource "aws_instance" "web" { ... }

# หลัง
resource "aws_instance" "frontend" { ... }

❌ ผิด: rename ใน config + apply

- aws_instance.web (destroyed)
+ aws_instance.frontend (created)

→ Downtime!

✅ ถูก:

# 1. Backup
terraform state pull > backup.tfstate

# 2. Rename ใน config
# (edit main.tf — rename "web" → "frontend")

# 3. Update state
terraform state mv aws_instance.web aws_instance.frontend

# 4. Verify
terraform plan
# → No changes (state matches reality + config)

Scenario: Move into Module

# 1. Backup
terraform state pull > backup.tfstate

# 2. Create module + reference
# main.tf:
# module "network" { source = "./modules/network" }

# 3. Move resources
terraform state mv aws_vpc.main module.network.aws_vpc.main
terraform state mv aws_subnet.public module.network.aws_subnet.public

# 4. Verify
terraform plan
# → No changes

Scenario: Re-create Broken Resource

# Instance somehow corrupt
terraform apply -replace="aws_instance.web"

ครั้งถัดไป apply:

Plan: 1 to add, 0 to change, 1 to destroy.
-/+ aws_instance.web (replace, force replacement)

State File ตรงๆ (Advanced — ระวัง!)

terraform state pull

terraform state pull > state.json

→ Download state file

terraform state push

terraform state push state.json

→ Upload state file (overwrite!)

ใช้ pull/push ด้วยความระวัง
  • ❌ Edit state file ตรงๆ ใน editor — corrupt risk
  • ✅ ใช้ tool ที่ generate state JSON อย่าง tfutils
  • ✅ Backup ก่อน push เสมอ

Force Unlock

terraform force-unlock <LOCK_ID>

ใช้ตอน lock ค้าง — ดูใน State Locking

Common Errors

Error: state mv to non-existent target

Error: Invalid target address

→ Resource address ผิด format — ใช้ terraform state list ดู format ที่ถูก

Error: state rm with dependencies

Warning: Resource has dependencies

→ Resource อื่นยังอ้างอิงอยู่ — ลบ dependency ก่อน หรือ rm ทั้งกลุ่ม

Error: Resource not in state

Error: Resource X not found in state

→ Quote address ถ้ามี special characters:

terraform state rm 'aws_subnet.public[0]'   # ใส่ quote!

รวม Commands

Commandหน้าที่Touch Cloud?
state mvRename / move ใน state
state rmRemove จาก state
state pullDownload state
state pushUpload state (overwrite)
apply -replaceForce destroy + recreate
importAdd resource เข้า state❌ (read only)
force-unlockปลด lock

Best Practices

✅ DO:
- Backup state ก่อนทุก operation
- ใช้ state mv แทน rename ในconfig + apply
- Verify ด้วย terraform plan หลัง state operations
- Document state changes ใน commit message

❌ DON'T:
- ห้าม edit state file ตรงๆ
- ห้าม push state ที่ generate manual
- ห้ามใช้ -replace บ่อย — fix root cause แทน
- ห้าม state rm เพราะอยาก reset (resource ยังอยู่ใน cloud!)

สรุป

  • state mv — rename / move resource (ใน state, ไม่แตะ cloud)
  • state rm — remove จาก state (resource จริงยังอยู่)
  • apply -replace — destroy + recreate
  • import — add existing resource เข้า state
  • Backup ทุกครั้งก่อนทำ — state file คือ source of truth!

ต่อไป → Advanced State Commands