เริ่มต้นใช้งาน Terraform ฉบับมือใหม่
ในยุคที่เราทุกคนต่างต้องใช้งาน Cloud Service Provider กันอยู่แล้ว การจัดการ Resource ต่างๆบน Cloud ด้วยมือเป็นเรื่องที่ยุ่งยากมากและยังไม่ปลอดภัยอีกด้วย ดังนั้น Terraform จึงเป็นสิ่งที่ทีม Developer และ ทีม Operation ต้องทำความรู้จักเอาไว้
ข้อเสียของการทำงานผ่าน GUI(Microsoft Azure Portal หรือ AWS Management Console) คือ
- resources ต่างๆถูกสร้างไว้ที่ไหนบ้างก็ไม่รู้
- resources แต่ละตัวกำหนด configuration ไว้ยังไงบ้าง(มีใครแอบไปเปิด s3 bucket เป็น public รึเปล่า)
- การกำหนดสิทธิแบบ least privilege(มีแค่เท่าที่จะใช้เท่านั้น) ค่อนข้างยุ่งยาก และเยอะมาก
- ไม่สามารถตรวจสอบ(Audit) การทำงานได้
- เคยทำแล้วใน region นึงแต่พอย้ายไปอีก region นึงก็ต้องนั่งทำใหม่(บางทีลืมไปหมดแล้วว่าทำอะไรลงไปบ้าง)
- สร้าง resources เหมือนกันหลายๆตัว ต้องมานั่งทำซ้ำหลายๆครั้ง
- แต่ละคนมีวิธีการตั้งชื่อและการ Config ที่ไม่เหมือนกัน(ไม่มีมาตรฐาน)
ซึ่งปัญหาต่างๆเหล่านี้ สามารถแก้ไขได้ด้วย Automation ซึ่ง Terraform จะเข้ามาแก้ปัญหาต่างๆเหล่านี้
Infrastructure as Code(IaC)
Infrastructure as Code(IaC) คือ Code ที่เขียนขึ้นมาเพื่อสร้าง Infrastructure ซึ่งมีหลาย platform เช่น
- Dockerfile สำหรับสร้าง Docker image
- Kubernetes manifest สำหรับสร้าง resources บน Kubernetes cluster
- Terraform สำหรับสร้าง resources ต่างๆ บน Cloud
- Ansible สำหรับจัดการ Configuration และติดตั้ง Services ต่างๆลงบน Server
Terraform คืออะไร?
Terraform คือ Infrastructure as Code(IaC) ที่จะช่วยให้เราทำงานกับ Cloud Service Providers ทุกๆเจ้าแบบอัตโนมัติ ซึ่งการทำงานกับ Terraform นั้นสามารถใช้งานได้ทั้ง
- Terraform CLI เป็น opensource เราสามารถใช้งาน terraform cli ได้ฟรี แต่ต้อง run ผ่าน command line และที่สำคัญคือเราต้องจัดการกับ state เอง
- Terraform CLoud เป็น Software as a Service(SaaS) ที่ให้บริการฟรี ซึ่ง Terraform Cloud จะเก็บรักษา state ไว้บน server(remote state) อ่านวิธีการใช้งาน Terraform Cloud ได้ที่บทความนี้
- Terraform Enterprise เป็น self-host ของ terraform cloud เป็น enterprise grade ไม่มีการจำกัด resources
Terraform vs Ansible
Terraform กับ Ansible เป็น Infrastructure as Code(IaC) เหมือนกันแต่ทำงานคนละอย่างกัน โดยที่เราจะใช้ Terraform ในการจะสร้าง infrastructure บน cloud ขึ้นมาตั้งแต่ต้น โดยการ call ผ่าน API ของ Cloud Services Provider(CSP) แต่ละเจ้า แต่เมื่อคุณมี infrastructure ที่เราสามารถ connect เข้าไปด้วย
- Secure Shell(ssh) บน Linux OS หรือ Router
- WinRM บน Windows
- Docker บน container based
- KubeCtl เมื่อต้องการจัดการกับ Kubernetes Cluster
เราจะสามารถใช้ Ansible เชื่อมต่อเข้าไปใน platform นั้นๆ เพื่อสร้างให้ platform นั้นเป็นไปตามสิ่งที่เราเขียนไว้ใน ansible playbooks
การใช้งาน Terraform เบื้องต้น
การจะใช้งาน Terraform เราจะค้องรู้จักสิ่งเหล่านี้ก่อน
-
Terraform Provider คือสิ่งที่ต้องติดตั้งก่อนเริ่มต้นใช้งาน ซึ่ง providers จะแบ่งออกเป็น 3 ประเภทตามผู้ดูแล ดังนี้
- Official code จะดูแลด้วยทีมของ hashicrop(เจ้าของ terraform) เอง
- Partner code จะดูแลโดยเจ้าของ product ซึ่งก็จะเป็น cloud service provider ที่ไม่ใช่เจ้าหลักๆนั่นแหละ ยกตัวอย่างเช่น Oracle Cloud Infrastructure(oci), Alibaba Cloud หรือ digital ocean
- Community code ชุดนี้จะเป็นกลุ่มที่มีผู้เขียนขึ้นมาให้เราใช้งาน(สามารถเลือกใช้งานได้ แต่จะไม่มี support เหมือน 2 แบบแรก) ยกตัวอย่างเช่น docker
-
Terraform State เป็นสถานะล่าสุดของ resources ต่างๆ ที่เราสร้างขึ้นมา terraform จะสร้างไฟล์ .tfstate ขึ่้นมาหลังจากที่เราสั่ง terraform apply ซึ่ง state นี้สามารถจัดเก็บไว้ได้ 2 ที่คือ
- Local state อยู่บนเครื่องที่ run terraform cli โดย default จะอยู่ใน folder ที่เรา run terraform apply
- Remote state อยู่บน server เพื่อ share กันระหว่างทีม เหมาะสำหรับการใช้งาน terraform ที่ใช้งานพร้อมๆกันหลายๆคน terraform จะสามารถจัดเก็บ state ไว้ใน storage ได้หลายรูปแบบ ยกตัวอย่าง เช่น
- Terraform cloud
- Hashicrop Consul
- Amazon S3
- Azure Blob Storage
- Google Cloud Storage
- Alibaba Cloud OSS
การเข้าไปแก้ไข resource ต่างๆด้วยมือ จะทำให้ state ของ terraform ผิดพลาด ซึ่งจะทำให้ terraform error หรือ ทำงานไม่ตรงกับสิ่งที่เราคาดไว้ ซึ่งการ update state เราสามารถใช้ terraform import ในการ update state ได้
ถ้าใช้ terraform สร้าง resource นั้นแล้วควรจะ manage ด้วย terraform อย่างเดียว
หลังจากนี้เราจะมาดูกันว่า จะใช้ terraform นั้นเราจะต้องรู้จักกับคำสั่งอะไรบ้าง
terraform init
ก่อนเริ่มต้นทำงานให้เรา install provider ลงมาก่อน ด้วย terraform init ซึ่งถ้าเป็น official provider เราจะสามารถกำหนด resource แบบนี้ได้เลย
resource "aws_instance" "app_server" {
ami = "ami-830c94e3"
instance_type = "t2.micro"
tags = {
Name = "ExampleAppServerInstance"
}
}
terraform จะมองดูที่ prefix ซึ่งในกรณีนี้เราจะสร้าง aws_instance ซึ่งนำหน้าด้วย “aws” terraform จะไป load provider ขึ้นให้เราโดยอัตโนมัติ
การปล่อยให้ terraform install provider ด้วยตัวเองอาจมีปัญหาเรื่อง version แนะนำให้ใส่ required_providers block ตามตัวอย่างด้านล่าง
แต่ถ้าเราไม่ได้ใช้ official provider เราต้องทำการระบุ provider ที่ต้องการใช้แบบนี้
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 2.23.1"
}
}
}
ข้อแนะนำ ให้ใส่ ~> เข้าไปหน้าเลข version เพื่อบอก terraform ว่าให้ install version 2.23.x (ตอนมี patch หรือ bugfix จะได้ update)
ถ้าเราเคยลง terraform provider ไปแล้วแต่ต้องการ upgrade ให้ใช้ คำสั่งนี้
$ terraform init -upgrade
terraform plan
terraform plan จะเป็นคำสั่งที่ใช้เปรียบเทียบข้อมูลที่อยู่ใน state กับ resource จริงๆว่าแตกต่างกันยังไง หลังจากนั้น terraform จะสร้าง execution plan ออกมาว่าจะต้่องมีการเปลี่ยนแปลงอะไรบ้าง resource บน cloud ถึงจะตรงกับสิ่งที่เขียนไว้ใน terraform configuration
เราจะใช้คำสั่งนี้ในการสร้าง execution plan
$ terraform plan
ถ้าเราต้องการเก็บ execution plan ไว้ใช้ในภายหลัง เราจะต้องใช้ parameter -out เพื่อ save execution plan เก็บไว้ใน file .tfplan
$ terraform plan -out demo.tfplan
เราสามารถบังคับให้ terraform plan ลบ resource เก่าทิ้งและสร้าง resource ใหม่ได้ด้วยคำสั่ง
$ terraform plan --replace aws_instance.app_server
aws_instance.app_server จะต้องถูกนิยามไว้ใน terraform configuration แบบนี้
resource "aws_instance" "app_server" {
ami = "ami-xxxxxxxxxxxxx"
instance_type = "t2.micro"
tags = {
Name = "ExampleAppServerInstance"
}
}
ถ้าต้องการลบหลายๆ resource สามารถใส่ replace ซ้ำหลายๆครั้งได้
$ terraform plan --replace aws_instance.app_server \
--replace aws_instance.web_server
terraform apply
terraform apply จะลงมือสร้าง resource บน cloud ขึ้นมาจริงๆแล้ว ซึ่งตอน run terraform apply ก็จะแสดง execution plan ขึ้นมา และมี prompt ให้เราตอบ “yes” เพื่อ confirm ว่าจะทำงานตาม execution plan ที่สร้างขึ้นมาจริงๆนะ(เราสามารถ run terraform apply โดยไม่ต้อง run terraform plan ก็ได้)
$ terraform apply
ถ้าเราแน่ใจว่าเรากำลังจะทำอะไรกับ resource นั้นๆ เราสามารถ ใส่ parameter “-auto-approve” ได้เลย
# terraform จะ apply ทันทีโดยที่ไม่ต้องพิมพิ์ yes
# ระวังข้อผิดพลาดที่อาจเกิดขึ้นจากขั้นตอนนี้ด้วย
$ terraform apply -auto-approve
เราสามารถระบุ path ของ .tfplan ที่ได้จาก terraform plan -out ด้วยคำสั่งนี้
$ terraform apply "demo.tfplan"
terraform destroy
หลังจากที่เราเลิกใช้งาน resource ต่างๆเหล่านั้นแล้ว เราจะใช้ terraform destroy ในการทำลาย resources ต่างๆ ที่อยู่ใน terraform configuration นั้นทิ้งทันที