เริ่มต้น Infrastructure as Code ด้วย Terraform และ DigitalOcean

หัวข้อในบทความนี้

- เกี่ยวกับ Terraform

- เกี่ยวกับ Digital Ocean

- ติดตั้ง Terraform บน Mac

- ติดตั้ง Terraform บน Windows

- สมัครใช้งาน Digital Ocean

- การนำ Token ของ Digital Ocean มาใช้

- การสร้าง SSH Key เพื่อเข้าสู่ Virtual Machine (Droplet)

- การสร้าง Virtual Machine (Droplet) บน Digital Ocean โดย Terraform

 

ในบทความนี้จะสาธิตการใช้งาน Terraform กับ DigitalOcean โดยละเอียด

 

เกี่ยวกับ Terraform

- Terraform เป็นเครื่องมือเกี่ยวกับ Infrastructure as Code ที่ใช้จัดการ services ต่างๆบน cloud 

- Terraform ใช้ภาษา HCL (HashiCorp Configuration Language) ซึ่งเป็นภาษาที่จะอธิบาย resources แบบสั้นๆ และเป็น block ๆ

- Terraform สามารถใช้งานได้ฟรี 

 

เกี่ยวกับ DigitalOcean

- เป็น cloud ที่ใช้งานง่าย  ไม่ซับซ้อน  เมื่อเทียบกับ cloud providers อื่นๆ   จึงทำให้สามารถ setup/implement ได้เร็ว

- มีราคาที่ถูกและมี standard ระดับโลก [ราคาเพิ่มเติม] [standard เพิ่มเติม]

 

ติดตั้ง Terraform บน macOS

เนื่องจากจะติดตั้ง Terraform โดยใช้ Homebrew ซึ่งเป็น command line   ดังนั้น ถ้ายังไม่มี Homebrew ให้ติดตั้งก่อน (อ้างอิงจาก : https://brew.sh )

ติดตั้ง Homebrew โดยคำสั่งดังต่อไปนี้

 

เมื่อติดตั้ง Homebrew เสร็จ

จากนั้นให้ติดตั้ง repository ของ Hashicorp โดยคำสั่งต่อไปนี้

 

ติดตั้ง Terraform

 

หรือสามารถทำการตรวจสอบว่า Terraform ถูกติดตั้งเรียบร้อยแล้วหรือไม่ พร้อมกับดู version ของ Terraform ด้วยคำสั่ง

ซึ่งจะได้ผลลัพธ์ดังตัวอย่าง

 

ติดตั้ง Terraform บน Windows

- ให้ download ได้ที่ https://www.terraform.io/downloads.html

- เมื่อ download เสร็จก็จะได้ไฟล์ zip  จากนั้นให้ extract ไฟล์ออกมา ซึ่งจะเป็นได้ไฟล์ "terraform.exe" 

- ผู้ใช้สามารถ copy ไฟล์ "terraform.exe" ไปไว้ใน folder ที่ต้องการได้   จากตัวอย่างนี้จะทำการ copy ไปไว้ที่ C:\

- ให้ไปที่ Control Panel >  System >  Advanced system settings >  Environment Variables

- จากนั้นให้คลิกที่ "Path" แล้วคลิกที่ "Edit" ดังรูปด้านล่าง Blog-Terraform-DO-WindowsEnvi

- จากนั้นให้คลิก "New"  แล้วกำหนด path เป็น "C:\"  (หรือ path ที่ไฟล์ terraform.exe อยู่) ดังรูปด้านล่าง   จากนั้นคลิก "OK"

Blog-Terraform-DO-WindowsEnvi-Edit

- ให้ restart เครื่อง laptop/PC

- ให้เปิด Command Prompt เพื่อทดสอบคำสั่ง TerraformBlog-Terraform-DO-WindowsCMDTerraform

สมัครใช้งาน Digital Ocean

ถ้าผู้ใช้ยังไม่มี account ของ Digital Ocean ให้เข้าไปสมัครได้ที่ https://cloud.digitalocean.com

เมื่อสมัครเสร็จ  แล้ว login เข้าสู่หน้า console หลักของ Digital Ocean ก็จะมีลักษณะเหมือนดังรูปด้านล่าง  Blog-Terraform-DO-MainConsole

 

การนำ Token ของ Digital Ocean มาใช้

เนื่องจากว่าการที่จะให้ Terraform สามารถเข้าไปสร้าง resources ต่างๆ หรือสิ่งต่างๆบน  account Digital Ocean ของเราได้นั้น  ตัว Terraform จำเป็นต้องมี Token (คล้ายๆกับเป็น username และ password สำหรับการ login)

ดังนั้น เมื่อผู้ใช้มี account ของ Digital Ocean แล้วให้ทำการ login ไปยังหน้าของ Digital Ocean 

เลือกที่ API > Tokens/Keys > Generate New Token ดังรูปด้านล่าง

Blog-Terraform-DO-API-Token

 

 ตั้งชื่อ Token แล้วคลิกที่ "Generate New Token" ดังรูปด้านล่าง

Blog-Terraform-DO-TokenName

จากนั้นก็จะได้ Token ดังรูปด้านล่าง   ดังนั้นให้เก็บรักษาไว้ให้เป็นความลับ

ในกรณีที่ลืม Token หรือต้องการเปลี่ยนเป็น Token ตัวใหม่ ก็สามารถ ลบ แล้ว generate ขึ้นมาอีกทีได้เช่นกัน

Blog-Terraform-DO-ShowToken

 

การสร้าง SSH Key เพื่อเข้าสู่ Virtual Machine (Droplet)

โดยทั่วไปแล้วการเข้าสู่ Linux Virtual Machine สามารถใช้ username/password หรือโดยใช้  SSH Key 

ในตัวอย่างนี้แนะนำให้สร้าง SSH Key ก่อนที่จะทำการสร้าง Virtual Machine (Droplet) ด้วยเหตุผลที่ว่า หลังจากที่ Virtual Machine (Droplet) ถูกสร้างแล้ว เราจะสามารถ remote ผ่าน terminal โดยวิธี SSH ไปได้โดยตรง

หลักการของการใช้ SSH Key มีคร่าวๆว่า

(1) เราต้องเก็บรักษา Private Key ไว้ให้ดีที่สุด (อาจจะเก็บไว้ใน laptop ของเราก่อน) 

(2) เราจะกำหนด Public Key ให้กับ Linux Virtual Machine ที่เราต้องการ 

 (หมายเหตุ : แต่ละ cloud provider อาจจะมีวิธีอำนวยความสะดวกในการ generate ตัว SSH Key ที่แตกต่างกัน ,  แต่สำหรับ Digital Ocean ณ ขณะนี้  ผู้ใช้ต้อง "เริ่ม" ทำการ generate ตัว SSH key ที่ laptop/PC ของผู้ใช้เอง )

ที่ macOS หรือ Linux ให้เปิดโปรแกรม Terminal ขึ้นมา แล้วพิมพ์คำสั่ง "ssh-keygen"  (ให้พิมพ์ที่ path หรือ directory ไหนก็ได้)

เช่นเดียวกับ Windows ให้เปิดโปรแกรม Command Prompt แล้วพิมพ์คำสั่ง "ssh-keygen"  (ในกรณีที่ Windows10 ไม่ได้เปิดใช้งาน SSH ให้เปิด feature นี้ตามตัวอย่าง https://km.cc.swu.ac.th/archives/2762 )

หลักจาก พิมพ์คำสั่ง ssh-keygen แล้วกด Enter ก็จะมีให้กำหนด path และ passphrase โดยผู้ใช้มือใหม่ที่ยังไม่เคยสร้าง SSH Key แนะนำให้กด Enter ไปเรื่อย เพื่อความสะดวกในตัวอย่างนี้

 

ในกรณีที่ laptop/PC ของผู้ใช้มี SSH key อยู่ใน default directory ก็จะมีถามว่า ต้องการ "Overwrite" หรือไม่   โดยผู้ใช้อาจต้องตัดสินใจเองว่า

- ถ้าต้องการให้มีการสร้าง SSH key ทับกับของเก่า ก็พิมพ์ 'y' แล้ว กด Enter

- ถ้าไม่ต้องการให้มีการสร้าง SSH key ทับกับของเก่า ก็พิมพ์ 'n' แล้วกด Enter หรือ กด CTRL+C

- หรือจัดการให้ SSH key ตัวเดิมและตัวใหม่อยู่คนละ directory

ในกรณีที่ laptop/PC ของผู้ใช้ไม่มี SSH key ใน default directory ก็จะไม่มีถามเกี่ยวกับ "Overwrite"

 

ถ้ามีการถาม passphrase ให้กด Enter (เพื่อความสะดวกในตัวอย่างนี้)

 

เมื่อสร้าง SSH ก็จะได้ผลลัพธ์ประมาณนี้ ดังรูปด้านล่าง

ซึ่ง Private Key คือ /Users/jam/.ssh/id_rsa

และ Public Key คือ /Users/jam/.ssh/id_rsa.pub

 

ผู้ใช้ที่ใช้งาน macOS และ Linux สามารถดู Private key ด้วยคำสั่ง

cat ~/.ssh/id_rsa

และดู Public key ด้วยคำสั่ง

cat ~/.ssh/id_rsa.pub ดังรูปด้านล่าง  ซึ่ง ตัว Public key นี้จะถูกนำไปใช้ตอนเริ่มสร้าง Virtual Machine (Droplet) 

 

 

การสร้าง Virtual Machine (Droplet) บน Digital Ocean โดย Terraform

 

ให้สร้าง folder ขึ้นมาใหม่สำหรับ project นี้  เนื่องจากว่าจะต้องสร้างไฟล์ Terraform ไว้ใน folder นั้นๆ เพราะตัว software Terraform ที่เราติดตั้งไปแล้วนั้น จะเขาไปอ่านทุกๆไฟล์ของ Terraform ใน folderBlog-Terraform-DO-NewFolder

 

Terraform จะถูกเขียนด้วยภาษา HCL (Hashicorp Configuration Language) ซึ่งเป็น text file นามสกุล .tf ดังนั้น ผู้ใช้สามารถใช้ IDE หรือ text editor อะไรก็ได้ในการเขียน

ตัวอย่างนี้จะสร้างไฟล์ชื่อว่า droplet.tf ขึ้นมาดังรูปด้านล่าง

Blog-Terraform-DO-NewFolder-dropletFile

ในไฟล์ droplet.tf ให้ทำการพิมพ์คำสั่งด้านล่าง

ตัวอย่างนี้ได้อ้างอิงจาก document ของ Terraform  ที่ https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs

 

ความหมายของคำสั่งหรือบล๊อคต่างๆมีดังนี้

 คำสั่ง/บล๊อคคำสั่ง ความหมาย
terraform {
    required_providers {
        digitalocean = {
            source = "digitalocean/digitalocean"
            version = "2.11.1"
        }
    }
}
จะใช้งาน provider ที่ชื่อว่า DigitalOcean โดยจะใช้งาน version 2.11.1
variable "do_token" { }

ประกาศตัวแปรชื่อว่า do_token ไว้ ซึ่งเป็น input variable ซึ่งตอนที่รัน Terraform จะมีให้ใส่ค่าของตัวแปร

provider "digitalocean" {
   token = var.do_token
}

ที่ provider DigitalOcean นี้ จะมีการกำหนดค่าของ token  โดยเป็นตัวแปรที่ชื่อว่า var.do_token ก่อนหน้า (เพื่อให้ Terraform สามารถ login เพื่อใช้งาน API ได้)    

ผู้ใช้สามารถทดลอง hardcode โดยกำหนดค่าของ token ไปใน string ตรงๆได้ เช่น 

token = "xxxxxxxxxxx"
แต่วิธีนี้จะไม่แนะนำ ถ้า source code ของ Terraform ไปอยู่ใน GitHub หรือ GitLab ด้วยเหตุผลเรื่องความปลอดภัย
resource "digitalocean_ssh_key" "mykey01" {
    public_key = file("~/.ssh/id_rsa.pub")
}

บล๊อค resource ประเภทนี้คือ digitalocean_ssh_key โดยกำหนดชื่อตัวแปรว่า mykey01

ที่บรรทัด public_key = file("~/.ssh/id_rsa.pub") ผู้ใช้สามารถกำหนดที่อยู่ของ Public Key ตามที่ต้องการได้

 

resource "digitalocean_droplet" "mydroplet01" {
    image = "ubuntu-18-04-x64"
    name = "mydroplet01"
    region = "sgp1"
    size = "s-1vcpu-1gb"
    ssh_keys = [digitalocean_ssh_key.mykey01.fingerprint]
}
บล๊อค resource ของ 

digitalocean_droplet โดยกำหนดชื่อตัวแปรให้ว่า mydroplet01 

หน้าที่ของ resource digitalocean_droplet คือสร้าง Droplet หรือ Virtual Machine

จากนั้นก็กำหนด arguments ที่จำเป็นต่างๆภายในบล๊อค ได้แก่

- จะใช้ image ของ ubuntu version 18 โดยมีชื่อเรียกของ DigitalOcean ว่า "ubuntu-18-04-x64"

- Droplet ที่ถูกสร้างจะมีชื่อว่า  "mydroplet01"

- Droplet นี้จะถูกสร้างที่ Singapore region

- Size ของ Droplet คือ 1 vCPU และ มี memory 1 GB 

- ขณะที่ droplet จะถูกสร้าง จะมีการกำหนด Public key ให้กับ Droplet ดังกล่าว  จากคำสั่งที่ว่า "digitalocean_ssh_key.mykey01.fingerprint" จะเป็นการอ้างตัวแปรของบล๊อค digitalocean_ssh_key ที่มีตัวแปรชื่อว่า mykey01 (จากก่อนหน้านี้)

 

จะเห็นได้ว่า Terraform จะมีลักษณะการเขียนเป็นบล๊อค ซึ่งแต่ละบล๊อคไม่ได้สนใจลำดับว่าใครมาก่อนหรือหลัง   ผู้ใช้สามารถทดลองสลับบล๊อคได้ 

Terraform จะตีความของภาษา HCL นี้ไปในลักษณะ graph ซึ่งไม่ได้ทำงานเรียงลำดับเหมือน programming ทั่วไป 

 

เมื่อเขียนคำสั่ง HCL เสร็จแล้วก็ถึงเวลารัน

จากนั้นให้เปิดโปรแกรม Terminal บน macOS/Linux หรือ CommndPrompt บน Windows แล้วไปยัง directory ที่ไฟล์ .tf อยู่

 

(terraform init)

จากนั้นให้พิมพ์คำสั่ง "terraform init" เพื่อให้ Terraform เตรียม working directory ของตัว Terraform

หลังจากที่คำสั่ง terraform init ทำงานเสร็จแล้ว 

ถ้าไปดูยัง directory ดีๆโดยใช้คำสั่ง "ls -al" จะเห็นได้ว่ามีสองสิ่งที่เพิ่มเข้ามา

(1) folder ชื่อ ".terraform" ซึ่งเป็น local cache

(2) ไฟล์ ".terraform.lock.hcl" ซึ่งเป็นไฟล์ที่เอาไว้ใช้ lock version ของ dependency ต่างๆ

 

(terraform plan) 

ให้ทำการพิมพ์คำสั่ง "terraform plan" เพื่อดูว่าจาก HCL ที่เราเขียนไปนั้นจะไปเปลี่ยนแปลงอะไรที่ DigitalOcean บ้าง 

เนื่องจากว่าตัวอย่างนี้ได้กำหนดให้ผู้ใช้กรอกค่าของ token ผ่าน input variable ดังนั้นให้ผู้ใช้ copy แล้ว paste ตัว token ที่เตรียมไว้ลงไป (จากก่อนหน้านี้)  แล้วกด Enter

 

จากนั้นผู้ใช้ก็สามารถทราบได้ว่า  ที่ infrastructure นั้นจะมีอะไรถูกเปลี่ยนแปลงบ้าง เช่นจากตัวอย่างด้านล่างนี้ 

 

(terraform apply)

จากนั้นให้พิมพ์คำสั่ง "terraform apply" 

จากนั้นก็จะมีให้ใส่ token ให้กับ input variable (เหมือนก่อนหน้า)

หลังจากใส่ค่า token แล้ว ก็จะมีให้ยืนยันสำหรับให้คำสั่ง terraform apply ดำเนินการ

ให้ผู้ใช้พิมพ์ "yes" เพื่อยืนยัน แล้วกด Enter

 

 

Terraform ก็จะมีแจ้งให้ด้วยว่ากำลังสร้างอะไรใน infra อยู่

(ในบางกรณีอาจจะมีการ error เกิดขึ้น ตัว Terraform เองก็จะแจ้งให้ทราบ  เช่น ชื่อของ VPC ซ้ำกัน ทำให้ terraform apply ทำงานไม่สำเร็จ หรือ error อื่นๆ)

 

ถ้าไม่มี error ใดๆเกิดขึ้น  ที่หน้า console ของ DigitalOcean ก็จะมี Droplet ถูกสร้างขึ้น

Blog-Terraform-DO-MainConsole-NewDroplet

  

เมื่อ Droplet ถูก boot ขึ้นเสร็จแล้ว เราก็จะได้ public IP ดังรูปด้านล่าง

Blog-Terraform-DO-MainConsole-NewDroplet-IP

 

ให้ทำการทดสอบ remote ไปยัง Ubuntu Linux server โดยวิธี SSH 

สำหรับ macOS/Linux สามารถใช้คำสั่งตามรูปแบบด้านล่าง

เช่นเดียวกันสำหรับ Windows สามารถใช้งาน SSH ได้โดย Command Prompt ถ้าได้เปิดใช้งาน feature เพื่อใช้งาน SSH 

(ตามตัวอย่าง https://km.cc.swu.ac.th/archives/2762 )

<คำสั่ง ssh>  -i  <ที่อยู่ของ private key> <ชื่อผู้ใช้ root ซึ่งเป็น default>@<public IP ของ Droplet>

 

ในกรณีที่ยังไม่เคยเข้าใช้งานที่ host ตัวนี้ก็จะมีให้ยืนยันการเชื่อมต่อ

ให้พิมพ์ "yes" แล้ว กด Enter

 

ในบางครั้ง DigitalOcean อาจ assign ตัว public IP ตัวเดิม ให้กับ Droplet ตัวใหม่ ซึ่งทำให้เราไม่สามารถ SSH ไปได้เนื่องจากการจำตัว host ใน laptop/PC ของเรา ดังนั้นให้ใช้คำสั่ง

ssh-keygen -R <ตัว public ip>

แล้วให้ทดลอง ssh ใหม่

เมื่อ remote โดย ssh สำเร็จ ผู้ใช้ก็จะสามารถใช้งาน Ubuntu Linux Server ได้

 

(terraform destroy)

คำสั่ง "terraform destroy" เป็นคำสั่งที่ใช้ลบทุกอย่าง หรือลบทุก resource ที่เราเขียนภาษา HCL เอาไว้ (หรือเราได้นิยามเอาไว้)

ให้พิมพ์ "terraform destroy" จากนั้นใส่ token  

 

จากนั้นก็จะมีให้ยืนยันการลบ ให้พิมพ์ "yes" แล้วกด Enter

 

ถ้าการ destroy สำเร็จ  แล้วถ้าผู้ใช้ดูที่หน้า console ของ DigitalOcean ก็จะเห็นว่า Droplet ถูกลบไปเรียบร้อย 

 

(การลบเฉพาะบาง resource)

ในกรณีที่ผู้ใช้ได้สร้างหลายๆ resource ไว้โดยภาษา HCL การที่จะใช้คำสั่ง "terraform destroy" ก็จะเป็นการลบทุกๆ resource   

แต่ถ้าผู้ใช้ต้องการลบแค่บาง resource เช่น ต้องการลบแค่ 1 Droplet จากหลายๆ Droplets ดังนั้นให้ผู้ใช้ทำการ comment ให้กับภาษา HCL หรือลบบล๊อคของ code ไป   แล้วให้ใช้คำสั่ง "terraform apply" 

(สรุป)

HCL คือภาษาที่มีรูปแบบ "นิยาม" infrastructure (HCL ไม่ใช่ programming ที่มี logic การทำงานจากบนลงล่าง)   การใช้คำสั่ง "terraform apply" ก็คือการนำสิ่งที่เราได้นิยามไว้นั้น (HCL แต่ละบล๊อคที่เราเขียนไว้) ไป apply ให้กับ infrastructure   , การ comment บางบล๊อค/บางบรรทัด หรือ ลบบางบล๊อค/ลบบางบรรทัด ของ HCL ก็คือการที่เราไม่ต้องการ "นิยาม" สิ่งเหล่านั้นให้กับ infrastructure เราแล้ว

  

 

สนใจ solutions เกี่ยวกับ cloud หรือ Infrastructure as Code ติดต่อ : cloudsale@jastel.co.th

CloudDigitaloceanHashicorpInfrastructure-as-codeTerraform

Leave a comment

All comments are moderated before being published