ข้ามไปยังเนื้อหา

Infrastructure as Code คืออะไร

Infrastructure as Code คือการอธิบาย cloud resource เป็นไฟล์ text แล้วเก็บไว้ใน version control แทนการคลิกผ่าน portal ไฟล์นั้นคือ source of truth และมีเครื่องมือคอยทำให้ของจริงตรงกับไฟล์นั้น

ลองนึกภาพ engineer คนหนึ่งเปิด Azure Portal แล้วสร้าง resource group, virtual network, virtual machine และ network security group ด้วยมือ ทุกอย่างก็ใช้งานได้ ผ่านไปสามอาทิตย์ อีกคนเปิด portal แล้วแก้ rule ของ NSG เพื่อปลด block การ deploy โดยไม่บอกใคร อีกเดือนถัดมามีคนลบ storage account ที่ดูเหมือนถูกทิ้งไว้เฉย ๆ — แต่จริง ๆ ไม่ได้ถูกทิ้งไว้เฉย ๆ

รูปแบบนี้มีชื่อเรียก มักพูดพร้อมสีหน้าเบ้ ๆ ว่า ClickOps จุดพังไม่ได้อยู่ที่คลิกไหนคลิกหนึ่งผิด แต่อยู่ที่ลำดับการคลิกทั้งหมดเป็นแบบนี้

  • Unrepeatable ไม่มีใคร spin environment เดียวกันขึ้นมาใหม่จากศูนย์ได้ เพราะ “คำสั่ง” คือ muscle memory ของคนคนหนึ่ง
  • Undocumented portal แสดง state ปัจจุบัน แต่ไม่บอกว่า ทำไม จึงเป็นแบบนี้ หรือใครเป็นคนเปลี่ยน
  • Drift-prone ทันทีที่มีสองคนเปลี่ยน subscription เดียวกันได้อย่างอิสระ state จริงกับภาพในหัวของแต่ละคนก็เริ่มเพี้ยนออกจากกันไปเรื่อย ๆ โดยไม่มีใครรู้ตัว

ไม่มีใครตอบได้ว่า “ตอนนี้ deploy อะไรอยู่จริง ๆ และทำไมถึงเป็นแบบนั้น” แค่อ่านอะไรสักอย่าง เพราะ portal เองคือ source of truth เดียว และไม่มีความจำ ไม่มี review process ไม่มี diff ให้ดู

Infrastructure as Code (IaC) แก้ปัญหานี้ด้วยการทำให้ infrastructure ที่ต้องการเป็นไฟล์ commit เข้า git, review ผ่าน pull request เหมือนโค้ดทั่วไป และมีประวัติให้ git blame ย้อนดูได้ แต่เครื่องมือ IaC ไม่ได้ทำงานแบบเดียวกันหมด ความต่างตรงนี้สำคัญ

  • Declarative IaC คุณอธิบาย end state ที่ต้องการ แล้วปล่อยให้เครื่องมือคิดเองว่าจะไปถึงยังไง Terraform เป็นแบบ declarative resource block บอกว่า “ควรมี resource group ชื่อนี้ property แบบนี้” แล้ว Terraform คิดเองว่านั่นแปลว่าต้องสร้างใหม่ อัปเดต หรือปล่อยไว้เฉย ๆ
  • Imperative IaC คุณเขียน script ของขั้นตอนตามลำดับ “สร้าง resource group ก่อน แล้วสร้าง virtual network ข้างใน แล้ว launch VM ใน network นั้น” script อธิบาย วิธีทำ และเป็นหน้าที่คุณเองที่ต้องคอยดูให้ถูกต้องตลอดเวลาที่อะไร ๆ เปลี่ยนไป รันซ้ำสองรอบอาจพังได้ถ้าแต่ละขั้นตอนไม่ได้ถูกเขียนให้รันซ้ำได้อย่างปลอดภัย
# Declarative: describe the desired end state.
# Terraform decides what needs to change to get there.
resource "azurerm_resource_group" "main" {
name = "example-resources"
location = "East US"
}
Terminal window
# Imperative equivalent: an explicit, ordered command.
# Running this twice either creates a conflict or errors out —
# the script itself has no idea what already exists.
az group create --name example-resources --location eastus

สังเกตว่าฝั่ง declarative ไม่มีคำว่า create เลยสักคำ กริยานั้นถูกตัดสินใจโดย Terraform ตอน plan จากสิ่งที่เจอจริง ๆ

loop หลักของ Terraform เป็นการเทียบสามทางแบบนี้เสมอ

  1. อ่าน real-world state ปัจจุบัน ของ resource ที่จัดการอยู่ (Terraform เก็บ record ตรงนี้ไว้ใน state file)
  2. อ่าน configuration ที่ประกาศไว้ คือ HCL ที่อธิบายสิ่งที่คุณต้องการ
  3. คำนวณ plan คือชุดของ create, update, destroy ที่น้อยที่สุดที่จำเป็น เพื่อทำให้ของจริงตรงกับ configuration

ไม่มีอะไรถูกทุบทิ้งแล้วสร้างใหม่ทั้งหมดแค่เพราะคุณเปลี่ยน argument เดียว ถ้าคุณแค่เปลี่ยน tag ของ resource group plan ก็จะเป็นแค่ update in-place ที่ attribute เดียวนั้น ส่วนที่เหลือที่ Terraform จัดการอยู่จะไม่ถูกแตะต้อง

flowchart LR
  config["HCL config (desired state)"] --> tf["Terraform"]
  real["Real Azure resources (actual state)"] --> tf
  tf --> plan["Plan: the diff"]
  plan --> apply["Apply: minimal changes"]
Terraform reconcile configuration ที่ต้องการเข้ากับ infrastructure จริง

Terraform ไม่ใช่เครื่องมือ IaC ตัวเดียวในตลาด และควรรู้ไว้ว่า Terraform ไม่ใช่อะไร

  • ARM template / Bicep คือ IaC เจ้าของบ้านของ Azure เอง Bicep เป็น DSL ที่ Microsoft ทำให้เขียนง่ายกว่า แล้ว compile ลงไปเป็น ARM JSON ข้างใต้ ทั้งคู่เป็น declarative เหมือน Terraform แต่ใช้ได้แค่กับ Azure ไม่มีทางเทียบเท่าที่จะจัดการ GCP project หรือ Datadog monitor ด้วยไฟล์เดียวกัน
  • Pulumi เป็น provider-based และ state-tracked เหมือนกัน แต่คุณเขียนภาษาโปรแกรมมิ่งจริง ๆ (TypeScript, Python, Go) แทน HCL syntax แบบ declarative แลก learning curve ที่เล็กกว่ากับความยืดหยุ่นเต็มรูปแบบ (พร้อมความซับซ้อนเต็มรูปแบบ) ของภาษา general-purpose
  • Ansible เป็นเครื่องมือ configuration management เป็นหลัก Ansible login เข้าเครื่องที่มีอยู่แล้วรัน task ใส่ (ติดตั้ง package, แก้ config file, restart service) playbook ในทางปฏิบัติค่อนไปทาง imperative มากกว่า คือ task เรียงลำดับรันจากบนลงล่าง และไม่มี state file ในตัวคอยบันทึกว่าสร้างอะไรไว้บ้าง

Terraform เจาะกลุ่ม declarative, provider-based, state-tracked infrastructure provisioning ด้วย plugin model (provider) ที่ทำให้ workflow และ HCL syntax เดียวกันไปจัดการ Azure, AWS, GCP, Kubernetes, Datadog และระบบอื่นอีกหลายร้อยตัวได้ พร้อม state file ที่บันทึกไว้ชัดเจนว่า Terraform รับผิดชอบอะไรบ้าง

อีกชื่อหนึ่งที่ควรรู้จักคือ OpenTofu หลังจาก Terraform เปลี่ยน license ในปี 2023 กลุ่ม contributor และบริษัทต่าง ๆ ได้ fork release เวอร์ชันโอเพนซอร์สล่าสุดออกมาเป็น OpenTofu ซึ่งตอนนี้ดูแลโดย Linux Foundation OpenTofu เป็น alternative แบบโอเพนซอร์สที่ compatible กัน — HCL syntax, provider และ workflow ที่เรียนในคอร์สนี้ใช้กับ OpenTofu ได้ตรง ๆ

ปัญหาหลักของการเปลี่ยนแปลง infrastructure ด้วยการคลิกผ่าน Azure Portal (ClickOps) คืออะไร
ความต่างระหว่าง declarative กับ imperative Infrastructure as Code คืออะไร
Terraform คำนวณอะไรระหว่าง configuration ที่ต้องการกับ state จริงของ infrastructure
ข้อไหนพูดถึง alternative ของ Terraform ได้ถูกต้อง