ความแตกต่างระหว่าง Terraform VS Ansible

The Difference Between Terraform and Ansible

Nopnithi Khaokaew (Game)
3 min readNov 1, 2020

— — — — — — — — — — — — — — —
สารบัญเนื้อหาทั้งหมด (My Contents)
— — — — — — — — — — — — — — —

สำหรับคนที่สนใจงานทางด้าน DevOps หรือ automation (ทั้งบน cloud หรือ on-premise) ก็น่าจะพอรู้จักกับ Terraform และ Ansible กันอยู่แล้วไม่มากก็น้อย เพราะสองตัวนี้ถือว่าเป็น tool ที่มาแรงและควรจะ “ต้องใช้เป็น” ด้วย

แต่อะไรหละคือ…ความแตกต่างระหว่าง Terraform กับ Ansible?

ข้อที่ 1: Tool คนละชนิด จุดประสงค์ในการใช้งานต่างกัน

Ansible เป็น configuration management tools ซึ่งอยู่ในกลุ่มเดียวกับพวก Chef, Puppet และ SaltStack ในขณะที่ Terraform หรือ CloudFormation (AWS) นั้นจัดเป็น provisioning tools

  • Provisioning Tools = ช่วย provision server (หรือ infrastructure) ขึ้นมา เช่น spin up VM ขึ้นมาบน cloud หรือ hypervisor
  • Configuration Management Tools = ช่วยรัน script บน server (หรือ infrastructure) เพื่อ install, แก้ไข configuration หรือ enable service ต่าง ๆ

จะเห็นว่า tool หนึ่งเป็นตัวเริ่ม อีก tool ใช้ทำงานต่อ ดังนั้นที่ถูกต้องที่สุดคือเราต้องเลือก tool ให้ตรงกับงานที่เราจะทำ นี่คือความแตกต่าง

ข้อที่ 2: วิธีการเขียน Code เพื่อสั่งงานแตกต่างกัน

ภาษาที่เราใช้เขียนเพื่อสั่งงาน tool ทั้งสองตัวนั้นมีหลักการที่แตกต่างกันดังนี้

  • Ansible ใช้ Procedural Language
  • Terraform ใช้ Declarative Language

ซึ่งเดี๋ยวผมจะอธิบายโดยยกตัวอย่าง scenario ให้เห็นภาพแทนแล้วกันครับ

ตัวอย่าง 1: สร้าง Server (EC2) บน AWS จำนวน 10 เครื่อง

ใช้ Ansible

การสั่งงาน Ansible ซึ่งใช้ procedural language นั้นจะเป็นการเขียน code โดยมีแนวคิดที่ว่าเราจะต้องเป็นคนกำหนดลำดับขั้นตอนอย่างตรงไปตรงมาเพื่อบอก Ansible ว่าเราจะให้มันทำอะไรบ้าง

Ansible Code (Playbook)

- amazon.aws.ec2:
count: 10
image: ami-015a6758451df3cb9
instance_type: t2.micro
region: ap-southeast-1

จากตัวอย่างด้านบน ผมต้องการใช้ Ansible สร้าง server บน AWS เป็น Amazon Linux 2 จำนวน 10 เครื่อง และเมื่อรัน playbook เสร็จ ผมก็จะได้ server ตามจำนวนที่ต้องการ

ใช้ Terraform

Terraform นั้นเป็นแบบ declarative language ซึ่งเป็นการเขียน code เพื่อระบุสถานะสิ้นสุดที่เราต้องการ และ Terraform มีหน้าที่ในการหาว่าการจะไปยัง desired state นั้นต้องทำอะไรบ้าง และจากความต้องการเดียวกัน ผมจะได้

Terraform Code (Configuration)

provider "aws" {
region = "ap-southeast-1"
}
resource "aws_instance" "example" {
count = 10
ami = "ami-015a6758451df3cb9"
instance_type = "t2.micro"
}

เมื่อดูผ่าน ๆ นั้นเขียนไม่ต่างกัน และผลจากทั้งสองตัวก็เหมือนกันเลย แล้วมันต่างกันตรงไหนหละ?

ตัวอย่าง 2: สร้าง Server (EC2) เพิ่มจาก 10 เป็น 15 เครื่อง

ใช้ Ansible

สมมุติผมต้องการเพิ่มจำนวน server จาก 10 เป็น 15 เครื่อง บน Ansible นั้นผมจะต้องแก้ไข code แบบด้านล่างนี้เพื่อให้ได้ผลตามต้องการ นั่นก็คือการสั่งให้มันสร้าง(อีก) 5 เครื่อง

Ansible Code (Playbook)

- amazon.aws.ec2:
count: 5
image: ami-015a6758451df3cb9
instance_type: t2.micro
region: ap-southeast-1

ใช้ Terraform

ในขณะที่ถ้าหากผมใช้ Terraform นั้น ผมสามารถแก้ไข code โดยเปลี่ยนจาก 10 เป็น 15 ได้เลยแบบนี้

Terraform Code (Configuration)

provider "aws" {
region = "ap-southeast-1"
}
resource "aws_instance" "example" {
count = 15
ami = "ami-015a6758451df3cb9"
instance_type = "t2.micro"
}

โดยเมื่อผม apply ลงไป Terraform จะทำการเช็ค state ปัจจุบัน(และพบว่าตอนนี้มี server อยู่แล้ว 10 เครื่อง) แล้วจึงทำการสร้าง server ขึ้นมาใหม่ให้ครบตามที่ผมระบุเอาไว้ (ต้องสร้างอีก 5 เครื่อง)

ในความคิดผม declarative language ยังมีข้อดีอีกอย่างคือเวลาที่เราย้อนกลับมาอ่าน code มันจะสามารถบอกสถานะของ infrastructure ณ ปัจจุบันได้เลย เช่น

Terraform Code (Configuration)

provider "aws" {
region = "ap-southeast-1"
}
resource "aws_instance" "example" {
count = 15
ami = "ami-015a6758451df3cb9"
instance_type = "t2.micro"
}

จาก code ด้านบน เมื่อทีมงานคนอื่น ๆ มาเห็นก็จะคาดเดาได้ทันทีว่า ณ ตอนนี้เรามี server อยู่ทั้งหมด 15 เครื่อง (จริง ๆ เราเช็ค state จะแน่นอนกว่าครับ)

ในขณะที่ code ของ Ansible นั้นไม่สามารถเดาได้เลยว่าตอนนี้มี server อยู่กี่ตัวกันแน่ และจะต้องย้อนกลับไปดู code เก่าประกอบ

Ansible Code (Playbook)

- amazon.aws.ec2:
count: 5
image: ami-015a6758451df3cb9
instance_type: t2.micro
region: ap-southeast-1

อย่างนี้มาเห็นก็ไม่รู้หรอกว่ามีทั้งหมด 15 เครื่องแล้ว ถูกมั้ยครับ?

ตัวอย่าง 3: Rollback กลับจาก 15 เครื่องให้เป็น 10 เครื่อง

ขออนุญาตไม่แสดงตัวอย่าง code แล้วนะครับ (ขี้เกียจ ฮ่า ๆ)

ใช้ Ansible

ถ้าเป็น Ansible ผมจะต้องเขียน code ขึ้นมาใหม่สำหรับ terminate VM โดยเฉพาะเลย ซึ่งแตกต่างจาก code ที่เราใช้ provision ในตัวอย่างที่ 1 และ 2

ใช้ Terraform

แต่ Terraform นั้น ผมเพียงแค่ปรับพารามิเตอร์ count จาก 15 กลับเป็น 10 แล้ว apply อีกที มันก็จะทำการ terminate VM ทิ้งให้ผม 5 เครื่องโดยอัตโนมัติ

ป.ล. ที่จริงแล้วมันก็มีบาง module ของ Ansible ที่มีลักษณะเหมือนกับ declarative language อยู่นะครับ แต่ในบทความนี้ผมพูดถึงลักษณะพื้นฐานโดยทั่วไปของ Ansible

สรุป

เมื่ออ่านมาถึงตรงนี้ดูเหมือนว่า Terraform จะดีกว่า? ใช่ครับ เพราะนี่เป็นตัวอย่างในการ provision infrastructure ขึ้นมา แต่ถ้าหากเป็นการ install app หรือ dependency, configure service ต่าง ๆ บน server หรืออาจจะเป็นการ configure network device จำนวนมาก ฯลฯ ทางฝั่ง Ansible ก็อาจจะตอบโจทย์กว่าครับ

ดังนั้นสุดท้ายสิ่งสำคัญที่สุดคือการเข้าใจ tool และเลือกให้เหมาะสมกับงานของเราแค่นั้นเองครับ และ tools พวกนี้มันก็จะพัฒนาและเปลี่ยนไปเรื่อย ๆ ด้วย

— — — — — — — — — — — — — — —
สารบัญเนื้อหาทั้งหมด (My Contents)
— — — — — — — — — — — — — — —

--

--

Nopnithi Khaokaew (Game)
Nopnithi Khaokaew (Game)

Written by Nopnithi Khaokaew (Game)

Cloud Solutions Architect & Hobbyist Developer | 6x AWS Certified, CKA, CKAD, 2x HashiCorp Certified (Terraform, Vault), etc.