--- คู่มือ Remote Backend Terraform สำหรับ AWS S3 + DynamoDB | DevOps Thai
อัปเดตเมื่อ 2026

การจัดการ Terraform State ด้วย Remote Backend

คู่มือ Step-by-Step การตั้งค่า AWS S3 และ DynamoDB เพื่อการทำงานแบบทีม การล็อก state และการจัดการ workspace

AWS S3 DynamoDB Terraform
ทีมผู้พัฒนา Dev1 Dev2 Dev3 ไฟล์ Terraform State terraform.tfstate การจัดเก็บ state แบบ remote AWS S3 my-terraform-state prod/terraform.tfstate DynamoDB terraform-state-lock กลไกการล็อก ล็อก ไดอะแกรม: ทีมผู้พัฒนาหลายคน → Local State → Remote Backend (S3 + DynamoDB)

สิ่งที่ต้องเตรียมพร้อม

  • พื้นฐาน Terraform: เข้าใจพื้นฐานการใช้งาน Terraform CLI
  • สิทธิ์ AWS IAM: สิทธิ์สร้าง S3 Bucket และ DynamoDB Table
  • AWS CLI: ติดตั้งและกำหนดค่า AWS CLI บนเครื่อง
  • ความเข้าใจเรื่อง State: เข้าใจว่า Terraform State คืออะไรและทำหน้าที่อะไร
1

บทนำ: ความสำคัญของ Remote Backend

สำหรับ DevOps Engineer หรือผู้ที่ทำงานกับ Infrastructure as Code (IaC) การจัดการ Terraform State อย่างถูกต้องคือพื้นฐานสำคัญอันดับแรก การเลือกใช้ Backend ที่เหมาะสมส่งผลโดยตรงต่อความสำเร็จของทีมงาน

Terraform State คืออะไร?

Terraform State (เรียกง่ายว่า "state file") คือไฟล์ JSON ที่ Terraform สร้างขึ้นเพื่อเก็บข้อมูลสถานะของ Infrastructure ที่ถูก deploy ทั้งหมด ประกอบด้วย:

  • • รายการทรัพยากร (resources) ทั้งหมดที่ถูกสร้างขึ้น
  • • ค่าและคุณสมบัติของแต่ละทรัพยากร (resource configuration)
  • • การเชื่อมโยงระหว่างทรัพยากร (dependencies)
  • • ข้อมูลเมตา (metadata) เช่น เวลาที่สร้าง, ข้อมูล provider

โดยทั่วไป Terraform จะเก็บ state file ไว้ในโฟลเดอร์ .terraform/ บนเครื่องของคุณ (เรียกว่า Local Backend) ซึ่งมีข้อจำกัดหลายประการเมื่อทำงานเป็นทีม

ข้อเสียของ Local Backend

  • State กระจายไม่เป็นศูนย์กลาง: แต่ละคนมี state file ในเครื่องของตัวเอง → เกิด state drift ถ้าใครไม่ได้ pull ล่าสุด
  • ไม่มีกลไกการล็อก: ถ้า Dev1 และ Dev2 run terraform plan/apply พร้อมกัน → อาจเกิด state corruption!
  • เข้าถึงจากระยะไกลไม่ได้: ไม่ว่าจะใช้ CI/CD, server สำหรับ deployment หรือ remote access
  • เสี่ยงสูญหาย: ถ้าเครื่องเสีย, ลบโฟลเดอร์ .terraform หรือ commit ผิดที่ git โดยไม่ตั้งใจ
  • ไม่สามารถ revert ได้ง่าย: ถ้าไม่มีการสำรองไว้ก่อนหน้า

ข้อดีของ Remote Backend

  • State รวมศูนย์: State อยู่ที่เดียว (S3) → ทุกคนเห็นข้อมูลเดียวกันเสมอ
  • กลไกการล็อกอัตโนมัติ: DynamoDB จะป้องกันไม่ให้รันพร้อมกันหลายคน → ปลอดภัย
  • เข้าถึงจากระยะไกลได้: เข้าถึงจาก CI/CD, server, หรือ remote development ได้
  • สำรองข้อมูลอัตโนมัติ: S3 versioning + Cross-Region Replication → ป้องกัน data loss
  • การทำงานร่วมกัน: ทีมที่ต่างประเทศสามารถทำงานพร้อมกันได้อย่างมีประสิทธิภาพ
  • การติดตามประวัติ: เห็น history ของ state file ผ่าน versioning ใน S3

สรุป

Remote Backend ไม่ใช่แค่ฟีเจอร์ที่ "ดีมี" แต่เป็น ข้อกำหนดสำคัญ สำหรับทีมใดก็ตามที่ใช้ Terraform อย่างจริงจัง เป็นสิ่งที่คุณควรตั้งค่าตั้งแต่วันแรกของโครงการ!

ประเภท Backend ของ Terraform

S3 (AWS)

ที่นิยมมากที่สุด ใช้งานง่าย ผสานกับ DynamoDB ได้ดี

GCS (GCP)

สำหรับผู้ที่ใช้ Google Cloud Platform

Azurerm (Azure)

สำหรับผู้ที่ใช้ Microsoft Azure

Consul

สำหรับผู้ที่มี infrastructure บน Consul

Local (Default)

ใช้เฉพาะกับ testing หรือ project ส่วนตัว

Artifactory

สำหรับ artifact management

S3 + DynamoDB เป็นคู่ที่ดีที่สุดสำหรับ AWS

  • AWS S3 - ใช้เก็บไฟล์ state โดยมี versioning และ encryption รองรับ
  • AWS DynamoDB - ใช้สำหรับ mechanism การล็อก (locking mechanism) เพื่อป้องกันการรันพร้อมกันหลายคน
  • ราคาประหยัด: ใช้ PAY_PER_REQUEST ทำให้ต้นทุนต่ำมากสำหรับการใช้งานปกติ
  • รวมกันได้ดี: โดย Amazon ออกแบบมาให้ทำงานร่วมกันอย่างมีประสิทธิภาพ
2

ขั้นตอนที่ 2: สร้าง AWS Resources

Remote Backend สำหรับ Terraform มีหลายประเภท แต่ที่นิยมที่สุดคือ S3 + DynamoDB โดย S3 เก็บ state file และ DynamoDB ทำหน้าที่เป็นlocking mechanism

Resources ที่ต้องสร้าง

S3 Bucket และ DynamoDB Table

2.1 สร้าง S3 Bucket

Storage for State Files

S3 Bucket เป็นที่เก็บ State File ของ Terraform

  • ชื่อต้องเป็น globally unique (เช่น: mycompany-terraform-state-2026)
  • ควรเปิด versioning เพื่อ rollback ได้
  • ควรเปิด encryption (AES-256 หรือ KMS)
aws s3 mb s3://mycompany-terraform-state-2026

คำอธิบาย:

คำสั่งนี้จะสร้าง S3 bucket ชื่อ mycompany-terraform-state-2026 ใน AWS region ที่กำหนดไว้ใน AWS CLI configuration

2.2 เปิดใช้งาน Versioning

แนะนำให้เปิดใช้งานเสมอ

Versioning ช่วยให้สามารถ rollback ไปยัง state file รุ่นก่อนหน้าได้

aws s3api put-bucket-versioning ^\n --bucket mycompany-terraform-state-2026 ^\n --versioning-configuration Status=Enabled

2.3 สร้าง DynamoDB Table

สำหรับกลไกการล็อก

DynamoDB Table ใช้สำหรับ mechanism การล็อกเพื่อป้องกันไม่ให้ run terraform พร้อมกันหลายคน

  • Primary key: LockID (type: String)
  • ไม่ต้องใช้ secondary index
  • Throughput: ใช้ PAY_PER_REQUEST เพื่อคุ้มค่า
aws dynamodb create-table ^\n --table-name terraform-state-lock ^\n --attribute-definitions AttributeName=LockID,AttributeType=S ^\n --key-schema AttributeName=LockID,KeyType=HASH ^\n --billing-mode PAY_PER_REQUEST

2.4 สร้าง IAM Policy (แนะนำ)

การตั้งค่าสิทธิ์ที่เหมาะสม

สำหรับการใช้งานในทีม ควรสร้าง IAM Policy เพื่อให้สิทธิ์เฉพาะที่จำเป็น:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "TerraformState",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:ListBucket",
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:DeleteItem"
      ],
      "Resource": [
        "arn:aws:s3:::mycompany-terraform-state-2026",
        "arn:aws:s3:::mycompany-terraform-state-2026/*",
        "arn:aws:dynamodb:*:*:table/terraform-state-lock"
      ]
    }
  ]
}
3

ขั้นตอนที่ 3: ตั้งค่า Terraform Backend

หลังจากสร้าง AWS Resources แล้ว ต้องกำหนดค่า backend ใน Terraform configuration ดังนี้

3.1 ตั้งค่า terraform block

เพิ่ม block backend "s3" ใน terraform configuration

terraform {
  backend "s3" {
    bucket = "mycompany-terraform-state-2026"
    key = "prod/terraform.tfstate"
    region = "ap-southeast-1" # ภูมิภาคอาเซียน (เซียงái)
    dynamodb_table = "terraform-state-lock"
    encrypt = true
    acl = "private"
  }
}

คำอธิบาย parameter:

bucket ชื่อ S3 bucket สำหรับเก็บ state file
key เส้นทางของ state file ใน bucket (เช่น prod/terraform.tfstate)
region AWS region ของ S3 bucket
dynamodb_table ชื่อ DynamoDB table สำหรับการล็อก
encrypt เปิดการเข้ารหัสข้อมูลสำหรับ state file
acl Access Control List - สร้าง state แบบ private เสมอ

3.2 ตัวอย่าง configuration เต็มรูปแบบ

โครงสร้างไฟล์หลักที่แนะนำ:

terraform-project/
├── backend.tf # กำหนดค่า remote backend
├── main.tf # ทรัพยากรหลัก
├── variables.tf # ตัวแปร
├── outputs.tf # ผลลัพธ์
└── .terraform/ # โฟลเดอร์ของ Terraform
# backend.tf - กำหนดค่า remote backend

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  
  backend "s3" {
    bucket = "mycompany-terraform-state-2026"
    key = "${path.basename(path.cwd)}/terraform.tfstate"
    region = "ap-southeast-1"
    dynamodb_table = "terraform-state-lock"
    encrypt = true
    acl = "private"
    kms_key_id = "alias/terraform" # ใช้ KMS encryption สำหรับความปลอดภัยเพิ่มเติม
  }
}

ข้อควรรู้:

  • • ไฟล์ backend.tf จะถูกประมวลผลก่อนไฟล์อื่นทั้งหมด
  • • การใช้ path.basename(path.cwd) จะใช้ชื่อโฟลเดอร์เป็น key
  • • การใช้ kms_key_id เพิ่มความปลอดภัยในการเข้ารหัส
  • • อย่า commit ไฟล์ที่มี credentials จริงลง git
4

ตัวอย่างการใช้งานแบบละเอียด

ในบทนี้เราจะมาดูตัวอย่างการใช้งานจริงในสถานการณ์ต่างๆ ที่คุณจะได้เจอเมื่อใช้ Remote Backend จริงๆ

1

ตัวอย่างที่ 1: โครงสร้างพื้นฐานสำหรับ Project เดียว

โครงสร้างที่ใช้สำหรับ project ที่มี environment น้อยและไม่ซับซ้อน

โครงสร้างไฟล์:

web-app/
├── backend.tf
├── main.tf
├── variables.tf
├── outputs.tf
└── .terraform/

ไฟล์: backend.tf

terraform {
  backend "s3" {
    bucket = "mycompany-terraform-state-2026"
    key = "web-app/terraform.tfstate"
    region = "ap-southeast-1"
    dynamodb_table = "terraform-state-lock"
    encrypt = true
    acl = "private"
  }
}

คำสั่งที่ใช้:

# กำหนดค่า credentials (ครั้งเดียว) aws configure
# เริ่มต้น terraform (จะใช้ remote backend) terraform init
# แสดง preview ก่อน deploy terraform plan
# สร้าง infrastructure terraform apply
# ดูรายการ resources terraform state list
2

ตัวอย่างที่ 2: หลาย environments ด้วย Workspace

วิธีที่นิยมมากที่สุดสำหรับทีมที่มี dev/staging/prod

โครงสร้างไฟล์ (ใช้ร่วมกันทั้ง environment):

web-app/
├── backend.tf # กำหนดค่า remote backend
├── main.tf # ทรัพยากร
├── variables.tf # ตัวแปร
├── outputs.tf # ผลลัพธ์
└── .terraform/

ไฟล์: backend.tf

terraform {
  backend "s3" {
    bucket = "mycompany-terraform-state-2026"
    key = "${terraform.workspace}/web-app/terraform.tfstate"
    region = "ap-southeast-1"
    dynamodb_table = "terraform-state-lock"
    encrypt = true
  }
}

Workspace ที่ถูกสร้าง:

dev
state path: dev/web-app/terraform.tfstate
staging
state path: staging/web-app/terraform.tfstate
prod
state path: prod/web-app/terraform.tfstate

คำสั่งที่ใช้:

# ดูว่ามี workspace อะไรบ้าง terraform workspace list
# สร้าง workspace ใหม่ terraform workspace new dev
terraform workspace new staging
terraform workspace new prod
# เปลี่ยน workspace ที่ใช้งาน terraform workspace select dev
# ดู workspace ปัจจุบัน terraform workspace show
# ลบ workspace (ลบ dev ออก) terraform workspace delete dev

ความแตกต่างของ state:

เมื่อใช้ ${terraform.workspace} ใน key:

  • • ทุก environment มี state file แยกกัน (ไม่ปนกัน)
  • • แต่ใช้ทรัพยากรเดียวกัน (code เดียวกัน)
  • • สามารถแยก environment ด้วย variable files ได้

3

ตัวอย่างที่ 3: โครงสร้าง Module-based (Best Practice)

โครงสร้างสำหรับ projects ที่ซับซ้อน ใช้ modules เพื่อ reuse code

โครงสร้างไฟล์:

terraform-project/
├── backend.tf # ใช้ร่วมกันทั้ง project
├── main.tf # หรือ environment-specific main.tf

├── modules/ # ไดเรกทอรี modules
│ ├── vpc/ # VPC Module
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── ec2/ # EC2 Module
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── rds/ # RDS Module
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── s3-bucket/ # S3 Module

└── environments/ # Environment directories
├── dev/ # Development environment
│ ├── main.tf
│ ├── terraform.tfvars
│ └── provider.tf
├── staging/ # Staging environment
│ ├── main.tf
│ └── provider.tf
└── prod/ # Production environment
├── main.tf
├── terraform.tfvars
└── provider.tf

ไฟล์: backend.tf (ใช้ร่วมกันทั้ง project)

terraform {
  backend "s3" {
    bucket = "mycompany-terraform-state-2026"
    key = "${path.module}/terraform.tfstate"
    region = "ap-southeast-1"
    dynamodb_table = "terraform-state-lock"
    encrypt = true
  }
}

หมายเหตุ: ใช้ path.module เพื่อให้แต่ละ module มี state ของตัวเองแยกกันโดยอัตโนมัติ

ตัวอย่างการใช้งาน Module:

เมื่อใช้ path.module เป็น key:

  • • modules/vpc/ จะมี state ที่ vpc/terraform.tfstate
  • • modules/ec2/ จะมี state ที่ ec2/terraform.tfstate
  • • environments/prod/ จะมี state ที่ environments/prod/terraform.tfstate

ข้อดี:

  • • แยก state ของแต่ละ module ทำให้ลบหรือแก้ไข module ได้โดยไม่กระทบ module อื่น
  • • สามารถ deploy แต่ละ module แยกกันได้
  • • ลดขนาดของ state file ทำให้การทำงานเร็วขึ้น

4

ตัวอย่างที่ 4: การ migrate จาก local backend

ขั้นตอนเต็มรูปแบบการย้ายจาก local state ไป remote backend

ข้อควรระวังสำคัญ!

1. สำรอง state file ก่อนทุกครั้ง
2. ไม่ควรทำพร้อมกันหลายคนในทีม
3. ทดสอบใน dev environment ก่อน

ขั้นตอนที่ 1: สำรอง state file

# สำรอง state file เดิม
mkdir -p .terraform/backup

# Copy state file เพื่อสำรอง
cp .terraform/terraform.tfstate .terraform/backup/terraform.tfstate.backup

# เพิ่ม timestamp สำหรับความปลอดภัยเพิ่มเติม
cp .terraform/terraform.tfstate .terraform/backup/terraform.tfstate.$(date +%Y%m%d%H%M%S)

ขั้นตอนที่ 2: เพิ่ม backend config และ run migrate

# Run terraform init เพื่อ initialize backend
terraform init -migrate-state -input=false

# ตอบ 'yes' เมื่อได้รับคำขอให้ copy state

ขั้นตอนที่ 3: ตรวจสอบว่า migrate สำเร็จ

# ดูรายการ resources ที่ถูกจัดการ
terraform state list

# ดูข้อมูล state แบบ summary
terraform state show aws_instance.example

# ตรวจสอบ remote backend (AWS S3)
aws s3 ls s3://mycompany-terraform-state-2026/

ตรวจสอบเพิ่มเติม:

หลังจาก migrate:

  • • ไฟล์ .terraform/terraform.tfstate ควรจะว่างเปล่า (แต่ยังคงไว้สำหรับ reference)
  • • ไฟล์ state จริงอยู่ใน S3 bucket แล้ว
  • • terraform plan จะเชื่อมต่อ state จากremote
  • • ทุกคนในทีมสามารถเข้าถึง state เดียวกันได้

5

ขั้นตอนที่ 5: การจัดการ Workspace

Workspace เป็นฟีเจอร์หนึ่งของ Terraform ที่ช่วยให้คุณสามารถสร้าง environment ต่างๆ ภายใน module เดียวกันโดยไม่ต้องคัดลอกโค้ด เหมาะสำหรับการพัฒนาและทดสอบ

Workspace vs Environment Directories

Workspace: ใช้โค้ดเดียวกัน แต่มี state แยกกัน เหมาะสำหรับการทดสอบและพัฒนาระยะสั้น
Environment Directories: ใช้โค้ดเดียวกันแต่แยกตามโฟลเดอร์ สามารถมี configuration ต่างกันได้ เหมาะสำหรับ production และ environment ที่ซับซ้อน

5.1 คำสั่งที่จำเป็นสำหรับ Workspace

คำสั่งพื้นฐาน:

terraform workspace list # ดูรายการ workspace
terraform workspace show # ดู workspace ปัจจุบัน
terraform workspace new <name> # สร้าง workspace ใหม่
terraform workspace select <name> # เปลี่ยน workspace
terraform workspace delete <name> # ลบ workspace (ต้องย้ายก่อน)

ตัวอย่างการใช้งาน:

# สร้าง workspace สำหรับ dev terraform workspace new development
# สร้าง workspace สำหรับ staging terraform workspace new staging
# สร้าง workspace สำหรับ production terraform workspace new production
# ไปที่ dev workspace terraform workspace select development

5.2 การใช้ตัวแปรworkspace ใน Terraform

# ตัวอย่าง: กำหนดค่าต่างกันตาม workspace

# variables.tf
variable "environment" {
  description = "Environment name"
  default = "unknown"
}

# main.tf - ใช้ตัวแปร
locals {
  environment = terraform.workspace
  is_production = terraform.workspace == "production"
  resource_prefix = terraform.workspace == "production" ? "prod" : terraform.workspace
}

resource "aws_instance" "example" {
  instance_type = local.is_production ? "t3.large" : "t3.micro"
  tags = {
    Name = local.resource_prefix "-web-server"
    Environment = local.environment
  }
}

5.3 การรวม Workspace กับ Variable Files

การใช้ variable files แยกตาม environment:

environments/
├── dev.tfvars
├── staging.tfvars
└── prod.tfvars
# dev.tfvars - ค่าสำหรับ development
instance_type = "t3.micro"
replica_count = 1
enable_monitoring = false

# prod.tfvars - ค่าสำหรับ production
instance_type = "t3.large"
replica_count = 3
enable_monitoring = true

วิธีใช้งาน:

terraform workspace select prod
terraform apply -var-file=environments/prod.tfvars

6

ขั้นตอนที่ 6: การล็อก State และ Best Practices

DynamoDB table ที่เราสร้างทำหน้าที่เป็นกลไกการล็อก (locking mechanism) ช่วยป้องกันไม่ให้คนหลายคน run terraform plan/apply พร้อมกัน ซึ่งอาจทำให้ state consistency

กลไกการล็อกทำงานอย่างไร:

1

เมื่อเริ่ม terraform plan/apply:

Terraform จะพยายามเขียน record ลง DynamoDB table ด้วย key = "LockID"

2

ถ้าไม่มี record:

การล็อกสำเร็จ terraform ทำงานต่อได้

3

ถ้ามี record อยู่แล้ว:

Terraform จะ error พร้อมแสดง Lock ID และข้อมูลผู้ล็อก

4

เมื่อทำงานเสร็จ:

Terraform จะลบ record ออกจาก DynamoDB (unlock)

Best Practices

  • ตั้ง lock timeout: ตั้ง timeout เพื่อป้องกัน deadlocks
  • ป้องกันการล็อกค้าง: ใช้ DynamoDB TTL (Time To Live)
  • ใช้ workspace แยกตาม environment: ป้องกันการชนกันของ state
  • เปิด S3 bucket versioning: สำรอง state file อัตโนมัติ
  • สำรอง state file ภายนอก: สำรองไป S3 cross-region replication
  • สร้าง IAM policy ที่เหมาะสม: ปฏิบัติตามหลัก least privilege
  • ไม่แก้ state file โดยตรง: ใช้คำสั่งที่ Terraform จัดให้

สิ่งที่ควรหลีกเลี่ยง

  • อย่า commit terraform.tfstate ลง git: มีข้อมูล sensitive
  • อย่า run terraform พร้อมกันหลายคน: อาจเกิด state corruption
  • อย่าแก้ state file โดยตรง: อาจทำให้ข้อมูลเสียหาย
  • อย่าลืม DynamoDB table: ไม่งั้นไม่มี locking!
  • อย่าลบ state file โดยไม่ตั้งใจ: ต้องมีสำรองไว้ก่อน
  • อย่าใช้ default namespace ใน CI/CD: แยก environment ให้ชัดเจน
  • อย่าใช้ terraform force-unlock เหตุผลที่ไม่จำเป็น: อาจเกิดปัญหา

6.1 วิธีตรวจสอบ Lock และ Force Unlock

ตรวจสอบสถานะ lock ปัจจุบัน:

# ดูสถานะ lock ของ DynamoDB
aws dynamodb get-item \\
  --table-name terraform-state-lock \\
  --key '{"LockID": {"S": "terraform.tfstate"}}'

Force Unlock (ในกรณีที่ lock ค้าง):

# คำสั่ง force unlock
terraform force-unlock LOCK_ID

# หรือลบโดยตรงจาก DynamoDB
aws dynamodb delete-item \\
  --table-name terraform-state-lock \\
  --key '{"LockID": {"S": "terraform.tfstate"}}'

คำเตือน:

การใช้ force unlock ควรทำเมื่อ แน่ใจ ว่า process ที่ล็อกได้จบไปแล้วหรือค้างจริงๆ เท่านั้น มิเช่นนั้นอาจทำให้ state ไม่สอดคล้องกัน

7

ขั้นตอนที่ 7: การแก้ไขปัญหา (Troubleshooting)

คำถามที่พบบ่อย (FAQ):

1

ข้อความ "Backend successfully initialized" คืออะไร?

หมายความว่า terraform init run สำเร็จและ backend configuration ถูก initialize แล้ว จากนี้ไป terraform จะใช้ remote state แทน local state

# Output ที่ควรเห็น:
Backend initialized!
Terraform has been successfully initialized.
You may now begin working with Terraform.
2

Error: "NoDefaultCredentials"

สาเหตุ: AWS CLI ยังไม่ได้ตั้งค่า credentials หรือ IAM role ไม่เพียงพอ

# วิธีแก้:
# 1. ตั้งค่า AWS CLI credentials
aws configure

# 2. หรือใช้ environment variables
export AWS_ACCESS_KEY_ID=your_access_key
export AWS_SECRET_ACCESS_KEY=your_secret_key
export AWS_DEFAULT_REGION=ap-southeast-1

# 3. ตรวจสอบ credentials ปัจจุบัน
aws sts get-caller-identity
3

Error: "AccessDenied"

สาเหตุ: IAM policy ไม่มีสิทธิ์เข้าถึง S3 หรือ DynamoDB

# ตรวจสอบสิทธิ์:
aws s3 ls s3://mycompany-terraform-state-2026

# ทดสอบ DynamoDB
aws dynamodb describe-table --table-name terraform-state-lock
4

State file ขนาดใหญ่จะทำให้ slow ไหม?

คำตอบ: ไม่ครับ! S3 ถูกออกแบบมาให้ scalable มากสำหรับ state file ขนาด several MB ถือว่าเล็กมาก และ DynamoDB มี latency ต่ำมาก

ถ้า state ของคุณใหญ่จริง (100MB+) พิจารณาใช้ terraform -chdir หรือ split เป็น multiple state files

5

สามารถใช้ backend อื่นได้ไหม?

คำตอบ: ได้ครับ! Terraform backend มีหลายประเภท:

gcs - Google Cloud Storage
azurerm - Azure Blob Storage
consul - Consul
http - HTTP server
ssh - SSH server
local - Default
6

Error: "Duplicate workspace name"

สาเหตุ: มี workspace ชื่อนี้อยู่แล้ว

# วิธีแก้:
# 1. ตรวจสอบ workspace ที่มีอยู่
terraform workspace list

# 2. เลือก workspace ที่มีอยู่ หรือ ลบออกก่อน
terraform workspace delete <name>
7

Cannot find backend configuration

สาเหตุ: ไม่มี backend.tf หรือ backend block ไม่ถูกต้อง

# ตรวจสอบว่า:
# 1. มี terraform block อยู่ในไฟล์ any .tf
# 2. backend block อยู่ภายใน terraform block
# 3. รัน terraform init หลังจากแก้ไข

# โครงสร้างที่ถูกต้อง:
terraform {
  backend "s3" { ... }
}

# โครงสร้างที่ผิด:
backend "s3" { ... } # ผิด! ต้องอยู่ใน terraform block
8

State mismatch error

สาเหตุ: State file ท้องถิ่นกับ remote state ไม่ตรงกัน

# วิธีแก้:
# 1. สำรอง state ปัจจุบัน
cp .terraform/terraform.tfstate .terraform/terraform.tfstate.backup

# 2. ดึง state จาก remote
terraform state pull > .terraform/terraform.tfstate

# 3. พยายามอัปเดต
terraform plan

ข้อความ error ที่พบบ่อย:

Error: Failed to read state

ไม่สามารถอ่าน state ได้ - ตรวจสอบ S3 bucket และ key

Error: Lock did not return a unique ID

DynamoDB มีปัญหา - ลอง force unlock ก่อน

AccessDenied: Access Denied

สิทธิ์ IAM ไม่เพียงพอ - ตรวจสอบ policy

Backend configuration changed

มีการเปลี่ยนแปลง backend - รัน terraform init -migrate-state

8

ขั้นตอนที่ 8: การผสานรวม CI/CD

เมื่อใช้ Remote Backend แล้ว การผสานรวมกับ CI/CD จะทำให้สามารถ deploy ได้อัตโนมัติอย่างปลอดภัย

8.1 ตัวอย่าง GitHub Actions

ไฟล์: .github/workflows/terraform.yml

name: Terraform CI/CD

on:
  push:
    branches: ["main", "staging"]
  pull_request:
    branches: ["main"]

jobs:
  terraform:
    name: "Terraform Deployment"
    runs-on: "ubuntu-latest"
    steps:
      - -uses: "actions/checkout@v4"

      - name: "Set up Terraform"
        uses: "hashicorp/setup-terraform@v3"

      - name: "Configure AWS credentials"
        uses: "aws-actions/configure-aws-credentials@v4"
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: "ap-southeast-1"

      - name: "Initialize Terraform"
        run: "terraform init"

      - name: "Terraform Plan"
        run: "terraform plan"

      - name: "Terraform Apply"
        if: "github.ref == 'refs/heads/main'"
        run: "terraform apply -auto-approve"

8.2 ตัวอย่าง Jenkins Pipeline

ไฟล์: Jenkinsfile

pipeline {
  agent any

  environment {
    AWS_ACCESS_KEY_ID = credentials('aws-access-key-id')
    AWS_SECRET_ACCESS_KEY = credentials('aws-secret-access-key')
    AWS_REGION = 'ap-southeast-1'
  }

  stages {
    stage('Terraform Init') {
      steps {
        sh 'terraform init'
      }
    }

    stage('Terraform Plan') {
      steps {
        sh 'terraform plan -input=false'
      }
    }

    stage('Terraform Apply') {
      when {
        branch 'main'
      }
      steps {
        sh 'terraform apply -auto-approve -input=false'
      }
    }
  }
}

Best Practices สำหรับ CI/CD:

  • • ใช้ secret management สำหรับ AWS credentials (ไม่ commit ลง git)
  • • ตั้ง webhook เพื่อ deploy อัตโนมัติเมื่อ push ไป main branch
  • • ใช้ protected branches เพื่อป้องกันการ merge โดยไม่ได้รับอนุญาต
  • • ตั้ง approvers สำหรับ production deployment
  • • สำรอง state ก่อน deploy production (ใช้ Terraform cloud หรือ manual)
  • • ใช้ workspace หรือ directory แยกตาม environment

สรุป

การตั้งค่า Remote Backend ด้วย AWS S3 และ DynamoDB เป็นหนึ่งในสิ่งสำคัญอันดับต้นๆ สำหรับทีม DevOps ที่ใช้ Terraform อย่างจริงจัง

สิ่งที่ได้:

  • • State file รวมศูนย์และสำรองอัตโนมัติ
  • • กลไกการล็อกป้องกันการรันพร้อมกันหลายคน
  • • Workspace support แยก environment ได้ง่าย
  • • การทำงานร่วมกันของทีมที่ดีขึ้น
  • • History ของ state ผ่าน versioning

Key Components:

  • • S3 Bucket: เก็บ state file
  • • DynamoDB: สำหรับกลไกการล็อก
  • • AWS IAM: ต้องมีสิทธิ์ถูกต้อง
  • • Workspace: ใช้แยก environment

ขอบคุณที่อ่านจนจบ! หวังว่าจะได้ความรู้และนำไปใช้ได้จริงครับ