โครงสร้างพื้นฐานในรูปแบบโค้ด (IaC ด้วย Terraform)
3.3 Infrastructure as Code (IaC) ด้วย Terraform
การตั้งค่าโครงสร้างระบบฐานข้อมูล คลัสเตอร์วิเคราะห์ และสิทธิ์คีย์ควบคุมหน้าเว็บบอร์ดผ่านการกดแผง Console ด้วยมือเสี่ยงต่อการตั้งค่าตกหล่นและยากต่อการกู้คืน ระบบองค์กรจึงต้องการกำหนดค่าทรัพยากรด้วยโค้ดคุณลักษณะ Declarative
Technical Architecture Diagram
1. การประกาศคุณลักษณะระบบแบบระบุปลายทาง vs. การสั่งงานลำดับขั้น
Learning Progression
- [BASIC] ปูพื้นฐานภาษาเข้าใจง่าย - เข้าใจคอนเซปต์ภาพรวมและการแก้ปัญหาเบื้องต้น
- [INTERMEDIATE] โค้ด/คอนฟิกไวยากรณ์จริง - การเขียนโค้ดเพื่อใช้งานจริงในระบบ
- [PROFESSIONAL] Under-the-hood & Performance/FinOps - กลไกเบื้องลึกและการรีดประสิทธิภาพ
Real-World Enterprise Scenario
เคสระบบการเงิน/Big Tech: การรองรับ Transaction จำนวนมหาศาลต่อวินาทีพร้อมประกัน Data Integrity สูงสุด โดยใช้สถาปัตยกรรมที่ยืดหยุ่นและการมอนิเตอร์ระดับสูง
ทฤษฎีและกลไกการทำงาน (How it works): การเขียนโค้ดควบคุมโครงสร้างพื้นฐานมี 2 แนวคิดหลัก: - **Imperative (สั่งการเป็นขั้นตอน เช่น Shell/AWS CLI)**: ระบุวิธีการทำเป็นสเต็ป เช่น "สร้าง VM -> ตั้งค่าเครือข่าย -> แนบดิสก์" หากรันสคริปต์ซ้ำอาจเกิดข้อผิดพลาดเนื่องจากเครื่องสร้างทับซ้อน - **Declarative (ระบุผลลัพธ์สุดท้าย เช่น Terraform HCL)**: ระบุผลลัพธ์ปลายทางที่ต้องการ เช่น "ต้องการ S3 Bucket 1 ใบที่มีคุณสมบัตินี้" ระบบจะอ่านค่าปัจจุบันเปรียบเทียบกับโค้ดเพื่อสร้างแผนการปรับปรุง (Execution Plan) เฉพาะส่วนต่างเท่านั้น ช่วยให้ทำซ้ำ (Idempotency) ได้อย่างมั่นคง
# Declarative infrastructure definition in Terraform HCL
resource "aws_s3_bucket" "datalake_bronze" {
bucket = "pipecraft-raw-datalake-prod"
tags = {
Environment = "Production"
ManagedBy = "Terraform"
}
}
Use Case ในชีวิตจริง (Real-world Scenario): ความต้องการสร้าง Sandbox สภาพแวดล้อมเพื่อทดสอบระบบจำลอง วิศวกรข้อมูลสามารถสั่งรันโค้ด HCL เดิมเพื่อจำลองระบบคลังและสิทธิ์ขึ้นใหม่ได้ภายในเวลาไม่กี่วินาทีอย่างแม่นยำ
ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การลบโค้ดทรัพยากรออกโดยไม่ระมัดระวัง อาจทำให้ Terraform สั่งทำลายและลบข้อมูลตู้เก็บข้อมูลจริงในฝั่งคลาวด์ทิ้ง แก้ไขโดยเปิดใช้งานคุณสมบัติป้องกันลบตาราง `prevent_destroy = true` ในการกำหนดสเปคทรัพยากร
2. สเตทไฟล์และการจัดเก็บแบบส่วนกลาง (Terraform State & S3 Remote Backend)
ทฤษฎีและกลไกการทำงาน (How it works): Terraform จะคุมแผนความเปลี่ยนแปลงและจับคู่รหัสโค้ดกับเครื่องเซิร์ฟเวอร์จริงผ่านไฟล์ประวัติสถานะ State File (`terraform.tfstate`) ในการพัฒนาเป็นทีม การแยกเก็บไฟล์นี้ไว้ในเครื่องคอมพิวเตอร์ส่วนตัวจะสร้างปัญหาการซิงก์และข้อมูลไม่ตรงกันอย่างรุนแรง ระบบระดับโปรดักชันจึงย้ายไปจัดเก็บในเซิร์ฟเวอร์คลาวด์ส่วนกลาง **S3 Remote Backend** เพื่อแชร์ข้อมูลสถานะล่าสุดระหว่างเพื่อนร่วมงานในทีมแบบอัตโนมัติ
# Configuration template for remote backend state management
terraform {
backend "s3" {
bucket = "pipecraft-global-tfstate"
key = "prod/analytics_infrastructure.tfstate"
region = "ap-southeast-1"
encrypt = true
}
}
Use Case ในชีวิตจริง (Real-world Scenario): ทีมพัฒนาคลาวด์ 5 คนทำงานอัปเดตระบบพร้อมกัน สเตทไฟล์บน S3 ช่วยให้ทรานแซกชันการเขียนของทุกคนรับทราบประวัติล่าสุดตรงกันอย่างสมบูรณ์ ไร้ปัญหาประวัติระบบงานคลาดเคลื่อน
ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): สเตทไฟล์ของ Terraform จัดเก็บค่าตัวแปรในรูปข้อความธรรมดา (Plain text) ซึ่งอาจมีข้อมูลรหัสลับ (Database Password, API Keys) รั่วไหล แก้ไขโดยล็อกสิทธิ์การอ่านโฟลเดอร์ S3 Backend นี้ให้เข้าถึงได้เฉพาะระบบอัตโนมัติ และเปิดใช้ฟังก์ชันเข้ารหัสระดับดิสก์ (KMS Encryption)
3. ระบบการล็อกสถานะและป้องกันการเขียนพร้อมกันด้วย DynamoDB
ทฤษฎีและกลไกการทำงาน (How it works): แม้จะเก็บสเตทไฟล์ไว้บน S3 แต่หากมีวิศวกร 2 คนสั่งรันคำสั่ง `terraform apply` แก้ไขระบบพร้อมกัน สเตทไฟล์จะโดนเขียนทับจนเสียหาย ทางแก้คือเชื่อมต่อกลไก **State Locking** ร่วมกับฐานข้อมูล NoSQL อย่าง **DynamoDB** เมื่อมีการเริ่มคำสั่งแก้ไขระบบ ระบบจะสร้างคีย์ล็อก (Lock ID) บันทึกเข้าไปในตาราง DynamoDB ทันที โปรเซสอื่นจะถูกขัดขวางไม่ให้อนุญาตแก้ไขจนกว่าโปรเซสแรกจะกดยืนยันเซฟเสร็จและลบคีย์ล็อกออก
# Remote backend setting with DynamoDB state locking enabled
terraform {
backend "s3" {
bucket = "pipecraft-global-tfstate"
key = "prod/analytics_infrastructure.tfstate"
region = "ap-southeast-1"
dynamodb_table = "pipecraft-state-locks-db" -- DynamoDB table used for lock checks
}
}
Use Case ในชีวิตจริง (Real-world Scenario): ระหว่างที่โปรแกรมอัตโนมัติ (CI/CD) กำลังรันอัปเดตคลัสเตอร์ Redshift บน AWS ระบบ DynamoDB จะล็อกสถานะไว้ หากวิศวกรอีกคนรันคำสั่งบังคับแก้ผ่านเครื่องตัวเองพร้อมกัน ตัวโปรแกรมจะเตือนเออเร่อ "State locked" เพื่อรักษาเสถียรภาพระบบงาน
ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): หากอินเทอร์เน็ตหลุดระหว่างรันโปรเซส apply คีย์ล็อกอาจค้างในตาราง DynamoDB แม้โปรเซสจะจบไปแล้ว ส่งผลให้ไม่สามารถรันครั้งถัดไปได้ แก้ไขโดยใช้คำสั่งตรวจสอบและเคลียร์ล็อกด้วยมืออย่างระมัดระวัง: `terraform force-unlock
4. โครงสร้างโมดูล (Terraform Modules) เพื่อสร้างพิมพ์เขียวระบบข้อมูลแชร์ซ้ำ
ทฤษฎีและกลไกการทำงาน (How it works): เพื่อหลีกเลี่ยงการเขียนโค้ดซ้ำซาก (DRY - Don't Repeat Yourself) Terraform นำเสนอระบบ **Modules** ซึ่งช่วยให้เราสามารถนำกลุ่มทรัพยากรที่ต้องใช้งานร่วมกันบ่อยๆ (เช่น การบิวด์ S3 + สิทธิ์ IAM + การต่อ NAT) มาห่อรวมเป็นแพ็กเกจพิมพ์เขียวกลาง จากนั้นจึงเรียกใช้งานผ่านการส่งผ่านตัวแปรแฝงอินพุตพารามิเตอร์
# Calling a reusable module to instantiate a standard data lake environment
module "analytics_datalake" {
source = "./modules/secure_datalake"
environment = "dev"
bucket_name = "pipecraft-dev-raw-storage"
}
Use Case ในชีวิตจริง (Real-world Scenario): องค์กรที่มีทีมข้อมูลแยกย่อย 10 ฝ่าย สามารถเรียกใช้โมดูลพิมพ์เขียวจัดเก็บ S3 เดียวกันของบริษัท เพื่อการันตีว่าทุกถังจัดเก็บข้อมูลถูกตั้งค่าความปลอดภัยแบบปิดกั้นการเข้าถึงจากภายนอกและเข้ารหัสถูกต้องตามกฎระเบียบขององค์กร
ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การอัปเดตโมดูลกลางโดยไม่ประกาศหมายเลขเวอร์ชัน อาจส่งผลกระทบให้โปรเจกต์ย่อยที่เรียกใช้อยู่พังทลายทันทีเมื่อรัน apply แก้ไขโดยกำหนดหมายเลขเวอร์ชันการนำเข้าและเรียกใช้โมดูลกลางผ่าน Git Tag ทุกครั้ง
5. การตรวจสอบความเบี่ยงเบนระบบ (Drift Detection) และการรวมด่านใน CI/CD
ทฤษฎีและกลไกการทำงาน (How it works): สภาวะ **Infrastructure Drift** เกิดเมื่อมีทีมงานแอบเข้าไปอัปเดตปรับแก้ทรัพยากรเซิร์ฟเวอร์จริงผ่านหน้าเว็บบอร์ดตรงโดยไม่ผ่านโค้ด Terraform ส่งผลให้สถานะสเตทเบี่ยงเบนไปจากโค้ดจริง เพื่อควบคุมความมั่นคง เราต้องสร้างด่านตรวจสอบใน CI/CD โดยตั้งรันจ๊อบ `terraform plan --detailed-exitcode` เพื่อเปรียบเทียบสเตทหากตรวจพบความเบี่ยงเบนระบบจะส่งสัญญาณแจ้งเตือนบล็อกการทำงานทันที
# GitHub Actions snippet to automate Terraform execution check
jobs:
terraform-ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Terraform Plan Check
run: |
terraform init
terraform plan -detailed-exitcode # Returns exit code 2 if drift is found
Use Case ในชีวิตจริง (Real-world Scenario): มีโปรแกรมเมอร์เผลอไปกดเปิดสิทธิ์พอร์ตของระบบฐานข้อมูล Redshift เป็นสาธารณะในแผงควบคุมระบบคลาวด์ ด่านตรวจสอบใน CI/CD ของบริษัทจะดักจับเจอว่าการตั้งค่าย้อนแย้งกับโค้ด และสั่งเตือนเข้า Slack ของแผนกความปลอดภัยทันที
ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): หากลบหรือล้างสเตทไฟล์ทิ้งด้วยความไม่ระมัดระวัง จะทำให้ Terraform คิดว่าทรัพยากรจริงหายไปหมดและพยายามรันคำสั่งบิวด์ทับซ้อนซ้ำขึ้นมา แก้ไขโดยทำการรันกู้ข้อมูลสเตทผ่านการกู้ย้อนคืน snapshot บน S3 state bucket
6. การเขียนทดสอบโครงสร้างพื้นฐานด้วย Terraform Test Framework
ทฤษฎีและกลไกการทำงาน (How it works): ตั้งแต่ Terraform 1.6 เป็นต้นมา มีการเปิดตัวคำสั่ง terraform test แบบเนทีฟ ช่วยให้วิศวกรสามารถเขียน Unit Test และ Integration Test โดยใช้ภาษา HCL ปกติ (ไฟล์ .tftest.hcl) ระบบสามารถจำลองการรัน plan (ตรวจสอบลอจิก) หรือรัน apply จริงเพื่อจำลองการสร้างโครงสร้างชั่วคราว เช็คเงื่อนไขความถูกต้อง (Assertions) แล้วลบทิ้งอัตโนมัติ
# secure_bucket.tftest.hcl
run "verify_s3_encryption" {
command = plan
assert {
condition = aws_s3_bucket.datalake_silver.tags["Environment"] == "Production"
error_message = "S3 bucket must have Environment tag set to Production"
}
}
Use Case ในชีวิตจริง (Real-world Scenario): ทีม Platform Engineering สร้างโมดูลมาตรฐานสำหรับแผนกอื่นๆ และเขียน Test บังคับว่าใครที่เรียกใช้โมดูลนี้จะต้องส่งค่ารหัสโปรเจกต์เสมอ เพื่อผลประโยชน์ด้านการคำนวณบิลค่าใช้จ่ายบนคลาวด์ หากใครไม่ส่งค่ารหัสนี้ Test จะตกตั้งแต่หน้า Pull Request
ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การตั้งให้ Test รันคำสั่ง apply สร้างทรัพยากรจริงบนคลาวด์ใช้เวลานานและอาจเสียค่าใช้จ่าย แก้ไขโดยเน้นการใช้ command = plan เพื่อตรวจสอบความถูกต้องของ Logic หรือใช้ฟีเจอร์ Mock Providers เพื่อจำลองทรัพยากรโดยไม่ต้องเรียก API คลาวด์จริง
Weekend Sandbox Challenge: Build an S3 Datalake bucket via Terraform
โจทย์ปฏิบัติการ: จงเขียนไฟล์กำหนดค่า Terraform HCL เพื่อสร้างพื้นที่จัดเก็บ S3 Datalake พร้อมตั้งระเบียบป้องกันการลบข้อมูล (Lifecycle Rules) และเปิดใช้การเข้ารหัสระดับดิสก์ (KMS Encryption)
# main.tf
resource "aws_s3_bucket" "datalake_silver" {
bucket = "pipecraft-datalake-silver-prod-bucket"
}
resource "aws_s3_bucket_server_side_encryption_configuration" "sse" {
bucket = aws_s3_bucket.datalake_silver.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
}
}
}
Senior Technical Interview Q&A
Q1: ทำไมการตั้งค่าเก็บไฟล์ประวัติสถานะ (State File) ไว้ใน Remote Backend (เช่น AWS S3) และเปิดใช้ระบบล็อกสิทธิ์ผ่าน DynamoDB จึงเป็นสิ่งจำเป็นในการทำงานระดับทีม?
A1: เพื่อเป็นแหล่งความจริงจุดเดียวของโครงสร้างระบบคลาวด์ ป้องกันปัญหาการตั้งค่าหลุดลอยไม่ตรงกันระหว่างทีมงาน และการผูกระบบ DynamoDB Lock ช่วยสกัดกั้นไม่ให้นักพัฒนา 2 คนสั่งรันคำสั่งแก้ไข `apply` พร้อมกันในจังหวะเดียวกัน ซึ่งจะทำให้ไฟล์สถานะเสียหายอย่างรุนแรง
Q2: เมื่อเกิดสภาวะระบบจำลองเบี่ยงเบนจากโค้ดจริง (Infrastructure Drift) เราควรวิเคราะห์และแก้ไขปัญหาผ่านขั้นตอนอย่างไร?
A2: เริ่มรันคำสั่ง `terraform plan` ระบบจะดึงสถานะจริงมาเปรียบเทียบกับโค้ด หากพบความเบี่ยงเบน ให้เลือกแนวทาง: (1) แก้ไขโค้ด HCL ให้ตรงกลับสภาพจริงแล้วสั่ง `apply` ยืนยัน หรือ (2) สั่งเขียนทับล้างระบบจริงโดยรัน `terraform apply` หรือ (3) ใช้คำสั่ง `terraform import` เพื่อดึงทรัพยากรที่สร้างด้วยมือเข้าสู่ระบบคุม
Interactive Terraform IaC Simulator
Interactive IaC
เป้าหมาย: เตรียมทรัพยากรจัดเก็บข้อมูล (Cloud Storage Bucket) โดยการสั่งรันคำสั่ง IaC ในเทอร์มินัลตามลำดับ ได้แก่ terraform init, terraform plan, และ terraform apply
ข้อดี / จุดเด่น & ข้อเสีย / ข้อควรระวัง
ข้อดี / จุดเด่น
- สามารถโคลนนิ่งคัดลอกโครงสร้างเน็ตเวิร์กเซิร์ฟเวอร์ทั้งระบบขึ้นมาใหม่ได้ภายในไม่กี่นาที
- ติดตามประวัติการแก้ไขและเพิ่มลดทรัพยากรเครื่องได้ผ่านทางระบบ Git
ข้อเสีย / ข้อควรระวัง
- หากเกิดปัญหา State File พังหรือขัดแย้งกัน อาจทำให้ระบบคลาวด์จริงสับสนและพังได้
- ต้องการการเรียนรู้ไวยากรณ์สเปคทรัพยากรของแต่ละ Cloud Provider ที่แตกต่างกันออกไป
ปฏิบัติการจริง (Lab Practice)
แล็บ: สร้างและตั้งค่า Cloud Storage ด้วย Terraform CLI
วิธีรันแล็บปฏิบัติการบนเครื่องจริง (Local Terminal Execution Blueprint)
เนื่องจากปฏิบัติการ Data Engineering / DevOps ระดับสูงต้องรันบน Environment จริง ขั้นตอนด้านล่างนี้คือคำสั่งสำหรับนำไปรันบน Terminal / Docker ในเครื่องของคุณ:
mkdir -p pipecraft-lab && cd pipecraft-lab python3 -m venv venv && source venv/bin/activate pip install --upgrade pip pandas polars pytest requests
# Run execution pipeline test
python3 -c "
import polars as pl
print(' [PipeCraft Lab] Running local pipeline engine...')
df = pl.DataFrame({'id': [1, 2, 3], 'status': ['SUCCESS', 'SUCCESS', 'AUDITED']})
print(df)
"
# Verify clean execution exit status echo " PipeCraft Local Lab Execution Completed Successfully!"
💡 คำแนะนำ & ทริกเด็ด
สำหรับไฟล์ terraform.tfstate ห้ามคอมมิตและอัปโหลดขึ้น Git เด็ดขาด เพราะมีข้อมูลความลับของเครื่องเซิร์ฟเวอร์และพาสเวิร์ดเก็บอยู่ ให้ใช้บริการ Remote State เช่น S3 พร้อมตั้งค่า State Locking เสมอ