แนะนำและทดลองใช้ Terraform ร่วมกับ Ansible แบบเข้าใจง่ายๆ 😎

Parinya B
Sirisoft
Published in
7 min readOct 8, 2021
แนะนำและทดลองใช้ Terraform ร่วมกับ Ansible

สวัสดีครับ วันนี้เราจมาแนะนำการใช้งาน Terraform ร่วมกับ Ansible
โดย Terraform จะใช้สำหรับการ Provisioning Infrastructure และ จะใช้ Terraform ทำการสั่ง Ansible ให้ทำการติดตั้งและเปิดใช้งาน Services

โดยก่อนอื่นเราจะมาอธิบายเบื้องต้นเกี่ยวกับ Terraform และ Ansible ก่อนนะครับ ว่าเจ้าสองตัวนี้มีไว้ใช้ทำงานอะไร 😎

เรามาเริ่มที่ Terraform กันก่อนนะครับ โดย Terraform จัดเป็น Tool ชนิดหนึ่งที่หลักๆมีไว้ใช้ในการ Provision infrastructure หรือเราจะเรียกว่า ใช้ Terraform ในการสร้าง *Infrastructure as A code (IaaS) ขึ้นมาโดย Provider หลักๆจะอยู่บน Cloud ครับ (Amazon, Google, Azure) และ Provider นอกเหนือจากบน Cloud (On-premise Environment) เช่น Vsphere

การทำงานของ Terrraform

โดย Terraform มีรูปแบบการเขียนโค้ดในลักษณะ Declarative Language เปรียบคือการเขียนโค้ดเพื่อระบุสถานะสิ้นสุดที่เราต้องการ และ Terraform มีหน้าที่ในการหาว่าการจะไปยัง desired state นั้นต้องทำอะไรบ้าง

“ Infrastructure as A code คือการสร้าง (Create), จัดการ (Manage)ทรัพยากร ภายใน Infrastructure ด้วยโค้ดเช่น การสร้างเครื่อง VM , สร้าง Security Group, กำหนด Network Interface ”

ข้อดีของ Terraform คือ

  1. Terraform สามารถใช้ในการ Track state ของ code ได้ว่ามีการเปลี่ยนแปลงอะไรไปบ้าง และสามารถเก็บ state ล่าสุดของ Infrastructure ตามโค้ดในไฟล์ที่เราสร้างไว้ได้
  2. Terraform รองรับการใช้งาน Automated test และ Life cycle management (ตั้งแต่เริ่ม Process การ Create Infrastructure จนไปถึงการ Destroy Infrastructure)
  3. Terraform ทำงานได้อย่างรวดเร็ว และโค้ดที่ใช้สร้าง, จัดการ Infrastructure เข้าใจง่าย

ต่อมาที่เราจะพูดถึงคือ Ansible เป็น Tool ชนิดหนึ่งที่ใช้ในการ Configuration management โดยเราสามารถใช้ Ansible ในการตั้งค่า Service (Enable, Disable หรือ Install) หรือแม้แต่ใช้ Ansible ในการรัน Script ต่างๆ

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

คุณสมบัติของ Ansible

โดยเพื่อนๆอาจจะสงสัยว่า Ansible จะสามารถนำมาใช้ Provision Infrastructure ได้หรือไม่ คำตอบคือ ได้เช่นกันครับ แต่ด้วยคุณสมบัติต่างๆทั้งหมดนั้น อาจจะไม่เอื้ออำนวยต่อการ Provision Infrastructure เท่าที่ควร ทำให้ ตัว Ansible ไม่นิยมนำมาใช้งานในด้านนี้ครับ
“โดยผมจะยกปัจจัยหลักของสิ่งที่ Ansibleไม่สามารถทำได้เมื่อเปรียบเทียบกับ Tool ที่นำมาใช้ Provisioning Infrastructure โดยเฉพาะอย่าง Terraform ครับ”

  • ไม่รองรับการจัดการเกี่ยวกับ Life cycle management และ ไม่สามารถตรวจสอบ State ล่าสุด ของการ Provisioning Infrastructure ตาม code ในไฟล์ที่เราสร้างไว้ได้ ยกตัวอย่างเช่น เราต้องการ Provision เครื่อง VM ทั้งหมด 5 เครื่อง (โดยเคย Provision ไปแล้วก่อนหน้านี้ 4 เครื่อง) ทำให้ต้อง Provision เพิ่มมาอีก 1 เครื่อง โดยเราต้องทำการแก้ไข code ตาม เครื่องที่เราต้องการจะ Provision มาเพิ่ม (ในขณะที่ Terraform สามารถตรวจสอบให้ได้เลยว่า ปัจจุบันมีกี่เครื่อง,ต้อง Provision ขึ้นมาเพิ่มอีกกี่เครื่องโดยไม่ต้องแก้ไข code )

ข้อดีของ Ansible คือ

  1. รองรับการ Provisioning Bare-metal Server ในขณะที่ Terraform ไม่สามารถทำได้
  2. รองรับการติดตั้ง Packaging เสริม หรือ ใช้งาน Template ต่างๆ ร่วมกับ Ansible เพื่อรองรับกับการใช้งานของผู้ใช้งาน
    (โดยผู้พัฒนา Ansible จัดทำเว็บไซต์ที่รวบรวมข้อมูลในส่วนของ Package หรือ Template ที่มี Vendor ต่างๆมาพัฒนาไว้รวมถึง Community ที่รวบรวมข้อมูลการใช้งาน โดยสามารถเข้าไปดูได้ตามลิ้งก์ ที่นี่ )

ก่อนที่เราจะยกตัวอย่างการใช้งาน Terraform ร่วมกับ Ansible เดี๋ยวผมจะขออธิบายการติดตั้ง Terraform และ Ansible ก่อนนะครับ 😉

การติดตั้ง Terraform
  1. ให้เพื่อนๆทำการกดคลิกเข้าที่ดาวน์โหลดได้ตามลิ้งก์ ที่นี่ ครับ
  2. ต่อมาให้ทำการเลือกระบบปฏิบัติการที่ต้องการจะติดตั้ง (ยกตัวอย่างเช่น MacOS, FreeBSD, Linux, Windows และ ระบบปฏิบัติการอื่นๆที่รองรับ)

*โดยในที่นี่เราจะยกตัวอย่างการติดตั้ง Terraform ลงบน ระบบปฎิบัติการ Linux
(สำหรับระบบปฎิบัติการอื่นๆ สามารถดูวิธีการติดตั้งที่ Website ของ Terraform ตามลิ้งก์
ที่นี่ ได้เลยครับ 💕 )

3. หลังจากการดาวน์โหลดเมื่อได้ไฟล์มาเรียบร้อยแล้ว
3.1 ให้เราทำการ unzip ไฟล์ที่ดาวน์โหลดมา โดยใช้ command ดังนี้

- unzip ตามด้วยชื่อไฟล์ที่ดาวน์โหลดมา

ตัวอย่างคำสั่งการ unzip ไฟล์ Terraform ที่ดาวน์โหลดมา

3.2 ทำการ SET path เพื่อที่จะเรียกใช้ Terraform จาก Path ไหนก็ได้
โดยเริ่มแรกให้เข้าไปที่ Path Home ของ user โดยใช้ command ดังนี้

cd /home/ตามด้วยชื่อuserที่เราใช้งานอยู่/

ตัวอย่าง Path Home ของ User ครับ (โดยในรูปจะเป็นของ User ชื่อว่า ec2-user)

เมื่อเข้าไปที่ path ดังกล่าวแล้ว ให้ใช้ command ดังนี้

vi .bash_profile

หลังจากเข้าหน้า Text editor ของไฟล์ .bash_profile เรียบร้อยแล้ว
ให้ทำการ ใส่ข้อมูลเข้าไปในไฟล์ 2 บรรทัดดังนี้

PATH=$PATH:$HOME/.local/bin:$HOME/bin:/ตามด้วยPATHของTerraform
export PATH

การตั้งค่า Environment Variable สำหรับ OS:Linux

3.3 ขั้นตอนสุดท้ายเราจะทดสอบรัน Terraform (เป็นคำสั่งในการตรวจสอบเวอร์ชัน) โดยใช้command ดังนี้
terraform --version

“ในกรณีที่ติดตั้งถูกต้องจะขึ้นแสดงเวอร์ชันดังรูปครับ”

รูป แสดงเวอร์ชันของ Terraform

หัวข้อต่อไปเราจะมาติดตั้ง Ansible กันครับ

*โดยในที่นี่เราจะยกตัวอย่างการติดตั้ง Ansible ลงบน ระบบปฎิบัติการ Linux (สำหรับ RHEL,CentOS, or Fedora เท่านั้น)

(สำหรับระบบปฎิบัติการอื่นๆ สามารถดูวิธีการติดตั้งที่ Website ของ Ansible ตามลิ้งก์
ที่นี่ ได้เลยครับ 💕 )

  1. ให้เพื่อนๆทำการติดตั้ง python (ในที่นี้จะใช้ Version 3.9)โดยใช้ command ดังนี้
    yum -y install python39
  2. ต่อมาให้เพื่อนๆติดตั้ง package pip (เป็น module ตัวหนึ่งที่ถูกสร้างโดย python)
    โดยใช้ command ดังนี้
    sudo yum install python39-pip
  3. เท่านี้เราก็จะสามารถติดตั้ง Ansible ได้แล้วโดยใช้ Package pip ที่ทำการติดตั้งมาในข้อ 2. โดยใช้ command ดังนี้
    pip3 install boto boto3 ansible
  4. ขั้นตอนสุดท้ายเราจะทำการตรวจสอบรัน Ansible (เป็นคำสั่งในการตรวจสอบเวอร์ชัน) โดยใช้ command ดังนี้
    ansible --version

“ในกรณีที่ติดตั้งถูกต้องจะขึ้นแสดงเวอร์ชันดังรูปครับ”

รูป แสดงเวอร์ชันของ Ansible

สุดท้ายเราจะทำการติดตั้ง GIT เพื่อความสะดวกในการจัดการโค้ด (Version Control)

โดยในที่นี้เราจะยกตัวอย่างการติดตั้งบน Linux (Red Hat Enterprise Linux, Oracle Linux, CentOS)ครับ ในกรณีที่ผู้ใช้งานต้องการติดตั้งใช้งาน Git ลงบน Windows , Mac os หรือสำหรับ Linux ที่มี Distribution อื่นๆ สามารถเข้าไปดูขั้นตอนติดตั้งและ ลิ้งค์การดาวน์โหลดได้ตามลิ้งก์ ที่นี่ ครับ

  1. ทำการติดตั้ง GIT เวอร์ชันล่าสุดโดยใช้ command ดังนี้
    yum -y install git

“ในกรณีที่ใช้คำสั่ง yum แล้วไม่สามารถติดตั้งแพคเกจ GIT ได้ ให้เข้าไปดาวน์โหลดไฟล์มาไว้ในเครื่องได้ตามลิ้งก์ ที่นี่ ครับ”

2. ในกรณีที่ติดตั้ง GIT เรียบร้อยแล้ว ให้ทำการใช้คำสั่งตรวจสอบเวอร์ชัน เพื่อเป็นการตรวจสอบว่า เครื่องของเราสามารถใช้ GIT ได้ โดยใช้ command ดังนี้
git --version

“ในกรณีที่ติดตั้งถูกต้องจะขึ้นแสดงเวอร์ชันดังรูปครับ”

3. ขั้นตอนสุดท้ายเราจะทำการ Config git ให้ทำการล็อกอินเข้าใช้สำหรับ Username หรืออีเมลของเรา (ใช้ได้สำหรับ GIT ทุกค่าย เช่น GITHUB , GITLAB , BITBUCKET

3.1 สำหรับ Config เพื่อที่จะล็อกอินเข้าใช้งานด้วย Username ให้ใช้ command ดังนี้
git config --global user.name “ใส่usernameของเราแทน

3.2 สำหรับ Config เพื่อที่จะล็อกอินเข้าใช้งานด้วย อีเมล ให้ใช้ command ดังนี้
git config --global user.email "ใส่อีเมลของเราแทน"

3.3 สุดท้ายให้เราทำการบันทึก Config Credential เพื่อที่จะไม่ต้องใส่รหัสหลายครั้ง
git config credential.helper store

หลังจากนี้เราจะมายกตัวอย่างการใช้งาน Terraform ร่วมกับ Ansible กันครับ

ตัวอย่างการใช้งาน Terraform ร่วมกับ Ansible
รูปตัวอย่างการใช้งาน Terraform ร่วมกับ Ansible

เริ่มต้น เราจะแนะนำไฟล์ที่จะใช้สร้าง Infrastructure as A code (Ias) ภายในโค้ดจะใช้สำหรับการ Provisioning เครื่อง EC2 ใน Platform Amazon Cloud ขึ้นมา โดยใช้ Terraform และใช้ Terraform ในการสั่งรัน Ansible เพื่อทำการติดตั้ง Apache Http Server

“เพื่อนๆ สามารถเข้าถึงข้อมูล Source code ทั้งหมดที่ผมได้ทำเป็นตัวอย่างไว้ใน GITLAB ตามลิ้งก์ ที่นี่ ครับ ”

ข้อมูล Source code ทั้งหมดใน GITLAB

โดยเราจะแนะนำไฟล์หลักๆที่สำคัญ 4 ไฟล์ดังนี้
1.main.tf
2.key.tfvars
3.variables.tf
4.apache.yaml

ข้อมูล code ภายในไฟล์ main.tf

เริ่มต้นที่ไฟล์ main.tf

โดยภายในไฟล์ main.tf เป็นไฟล์หลักที่ใช้ในการสั่งรัน Terraform ให้ทำการ Provisioning เครื่อง EC2 ขึ้นมา โดยภายในไฟล์หลักๆจะประกอบด้วยข้อมูลเครื่องEC2 สำหรับใช้ Provisioning , Resource ของเครื่อง EC2 ที่จะ Provisioning ขึ้นมา และคำสั่งที่จะทำการสั่ง Ansible ให้รัน playbook (ไฟล์.yaml) เพื่อติดตั้ง Apache Http Server”

locals {
vpc_id = “vpc-cc40a0aa
#ข้อมูล vpc-id ของเครื่อง EC2
subnet_id = "subnet-1ee76447"
#ข้อมูล subnet-id ของเครื่อง EC2
ssh_user = "ec2-user"
key_name = "aws-provision"
#ข้อมูล private key ภายในเครื่อง EC2
private_key_path = "~/.ssh/aws-provision"
#ข้อมูลที่อยู่ private key ภายในเครื่อง EC2
}
#กำหนดข้อมูลเครื่อง EC2 สำหรับใช้ในการ Provisioing เครื่อง EC2 อีกเครื่องขึ้นมา
provider "aws" {
access_key = var.aws_access_key
secret_key = var.aws_secret_key
region = var.aws_region
}
#กำหนดข้อมูล Provider ผู้ให้บริการเครื่อง VM(ในที่นี้เรายกตัวอย่างเป็น Amazon Web Services ) โดยข้อมูล access-key , secret-key และ region จะถูกดึงมาจากไฟล์ variables.tf
resource “aws_security_group” “apache” {
name = “apache_access”
vpc_id = local.vpc_id
#กำหนดชื่อ Security Group ของเครื่อง EC2 ที่สามารถขึ้นมา
ingress {
from_port = 22
to_port = 22
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
}
ingress {
from_port = 80
to_port = 80
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
}
egress {
from_port = 0
to_port = 0
protocol = “-1”
cidr_blocks = [“0.0.0.0/0”]
}}
#กำหนดข้อมูล Ingress (ขาเข้า) และ egress (ขาออก) สำหรับ service port ที่เราอนุญาติให้เข้าถึงเครื่อง EC2 ที่เราทำการ Provisioning ขึ้นมา
resource "aws_instance" "apache" {
ami = "ami-02b6d9703a69265e9"
subnet_id = "subnet-1ee76447"
instance_type = "t3a.nano"
associate_public_ip_address = true
security_groups = [aws_security_group.apache.id]
key_name = local.key_name
#กำหนดข้อมูล Resource เครื่อง EC2 ที่เราจะทำการ Provisioning ขึ้นมา
provisioner "remote-exec" {
inline = ["echo Done!"]
connection {
type = "ssh"
user = local.ssh_user
private_key = file(local.private_key_path)
host = aws_instance.apache.public_ip
}}
#กำหนดข้อมูล connection ของเครื่อง ec2 ที่พึ่งทำการ Provisioning ขึ้นมา
provisioner "local-exec" {
command = "ansible-playbook -i ${aws_instance.apache.public_ip}, --private-key ${local.private_key_path} apache.yaml"
}}
#ทำการใช้ Terraform สั่งให้ ansible ทำการรัน playbook(เพื่อติดตั้ง apache http server)
output "apache_ip" {
value = aws_instance.apache.public_ip
}
#ทำการ print public ip ของเครื่อง EC2 ที่พึ่งทำการ Provisioning ขึ้นมา

ต่อมาจะเป็นในส่วนไฟล์ variables ที่จะดึงมาใช้ในไฟล์ main.tf (ภายในจะประกอบด้วยข้อมูล access-key, secret-key, region ) โดยข้อมูลเหล่านี้เป็นข้อมูลผู้ใช้งานภายในเว็บไซต์ AWS โดยไฟล์ variables จะประกอบด้วยสองไฟล์ครับ คือ
1.key.tfvars
2. variables.tf

ข้อมูล region และ key ภายในไฟล์ key.tfvars

เริ่มที่ไฟล์ key.tfvars

“โดยภายในไฟล์ key.tfvars จะมีข้อมูล access-key , secret-key และ region ของผู้ใช้งานภายในเว็บไซต์ AWS”
(แนะนำให้ทำการปกป้องข้อมูลไว้โดยทำตามลิ้งก์
ที่นี่ ครับ)

aws_region="ap-southeast-1" 
#ข้อมูล region ผู้ใช้งานภายใน AWS
aws_access_key="ACCESSKEY"
#ข้อมูล access-key ผู้ใช้งานภายใน AWS
aws_secret_key="SECRETKEY"
#ข้อมูล secret-key ผู้ใช้งานภายใน AWS
กำหนดตัวแปร region และ key ภายในไฟล์ variables.tf

ต่อมาที่ไฟล์ variables.tf

“โดยภายในไฟล์ variables.tf จะมีกำหนดชื่อตัวแปรของ access-key , secret-key และ region ของผู้ใช้งานภายในเว็บไซด์ AWS ที่นำข้อมูลมาจากไฟล์ keys.tfvars”

(จุดประสงค์การทำไฟล์นี้ เพื่อที่ไฟล์ main.tf จะดึงค่า access-key , secret-key และ region ไปใช้งานเป็น variables ต่อได้)

variable "aws_region" {
type = string
}
variable "aws_access_key" {
type = string
}
variable "aws_secret_key" {
type = string
}
กำหนด Task ในการติดตั้งและสตาร์ท Apache Http Server

สุดท้ายจะเป็นไฟล์ apache.yaml

“โดยภายในไฟล์ apache.yaml จะทำการติดตั้ง Package และทำการสั่งรัน Apache Http Server ภายในเครื่อง EC2 ที่พึ่ง Provisioning ขึ้นมา ”

---- name: Setup for install
hosts: all
remote_user: ec2-user
become: yes
#กำหนดค่าของเครื่อง EC2 ที่จะติดตั้งและรัน package
tasks:
- name: Install apache http server packages
yum:
name: httpd
state: present
#ทำการสั่ง Ansible ให้ทำการติดตั้ง Package Apache Http Server
- name: ensure apache http server is running
service:
name: httpd
state: started
#ทำการสั่ง Ansible ให้ Start Package Apache Http Server

หลักๆคำสั่งที่จำเป็นสำหรับการใช้งาน Terraform มีดังนี้
1. คำสั่งที่ใช้ในการติดตั้ง Provider Plugins (ในที่นี้จะเป็นของProvider-AWS)
*ต้องทำการรันทุกครั้งหลังจากทำการใส่ข้อมูล code ภายใน Terraform เรียบร้อยแล้ว
terraform init

2. คำสั่งที่ใช้ในการตรวจสอบสถานะ state ภายในโค้ดของ Terraform โดยยังไม่ต้องทำการรันสั่งทำงานจริง (option -var-file คือการระบุไฟล์ variables)
terraform plan -var-file=key.tfvars

3. คำสั่งที่ใช้ในการรันสั่งทำงานโค้ดของ Terraform
* ในที่นี้ใช้สำหรับ Provisioning EC2 ขึ้นมา , ติดตั้งและรัน Apache Http Server (option -var-file คือการระบุไฟล์ variables)
terraform apply -var-file=key.tfvars

4. คำสั่งที่ใช้ในการทำลายเครื่อง EC2 ที่ทำการ Provisioning ขึ้นมา
(option -var-file คือการระบุไฟล์ variables)
terraform destroy -var-file=key.tfvars

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

“โดยเพื่อนๆสามารถดู Blog ที่น่าสนใจอีกมากมายของบริษัท Sirisoft ได้ ตามลิ้งก์
ที่นี่ ครับ”

ผู้เขียนขอบคุณมากสำหรับเพื่อนๆทุกคนที่ติดตามอ่านกันมาถึงตรงนี้ครับ 💕💕💕
Parinya B.

--

--