เอา Kubernetes ไปรัน Terraform แล้วมันจะไม่ยิ่งซับซ้อนเหรอ?

Chanwit Kaewkasi
2 min readAug 26, 2022

จริง ๆ แล้วคำถามนี้เป็นคำถาม Classic มากเลยครับว่า แค่ Kubernetes ก็แย่แล้ว จากปกติเราก็ใช้ Terraform สร้าง (Provision) Infrastructure กันก็น่าจะจบแล้ว

แล้วการรัน Terraform ใน Kubernetes คืออะไร? จะทำให้มันยากไปไหน?

ระบบที่ต้องการการ Provision ขนาดนี้มีจริงมั้ย

มันจะมีคนเอาทำอะไรจริง ๆ เหรอ ที่ต้อง Provision กันเป็นพัน ๆ โมดูล ขนาดนั้น

มันก็คงเหมือนกับการถามว่า จะสร้างจรวดทำไมให้มีแรงขับตั้งเยอะตั้งแยะ ใช้ Booster ทีเดียวตั้ง 9 ตัว แถมต้องทำให้อุณหภูมิของ Booster ด้านนอกเย็นเจี๊ยบอีก ถ้าผมไม่เคยเห็นจรวดแบบนั้นผมก็คงมีคำถามแบบเดียวกันว่า มันจะมีคนเอาไปทำอะไรจริง ๆ เหรอ

เอาเป็นคำตอบสั้น ๆ ก่อนละกันครับว่า มี

แล้วจะเอา Kubernetes ไปรัน Terraform ทำไม

เรื่องนี้ต้องย้อนไปถึง Concept ของการใช้ Terraform ก่อน ว่า ใน DevOps เราใช้ Terraform ทำไม

  1. เราใช้เพราะเหตุผลของ Infrastructure as Codes คือเก็บ Infrastructure ในรูปแบบของ Code ได้ เอามารันซ้ำ ๆ ได้ เก็บเข้า Git ได้ (ตรงข้ามกับการ Click ผ่าน UI)
  2. เรามักจะใช้ Terraform กันใน CI Pipeline (ย้ำนะครับว่า CI Pipeline) คือ แก้ Code, Push แล้วรัน Terraform Plan, Apply ใน Pipeline (ส่วนนี้คือ Provisional Workflow)
  3. เรามีหลาย ๆ CI Pipeline เพื่อจัดการ Infrastructure หลาย ๆ Environment พูดง่าย ๆ ภาษา Terraform ก็คืออาจจะมี 3 (Root) Modules เช่น Dev, Staging, Prod ก็ว่ากันไป

พอมาถึง Step นี้ หลายคนอาจจะมีคำถามในใจว่า อ้าว ก็ครบแล้วนี่

แต่ผมก็จะถามว่า ขาดอะไรไปรึเปล่า?

สิ่งที่ขาดหายไปในนั้นคือ Configuration Management Workflow

Provisional Workflow v.s. Configuration Management Workflow

Provisional Workflow คือ Workflow ของการสร้าง Infrastructure ที่ทุกคนคุ้นเคยดี

ส่วน Configuration Management Workflow เราก็คุ้นเคยเช่นกัน ทำอยู่แหละ แต่อาจจะมองไม่ชัดใน Terraform

เช่น การเปิดปิด Port ใน SecurityGroup บน AWS

เช่น การโยง IAM Policy ให้กับ User บางกลุ่ม แล้วต้องถอดออก

เช่น การเปิด S3 Bucket เป็น Public แล้วต้อง Set กลับให้เป็น Private

คุ้น ๆ อะไรมั้ยครับว่า เรามักจะทำของแบบนี้ครั้งเดียว (ด้วย Provisional Workflow หรือทำผ่าน UI) แล้ว ลืม

พอมีคนมาทักว่าลืมปิด Bucket นะ เปิด Port ทิ้งไว้นะ เราก็ค่อยไปแก้ แต่บางครั้งมันก็ไม่ทันแล้ว

เพื่อให้ Configuration Management ง่ายขึ้น พลาดน้อยลง กลไกที่ Terraform และเครื่องมือกลุ่มนี้ใช้แก้ปัญหา ให้มีตัวตรวจสอบการเปลี่ยนแปลงใน State ของ Infra ที่ไม่ตรงกับต้นทางที่เราต้องการ คือ กลไก Drift Detection

ทำไม Drift Detection ต้องการ Kubernetes?

คำตอบคือ ไม่จำเป็น

วิธีการแบบนี้มีมานานแล้วครับ เราใช้เครื่องมืออื่น ๆ ทำก็ได้ ตัว Classic ที่เค้าทำ ๆ กันก็ใช้ Cron Job ตรวจสอบ

ที่ใช้ Kubernetes ก็เพราะว่ามันเป็น Interface ที่เป็น De facto Standard ที่จะได้โยงการสร้าง Infrastructure เข้ากับการ Deploy Application Workload ไปได้เลย

เช่น เรามี Kubernetes เป็น Management Cluster 1 ตัว ลง Terraform Controller ไว้แล้วใช้สร้าง สร้าง EKS Cluster อีก 5 ตัว ได้ KubeConfig ของตัวใหม่ที่สร้างกลับมาเป็น Secret แล้วก็ใช้ Flux Deploy ระบบต่อเนื่องไปได้จนจบ ด้วย GitOps ทุกอย่างเกิดขึ้นใน CD Pipeline (ย้ำว่า GitOps + CD Pipeline นะครับ — ไม่ใช่ CI อย่างเดียว) โดยไม่มีการแตะหรือมองเห็น Secret จากด้านนอกชุดของ Cluster เหล่านี้เลย

CD Pipeline ที่เชื่อถือได้

พอเป็น Kubernetes ก็จะมีข้อดีอีกอย่างนึงก็คือ Docker Image ครับ ตอนนี้ Docker Image กลายเป็นมาตรฐานที่เรียกว่า Open Container Initiative (หรือ OCI) format และเราก็ใช้ Docker Image เป็นสื่อกลางของ CI Pipeline ในการ Deliver ตัว Application มากันจนคุ้นเคยไปแล้ว

คราวนี้ก็มายกระดับกันต่ออีกซักหน่อย

ตอนนี้โครงการ GitOps เช่น Flux2 (v0.32) หรือแม้แต่ Helm (3.9) ก็เริ่มใช้ OCI / Docker Image มาเป็นสื่อกลางในการเก็บ YAML กันแล้วครับ

ผมเป็นส่วนนึงของการผลักดันให้เกิด Eco-System นี้ในโลกของ Cloud Native ก็เพิ่งทำให้ Terraform Controller สามารถ Provision ตัว Terraform Module ที่อยู่ในรูปแบบ OCI / Docker Image ได้ไปเมื่อซัก 2 สัปดาห์ก่อนนี่เอง ตาม Flux v2 ไปติด ๆ

แล้วมันสำคัญยังไง จุดสำคัญของ OCI / Docker Image ก็คือมัน “Sign” และ “Verify” ได้ครับ พอมัน Sign ได้ด้วยเครื่องมือมาตรฐานก็จะทำให้เกิดเป็น Trusted Pipeline ขึ้นมา

ถ้าอยากย่อย Vision เรื่องนี้เพิ่ม ลองไปอ่านต่อได้แถว ๆ นี้ครับ

--

--

Chanwit Kaewkasi

Creator Weave TF-controller, Kubernetes & GitOps for Terraform, SNR SE @weaveworks, Go nut since r57 (pre v1)