Lab: ตั้งค่า Remote State บน S3
📖 text • 20 นาทีLab: ตั้งค่า Remote State บน S3
สิ่งที่ต้องมี: Terraform + AWS Credentials ตั้งค่าแล้ว
เป้าหมาย
- สร้าง S3 bucket + DynamoDB table สำหรับเก็บ state
- ย้าย local state ไป remote
- ทดสอบว่า remote state ทำงานถูกต้อง
Part 1: สร้าง Backend Infrastructure
Step 1: สร้างโปรเจค
mkdir terraform-state-lab && cd terraform-state-lab
mkdir -p backend app
โครงสร้าง:
terraform-state-lab/
├── backend/ ← สร้าง S3 + DynamoDB (state ของตัวเองเก็บ local)
└── app/ ← โปรเจคจริง (ใช้ remote state)
Step 2: สร้าง Backend Resources
สร้างไฟล์ backend/main.tf:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-southeast-1"
}
resource "random_id" "suffix" {
byte_length = 4
}
# S3 Bucket สำหรับเก็บ state
resource "aws_s3_bucket" "state" {
bucket = "tf-state-lab-${random_id.suffix.hex}"
tags = {
Name = "Terraform State"
ManagedBy = "terraform"
}
}
# เปิด versioning
resource "aws_s3_bucket_versioning" "state" {
bucket = aws_s3_bucket.state.id
versioning_configuration {
status = "Enabled"
}
}
# เปิด encryption
resource "aws_s3_bucket_server_side_encryption_configuration" "state" {
bucket = aws_s3_bucket.state.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
# Block public access
resource "aws_s3_bucket_public_access_block" "state" {
bucket = aws_s3_bucket.state.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# DynamoDB Table สำหรับ state locking
resource "aws_dynamodb_table" "locks" {
name = "tf-state-locks-${random_id.suffix.hex}"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
tags = {
Name = "Terraform State Locks"
ManagedBy = "terraform"
}
}
# Output ค่าที่ต้องใช้ในโปรเจคอื่น
output "state_bucket" {
value = aws_s3_bucket.state.bucket
description = "ชื่อ S3 bucket สำหรับเก็บ state"
}
output "dynamodb_table" {
value = aws_dynamodb_table.locks.name
description = "ชื่อ DynamoDB table สำหรับ locking"
}
Step 3: Apply Backend
cd backend
terraform init
terraform apply
พิมพ์ yes — จดค่า output ไว้:
state_bucket = "tf-state-lab-a1b2c3d4"
dynamodb_table = "tf-state-locks-a1b2c3d4"
จด output ไว้! จะใช้ใน Part 2
Part 2: ใช้ Remote State
Step 4: สร้าง App Project ด้วย Local State ก่อน
สร้างไฟล์ app/main.tf:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-southeast-1"
}
resource "aws_s3_bucket" "app_data" {
bucket = "tf-lab-app-data-${formatdate("YYYYMMDDhhmmss", timestamp())}"
tags = {
Name = "App Data"
Environment = "lab"
ManagedBy = "terraform"
}
}
output "app_bucket_name" {
value = aws_s3_bucket.app_data.bucket
}
cd ../app
terraform init
terraform apply -auto-approve
ตอนนี้ state อยู่ local:
ls -la terraform.tfstate
# -rw-r--r-- terraform.tfstate ← อยู่บนเครื่อง
Step 5: Migrate ไป Remote State
เพิ่ม backend configuration ใน app/main.tf:
terraform {
backend "s3" {
bucket = "tf-state-lab-XXXXXXXX" # ← ใส่ค่าจาก output
key = "app/terraform.tfstate"
region = "ap-southeast-1"
dynamodb_table = "tf-state-locks-XXXXXXXX" # ← ใส่ค่าจาก output
encrypt = true
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
แทนที่
XXXXXXXXด้วยค่าจริงจาก Part 1 output
Step 6: Init เพื่อ Migrate
terraform init
Initializing the backend...
Do you want to copy existing state to the new backend?
Enter a value: yes
Successfully configured the backend "s3"!
Step 7: ตรวจสอบ
# state ยังทำงานปกติ
terraform plan
ควรเห็น No changes. — state ย้ายสำเร็จ ข้อมูลครบ
# local state ไม่มีข้อมูลแล้ว
cat terraform.tfstate
{
"version": 3,
"backend": {
"type": "s3",
...
}
}
Local state เหลือแค่ backend config — ข้อมูล resource อยู่บน S3 แล้ว
Step 8: ตรวจสอบบน S3
aws s3 ls s3://tf-state-lab-XXXXXXXX/app/
terraform.tfstate
Part 3: Cleanup
ลบ App Resources
cd ../app
terraform destroy -auto-approve
ลบ Backend Resources
cd ../backend
# ต้องล้าง S3 bucket ก่อน (ไม่สามารถลบ bucket ที่มีไฟล์ได้)
aws s3 rm s3://tf-state-lab-XXXXXXXX --recursive
terraform destroy -auto-approve
ลบ Lab Directory
cd ../..
rm -rf terraform-state-lab
สิ่งที่ได้เรียนรู้
| Concept | สิ่งที่ฝึก |
|---|---|
| S3 Backend | สร้าง S3 + DynamoDB สำหรับเก็บ state |
| Security | Versioning, encryption, block public access |
| Migration | ย้ายจาก local state ไป remote state |
| State Locking | DynamoDB ป้องกัน concurrent access |
| Verification | ตรวจสอบว่า remote state ทำงานถูกต้อง |
สรุป
คุณเพิ่งตั้งค่า production-grade remote state:
- S3 เก็บ state file อย่างปลอดภัย (encrypted + versioned)
- DynamoDB ป้องกันไม่ให้ 2 คน apply พร้อมกัน
- Migration ย้ายจาก local ไป remote ง่ายๆ ด้วย
terraform init
บทถัดไปเราจะเรียนรู้เรื่อง Variables และ Outputs