Terraform EP1 - What and Why
Tags: terraform, devops, iac
Published: 2020-03-18 09:48:01

> สรุปมาจาก [A Comprehensive Guide to Terraform](https://blog.gruntwork.io/a-comprehensive-guide-to-terraform-b3d32832baca) และ [Why we use Terraform and not Chef, Puppet, Ansible, SaltStack, or CloudFormation](https://blog.gruntwork.io/why-we-use-terraform-and-not-chef-puppet-ansible-saltstack-or-cloudformation-7989dad2865c)

# Terraform คืออะไร?

[Terraform](https://www.terraform.io/) คือ opensource tool ที่ช่วยให้เราสามารถ provision infrastructure บน cloud providers ต่างๆ ได้ง่ายๆ ไม่ว่าจะเป็น AWS, Azure, Google Cloud, Digital Ocean เป็นต้น เพียงแค่เขียนสิ่งทีเราต้องการลงไปใน code (descriptive programing language ชื่อ [HCL](https://www.terraform.io/docs/configuration/syntax.html)) แล้วสั่งให้ Terraform ทำงาน มันจะพิจารณาสถานะปัจจุบันแล้วทำแค่สิ่งที่จะต้องทำเพื่อให้ infrastructure เป็นดังที่เราต้องการ 

เราอาจเรียก Terraform ว่าเป็น Tool ในการทำ Infrastructure-as-Code (IaC)

---

# ทำไมต้องทำ Infrastructure-as-Code ?

ลองนึกภาพว่าเราได้รับคำสั่งให้เตรียม server สำหรับทำ web ขนาดใหญ่บน cloud provider ซึ่งเจ้าหนึ่ง (แค่เจ้าเดียวก่อนก็เหนื่อยละ 😫) โดยเราต้องเตรียม 100 servers เป็น database 50 servers และ Web Server 50 เครื่อง ซึ่ง Database เราต้องเพิ่ม Disk ให้มันเครื่องละ 1 TB mount ไว้ที่ /data และ Web Server ต้องเพิ่ม network interface ขา Internet 

ถ้าเราต้องนั่ง click GUI เสร็จแล้วต้องเข้าไปตรวจสอบทุกเครื่องอีก คงเป็นงานที่ ถึก เหนื่อย และเสียเวลาน่าดู จะดีกว่าไหม... ถ้าเราแค่เขียนสิ่งที่ต้องการให้ตรง format แล้วให้ Terraform ทำให้เราทั้งหมด 

นั่นเป็นแค่ข้อดีข้อหนึ่งของ Infrastructure-as-Code ทาง Gruntwork ได้ list ข้อดีมาเพิ่มให้เราอีกดังนี้

- ทำให้เราสามารถทำ automation ได้ทั้งระบบ ตั้งแต่ infra ยัน deploy application ทำให้สามารถสร้างหรือเปลี่ยนแปลงได้เร็วขึ้น
- เราสามารถดู infrastructure ของเราทั้งหมดได้จาก code ที่เราทำไว้ ไม่ใช้อยู่ในหัวของ admin คนใดคนหนึ่ง
- เนื่องจากว่ามันเป็นแค่ text file ดังนั้นเราสามารถเก็บมันไว้ใน version control ได้ ทำให่ง่ายต่อการ track ปัญหาย้อนหลัง และ trace ได้ว่าใครทำ code ส่วนนี้ขึ้นมาเพื่ออะไร
- สามารถ review การเปลี่ยนแปลง ของ infrastructure ได้เหมือนการ review code และสามารถทำ automated test ได้
- ถ้าเราทำให้ code ให้ดีๆ ใช้ซ้ำได้ มี document ดีๆ พร้อมทั้ง test ที่ครอบคลุม เราก็สามารถเอาไปวางใน Market Place ต่างๆ เพื่อขายได้

> "IAC offers a better alternative that allows computers to do what they do best (automation) and developers to do what they do best (coding)"

---

# ทำไมถึงใช้ Terraform ?

ทาง Gruntwork ได้ทำการแบ่งหัวข้อในการพิจารณาเปรียบเทียบ IaC Tool หลักๆ ในตลาดไว้ดังนี้

- **Configuration Management vs Provisioning**
  - **Configuration Management Tool** ใช้ในการ install และ จัดการ software บนเครื่องที่มีอยู่แล้ว ตัวอย่างเช่น Chef, Puppet, Ansible และ SaltStack
  - **Provisioning Tool** ใช้ในการสร้าง infrastructure เช่น servers, load balancer, network หรือ database ขึ้นมาใหม่ เช่น CloudFormation และ Terraform
  
  > Tool ทั้ง 2 ประเภทนี้ มีจุดประสงค์คนละแบบ แต่ก็มีบางส่วนที่ทับซ้อนกันอยู่ เวลาเลือกใช้ ควรเลือกตามประเภทและการใช้งาน

- **Mutable Infrastructure vs Immutable Infrastructure**
  - **Mutable infrastructure** คือการที่เราเข้าไปแก้ไขอะไรบางอย่างตรงๆ ในแต่ละ servers เช่น update software หรือ แก้ไข configuration files โดยปกติแล้ว Configuration Management Tool จะเป็น mutable infrastructure ด้วย วิธีนี้เมื่อทำไปนานๆ มักทำให้เกิดความแตกต่างบางอย่างเล็กน้อยในแต่ละ server ซึ่งอาจนำไปสู่ bug ที่ยากต่อการ diagnose และ reproduce 
  - **Immutable Infrastructure** คือการแก้ไขผ่าน image ของ server ประเภทนั้นๆ ด้วย tool อย่าง Docker หรือ Packer แล้วทำการ re-provisioning server ใหม่ด้วย image นั้นๆ ด้วยวิธีนี้ทุก server จะเหมือนกันแน่นอน ถ้าหากพบปัญหา เราสามารถทำ image นี้ไป provision และ debug ได้เลย 

  > เราอาจบังคับให้ Configuration Management Tool ทำงานแบบ Immutable Infrastructure ได้แต่ก็จะฝืนๆ ธรรมชาติของมัน ทำให้งานบางอย่างอาจไม่สะดวก หรือ ซับซ้อนขึ้นมาก

- **Procedural vs Declarative**
  - **Procedural Style** เป็นการที่เราเขียนวิธีการทำงาน ให้ Tool นำไปปฏิบัติแบบ step-by-step เพื่อที่จะให้ได้สิ่งที่เราต้องการ ตัวอย่างเช่น Chef และ Ansible
  - **Declarative Style** เป็นการเขียนสิ่งที่เราต้องการขึ้นมา แล้วให้ IaC Tool เองเป็นคนคิดว่าต้องทำอะไรบ้างเพื่อให้ได้สิ่งที่เราต้องการ ตัวอย่างเช่น CloudFormation, SaltStack และ Puppet

    <u>ตัวอย่าง:</u> ถ้าเรามีอยู่ 10 servers แล้ว เราต้องการเพิ่ม server เป็น 15 servers<br/>
    - หากเราใช้ **Ansible** เราต้องบอกให่มันสร้าง server อีก 5 servers
    - แต่ถ้าเป็น **Terraform** เราแค่บอกมันว่าอยากให้มัน server ทั้งหมด 15 servers มันจะคิด แล้วสร้างอีก 5 servers ให้เอง

    <u>ข้อได้เปรียบของ **Declarative Style** ที่มีต่อ **Procedural Style**</u> มีดังนี้
    - ถ้าเราอยากรู้ว่า infrastructure ปัจจุบันเป็นอย่างไร สำหรับ Ansible เราต้องเอาหลายๆ code มาเรียงตามลำดับเวลา เพื่อจะที่จะดูว่า สถานะปัจจุบันของ infrastructure เป็นอย่างไร แต่ถ้าใช้ Terraform เราดู code สุดท้าย code เดียวได้เลย
    - ในแง่ reusable นั้น **Procedural Style** จะทำได้ยากกว่าเพราะ code จะเพิ่มขึ้นเรื่อยๆ เมื่อเกิดการเปลี่ยนแปลง แต่ **Declarative Style** code จะไม่เปลี่ยนมาก ทำให้สามารถนำกลับมาใช้ใหม่ได้ง่ายกว่า

    <u>ข้อได้เปรียบของ **Procedural Style** ที่มีต่อ **Declarative Style**</u> มีดังนี้
    - **Procedural Style** สามารถทำ programming logic เช่น condition และ looping ได้ดีกว่า จึงสามารถทำงานที่ซับซ้อน เช่น เราเอาข้อดีนี้ไปทำพวก zero downtime deployment ได้ ส่วน **Declarative Style** ทำได้แค่การ assign ตัวแปร และ function ง่ายๆ เท่านั้น ในการทำ zero downtime deployment ต้องเขียน script มาช่วยมัน

- **Master vs Masterless**
  - **Master** คือต้องมี Master Server ในการทำงาน เช่น Chef, Puppet และ SaltStack หน้าที่ของ master server คือ เก็บ state ของ infrastructure โดยทุกการสั่งงานจะต้องส่งมาที่ master server เสมอ แล้ว master จะเป็นคนไปทำงานต่อให้
    - <u>ข้อดี</u>
      - มีการทำงานรวมศูนย์ที่ Master server ทำให้ติดตามการทำงานได้ง่าย
      - บางระบบมี background process ในการ enforce ให้ infrastructure เป็นเหมือนตาม configure ตลอด ทำให้ป้องกันคนเข้าไปแก้ไข manual โดยไม่ได้ตั้งใจ
    - <u>ข้อเสีย</u>
      - ต้องมี server เฉพาะสำหรับงานนี้
      - ต้องคอย maintenance เช่น upgrade, backup, monitor และ scale เป็นต้น
      - เป็นช่องโหว่ง เพราะ master server สามารถทำได้ทุกอย่าง
  - **Masterless** คือไม่ต้องมี Master Server เช่น Ansible, CloudFormation, Heat และ Terraform Tool พวกนี้ไม่ถึงกับไม่มีต้องมี master เลย แต่แค่ไม่จำเป็นต้องแบ่ง server เฉพาะเพื่อการทำมัน เราสามารถ run ที่ไหนก็ได้ จึงมองว่ามันเป็นส่วนหนึ่งของ infrastructure ของเรา เช่น Terraform ใช้ การ Authen และ API ของ Cloud Providers เลย และ Ansible ใช้การ login และ authen ด้วย SSH เป็นต้น

- **Agent vs Agentless**
  - **Agent** ต้องลง agent ในทุกเครื่องที่ต้องการ configure ในบางตัวอาจมี option ที่ไม่ต้องลง agent แต่ก็ไม่สามารถทำงานได้ทุก features เช่น Chef, Puppet และ SaltStack
    - <u>ข้อเสีย</u>
      - ต้องลอง agent และ configure มันให้ใช้งานได้
      - ต้อง maintenance เช่น update software, ดูแลไม่ให้ application crash และบางครั้ง agent เองอาจมี bug
      - ต้องเปิด port ขาเข้าให้ Master เข้ามาสั่งงาน ซึ่งอาจเป็นช่องโหว่ได้ ถึงแม่จะมีการ authen แต่มันก็เป็นช่องให้ Hacker เจาะได้
  - **Agentless** พวกนี้ไม่ต้องมี agent แต่มันจะใช้ของที่มีอยู่แล้วในระบบ เช่น SSH หรือ API ของ Cloud Provider เป็นต้น ในการทำงาน เช่น Ansible, CloudFormation, Heat และ Terraform

- **Large Community vs Small Community**
  - **Large Community** คนใช้เยอะ ย่อมมีคน contribute เยอะ ทำให้มี feature เยอะ และ bug ถูกแก้ได้เยอะกว่า เช่น Ansible, Chef, Puppet และ Terraform
  - **Small Community** คนใช้น้อย อะไรๆ ก็น้อย ยกเว้น bug เช่น SaltStack และ Heat

  > ในที่นี้จะไม่รวม CloudFormation เพราะ ไม่ใช่ Opensource

- **Mature vs Cutting Edge**
  - **Mature** มีอายุนานกว่า หลายๆ อย่างค่อนข้างเสถียร แต่อาจมีบางอย่างที่ล้าสมัย ต้องดูดีๆ ไม่ใช่ Mature แล้วจะดีเสมอไป
  - **Cutting Edge** มีอายุน้อยกว่า นั่นคือมี technology ที่ใหม่กว่า แต่อาจไม่ค่อยเสถียร

| Name | Initial Release | Current Version |
|:----:|:---------------:|:---------------:|
| Puppet | 2005 | 6.14.0 |
| Chef | 2009 | 13.1.13 |
| CloudFormation | 2011 | 2010-09-09 |
| SaltStack | 2011 | 3003 |
| Ansible | 2012 | 2.4.6 |
| Heat | 2012 | 13.0.0 |
| Terraform | 2014 | 0.12.23 |

---

# Tool เดียวไม่ตอบโจทย์ ก็ต้อง combo

- **Provisioning Tool + Configuration Management Tool**
  
  - **Terraform + Ansible** โดยใช้ Terraform ทำ Infrastructure และใช้ Ansible จัดการเรื่องการลง application และ configuration
  
    <u>ข้อดี</u>
    - ไม่ต้องมี server เพิ่มเติมเพื่อเป็น Master เลย
    - ทั้ง 2 เครื่องมือทำงานร่วมกันได้อย่างดี โดยใช้ tags

    <u>ข้อเสีย</u>
    - Ansible เป็น Mutable infrastructure ทำให้ code ขยายขึ้นเรื่อยๆ และยากต่อการ maintenance

- **Provisioning Tool + Templating**

  - **Terrform + Packer** โดยใช่ Packer สร้าง Image และ นำ image นี้ไป provisioning ด้วย Terraform
  
    <u>ข้อดี</u>
    - ไม่ต้องมี server เพิ่มเติมเพื่อเป็น Master เลย
    - ทั้ง Terrform และ Packer เป็น Immutable Infrastructure ทำให้ maintenance code ได้ง่าย
    
    <u>ข้อเสีย</u>
    - การ build และ deploy VM ใหม่ทั้ง VM ใช้เวลานาน
    - ไม่สามารถทำ Deployment Strategy เช่น blue-green ได้โดยตรงจาก Terraform ทำให้ต้องเขียน script เพิ่มเพื่องานนี้ 
      
- **Provisioning Tool + Templating + Orchestration**
  
  - **Terraform + Packer + Docker + Kubernetes** โดยใช้ Packer ทำ image ที่ลง Docker และ Kubenetes ไว้แล้ว จากนั้น provision image นั้น เป็น VM พร้อมด้วย resources ต่างๆ ก็จะได้ kubernetes cluster ที่มี Docker เป็น container runtime
  
    <u>ข้อดี</u>
    - Docker build เร็วกว่า และ deploy เร็วหว่า VM image ของ Packer
    - Kubernetes จะช่วย manage เรื่องต่างๆ ให้ ไม่ว่าจะเป็นการ health check, auto recovery และ  deployment strategy เป็นต้น
    
    <u>ข้อเสีย</u>
    - ค่อนข้างซับซ้อน
    - Cloud Provider ส่วนใหญ่มี Managed Kubernetes Cluster ไว้ให้ใช้อยู่แล้ว

---