Terraform Debugging: ใช้ Log, Graph และ State Inspection วิเคราะห์ปัญหา

เมื่อ apply ล้มเหลวหรือพฤติกรรมไม่เป็นอย่างที่คาดไว้ การ debug ที่มีประสิทธิภาพต้องอาศัยทั้ง log verbose, graph แสดงความสัมพันธ์ของ resource และคำสั่งช่วย inspect state ที่เหมาะสม — บทความนี้รวมเครื่องมือและเทคนิคหลักที่ใช้วิเคราะห์ปัญหาได้อย่างรวดเร็ว

เปิด Log Verbose ด้วย TF_LOG

ตัวแปร environment TF_LOG ควบคุมระดับ log output เรียงจากละเอียดมากไปน้อย ได้แก่ TRACE, DEBUG, INFO, WARN, ERROR

export TF_LOG=DEBUG
export TF_LOG_PATH=./terraform.log
terraform apply

ระดับ TRACE แสดงทั้ง HTTP request/response ระหว่าง core กับ provider API — เหมาะกับการ debug ปัญหาเกี่ยวกับ API call ที่ตอบกลับผิดปกติ หรือ permission ที่ขาดหาย

สามารถแยก log ของ core กับ provider ด้วย TF_LOG_CORE และ TF_LOG_PROVIDER เพื่อลด noise เมื่อโฟกัสเฉพาะส่วน

export TF_LOG_CORE=INFO
export TF_LOG_PROVIDER=TRACE
terraform plan

การใช้คำสั่ง terraform graph

คำสั่ง terraform graph สร้างผลลัพธ์เป็นรูปแบบ DOT ซึ่งนำไป render เป็นภาพ dependency graph ระหว่าง resource ผ่าน Graphviz

terraform graph | dot -Tpng > graph.png
terraform graph | dot -Tsvg > graph.svg

ภาพที่ได้จะเห็นว่า resource ใดพึ่งพา resource ใดบ้าง เหมาะกับการตรวจ circular dependency, การเข้าใจลำดับ apply, และการวิเคราะห์ว่าทำไม plan ถึงรายงานการเปลี่ยนแปลงนอกเหนือคาด

กำหนด type ของ graph ได้ด้วย flag -type เพื่อเลือกดูเฉพาะ plan, apply, หรือ destroy

terraform graph -type=plan | dot -Tpng > plan_graph.png
terraform graph -type=apply | dot -Tpng > apply_graph.png
terraform graph -type=plan-destroy | dot -Tpng > destroy_graph.png

Inspect State ด้วย terraform show และ state list

เมื่อสงสัยว่า state ไม่ตรงความจริง ใช้ terraform state list ดู resource ทั้งหมดใน state และ terraform state show ดูรายละเอียด resource ตัวใดตัวหนึ่ง

terraform state list
# aws_vpc.main
# aws_subnet.public[0]
# aws_subnet.public[1]

terraform state show aws_subnet.public[0]
# ดูรายละเอียด attribute ทั้งหมด

คำสั่ง terraform show -json ส่งออก state เป็น JSON นำไปวิเคราะห์ต่อด้วยเครื่องมือเช่น jq ได้สะดวก

terraform show -json | jq '.values.root_module.resources[] | {address, type}'

Plan File สำหรับวิเคราะห์

บันทึก plan ลงไฟล์แล้วแปลงเป็น JSON เพื่อตรวจรายละเอียดการเปลี่ยนแปลง

terraform plan -out=tfplan
terraform show -json tfplan > plan.json

jq '.resource_changes[] | {address, actions: .change.actions}' plan.json

วิธีนี้เหมาะกับ CI/CD เพื่อตรวจว่าไม่มี resource ถูก destroy โดยไม่ตั้งใจ หรือมี resource จำนวนมากผิดปกติที่ต้องสร้างใหม่

Terraform Console สำหรับทดลอง Expression

เมื่อไม่แน่ใจว่า expression ใน locals, variable, หรือ for_each ให้ผลลัพธ์อย่างไร ใช้ terraform console ทดลองได้ทันทีโดยไม่ต้อง apply

terraform console
> var.environments
["dev", "staging", "prod"]

> [for env in var.environments : upper(env)]
["DEV", "STAGING", "PROD"]

> aws_instance.web[0].private_ip
"10.0.1.23"

ปัญหาที่พบบ่อยและวิธีวิเคราะห์

  • State lock timeout — เปิด TRACE log ดู log ของ backend (S3/DynamoDB) ว่า item lock อยู่ที่ใคร ใช้ terraform force-unlock LOCK_ID ปลด lock เมื่อแน่ใจว่าไม่มี run อื่นทำงานอยู่
  • Provider not found — ตรวจ required_providers block และ run terraform init -upgrade ให้ download provider version ที่ถูกต้อง
  • Circular dependency — ดูผลจาก terraform graph หา cycle ระหว่าง resource แก้ด้วยการยก computed attribute ออกเป็น data source หรือใช้ depends_on ให้ถูกต้อง
  • API rate limit — เพิ่ม -parallelism=5 ลด concurrent call, หรือใช้ retry logic ใน provider config
  • Resource drift — เทียบ terraform plan กับ cloud console หาก drift เกิดจาก external change ให้ apply import หรือ refactor ให้ ignore

Visualize ด้วยเครื่องมือภายนอก

เครื่องมือ third-party เช่น terraform-visual, rover, inframap ช่วยเปลี่ยน plan JSON เป็นภาพที่อ่านง่ายกว่า DOT graph ดั้งเดิม — เหมาะกับการนำเสนอทีมหรือตรวจ review

npm install -g @mhlabs/terraform-visual-cli
terraform plan -out=plan.out
terraform show -json plan.out > plan.json
terraform-visual --plan plan.json

Debug Module ซ้อนกัน

เมื่อใช้ module หลายระดับ address ของ resource ใน log จะยาวมาก เช่น module.vpc.module.subnet.aws_subnet.main[0] — ใช้ terraform state list | grep module.vpc กรอง resource เฉพาะ module ที่สนใจ จะช่วยลดความสับสน

หากต้องการ target เฉพาะ resource ใน plan/apply ใช้ flag -target

terraform plan -target=module.vpc.aws_subnet.public[0]
terraform apply -target=module.eks

คำเตือน — -target ไม่แนะนำให้ใช้ใน production ปกติเพราะข้าม dependency detection อาจทำให้ state ไม่ consistent ใช้เฉพาะเวลาแก้ไขปัญหาจริง ๆ

สรุป

การ debug โค้ด infrastructure ต้องอาศัยทั้งการอ่าน log และการมองเห็นโครงสร้าง dependency ของ resource — เครื่องมือหลักที่ตัว IaC มีให้ เช่น TF_LOG, terraform graph, terraform show ช่วยให้สามารถค้นหา root cause ได้เร็วกว่าการเดาจากข้อความ error อย่างเดียว

การรวม plan file ร่วมกับ jq และเครื่องมือ visualization เพิ่มเติมจะยกระดับ workflow การตรวจสอบในทีม — ทำให้การ review PR ด้าน infrastructure ปลอดภัยขึ้นและลดโอกาสที่การเปลี่ยนแปลงจะส่งผลกระทบโดยไม่ทันตั้งตัว