เปลี่ยนการตั้งค่าเซิร์ฟเวอร์ด้วยมือ ให้กลายเป็นโค้ดที่ทำงานอัตโนมัติ รวดเร็ว และทำซ้ำได้
การใช้คน (System Admin) รีโมท (SSH) เข้าไปพิมพ์คำสั่งทีละเครื่อง หรือคลิกผ่านหน้าเว็บ UI
"It works on my machine!"
IaC (Infrastructure as Code) คือแนวปฏิบัติในการจัดการและเตรียมความพร้อม (Provisioning) โครงสร้างพื้นฐานทางไอที (เซิร์ฟเวอร์, เครือข่าย, ฐานข้อมูล) ผ่าน "ไฟล์โค้ด (Code)" แทนที่จะใช้การตั้งค่าด้วยมือ
ตั้งค่าเซิร์ฟเวอร์ 100 เครื่องได้เร็วเท่ากับ 1 เครื่อง ลดเวลาจากหลายสัปดาห์เหลือเพียงไม่กี่นาที
กำจัดปัญหา Snowflake เซิร์ฟเวอร์ทุกเครื่องที่ถูกสร้างจากโค้ดชุดเดียวกัน จะมีหน้าตาและสภาพแวดล้อมเหมือนกันเป๊ะ 100%
เมื่อใช้ร่วมกับ Git เราจะรู้ได้ทันทีว่า "ใคร" เปลี่ยนแปลงค่าเซิร์ฟเวอร์ "อะไร" และ "เมื่อไหร่" (Audit Trail)
IaC เป็นรากฐานสำคัญที่ทำให้กระบวนการ DevOps สมบูรณ์
เน้นการ "สร้าง" ทรัพยากร (เช่น เช่า VM ใหม่, สร้าง VPC, สร้าง Load Balancer บน Cloud)
เน้นการ "ตั้งค่า" ภายในเซิร์ฟเวอร์ที่มีอยู่แล้ว (เช่น ติดตั้ง Nginx, สร้าง User, แก้ไขไฟล์ Config)
*ในโลกความเป็นจริง มักใช้ร่วมกัน เช่น ใช้ Terraform สร้าง VM และใช้ Ansible เข้าไปติดตั้ง Software
สองแนวคิดหลักในการสั่งงาน Infrastructure
บอก "ขั้นตอน (How)" ว่าต้องทำอย่างไรทีละขั้น
บอก "ผลลัพธ์ (What)" ที่ต้องการ แล้วให้ระบบจัดการหาวิธีเอง
คุณต้องระบุขั้นตอนอย่างละเอียด (Step-by-step) คล้ายกับการเขียน Bash Script
# ตัวอย่าง Bash Script (Imperative)
apt-get update
apt-get install -y nginx
systemctl start nginx
systemctl enable nginx
คุณระบุเฉพาะ "สภาวะสุดท้ายที่ต้องการ (Desired State)" เครื่องมือจะไปหาวิธีทำให้มันเกิดขึ้นเอง
# ตัวอย่าง Ansible (Declarative)
- name: Ensure Nginx is installed
apt:
name: nginx
state: present # ขอแค่ให้มี
- name: Ensure Nginx is running
service:
name: nginx
state: started # ขอแค่ให้รันอยู่
| Feature | Imperative (How) | Declarative (What) |
|---|---|---|
| Focus | บอกขั้นตอนว่าต้องทำอย่างไร | บอกผลลัพธ์สุดท้ายที่อยากได้ |
| Learning Curve | เริ่มต้นง่าย (เหมือนเขียน Script) | ต้องเรียนรู้ Syntax ของเครื่องมือ |
| Idempotency | มักจะไม่มี (ต้องเขียนเช็คเงื่อนไขเอง) | มีในตัว (Built-in) ทำซ้ำได้ปลอดภัย |
| Examples | Bash scripts, Chef (mostly) | Terraform, Ansible, Kubernetes YAML |
Ansible คือ Open-source IT Automation Tool ที่พัฒนาโดย Red Hat ใช้สำหรับ Configuration Management, Application Deployment, และ Task Automation
เขียนด้วยภาษา Python แต่ผู้ใช้เขียนคำสั่งด้วยรูปแบบ YAML ที่อ่านง่ายเหมือนภาษาอังกฤษ
เรียบง่ายทรงพลัง และเน้นการทำงานแบบ Declarative (Desired State)
ไม่ต้องลงโปรแกรม (Agent) ไว้ที่เครื่องปลายทาง ต่างจาก Chef/Puppet ทำให้ระบบเบาและปลอดภัย
ทำงานผ่านโปรโตคอลความปลอดภัยพื้นฐานที่มีอยู่แล้ว (SSH สำหรับ Linux, WinRM สำหรับ Windows)
ไม่ต้องเรียนรู้ภาษาโปรแกรมมิ่งใหม่ การเขียน Playbook เป็นรูปแบบข้อความที่มนุษย์อ่านเข้าใจทันที
Push Model: ผลักดันคำสั่งจากเครื่องหลักไปยังเครื่องเป้าหมาย
เครื่องคอมพิวเตอร์หลักที่เราใช้สั่งงาน (อาจเป็น Laptop ของเรา หรือ Server กลาง)
เครื่องเป้าหมายที่ Ansible จะเข้าไปจัดการ (เช่น Web Server, Database Server)
ไฟล์ที่เก็บรายชื่อ IP Address หรือ Hostname ของ Managed Nodes ทั้งหมด
# ไฟล์ inventory (มักใช้ชื่อ hosts หรือ inventory.ini)
[webservers]
192.168.1.10
192.168.1.11
web1.example.com
[dbservers]
192.168.1.20
[all:vars]
ansible_user=ubuntu # กำหนด user สำหรับ SSH
ansible_ssh_private_key_file=~/.ssh/id_rsa
*เราสามารถจัดกลุ่ม (Group) เครื่องเข้าด้วยกัน เช่นกลุ่ม [webservers] เพื่อสั่งงานรวดเดียวทั้งกลุ่ม
Modules คือชิ้นส่วนโปรแกรมสำเร็จรูป (Scripts) ที่ทำงานเฉพาะเจาะจง Ansible มี Built-in modules มาให้หลายพันตัว (Batteries included)
apt, yum, dnf, pip, npm
copy, file, template, fetch
service, systemd
command, shell, script
เมื่อสั่งรัน Ansible จะส่ง Module (Python script) ไปยัง Managed Node เพื่อทำงาน และลบทิ้งเมื่อเสร็จสิ้น
เป็นภาษาที่ใช้เก็บข้อมูลโครงสร้าง (Data Serialization) ออกแบบมาให้อ่านและเขียนได้ง่ายมากที่สุด "Human-readable"
.yml หรือ .yaml: ) ต้องมีเสมอ# คอมเมนต์ใช้เครื่องหมาย Hashtag
name:
John Doeage:
30is_developer:
true# สังเกตการย่อหน้า
skills:
frontend: React
backend: Python
จับคู่กุญแจกับค่าของมัน
รายการข้อมูล ใช้เครื่องหมายขีด (Dash)
เปรียบเทียบข้อมูลเดียวกัน ทำไมเราถึงรัก YAML
<person>
<name>John</name>
<age>30</age>
<skills>
<skill>Linux</skill>
<skill>Git</skill>
</skills>
</person>
{
"person": {
"name": "John",
"age": 30,
"skills": [
"Linux",
"Git"
]
}
}
---
person:
name: John
age: 30
skills:
- Linux
- Git
Playbook คือไฟล์ YAML ที่เปรียบเสมือน "คู่มือการทำงาน (Instruction Manual)" ที่เราระบุไว้ว่าอยากให้ Ansible เข้าไปทำอะไรในเซิร์ฟเวอร์เป้าหมายบ้าง
ไฟล์ 1 ไฟล์
การจับคู่เป้าหมาย (Hosts) กับงานที่ต้องทำ
งานย่อยๆ ที่ทำทีละลำดับ
คำสั่งเฉพาะเจาะจง (เช่น apt, copy)
--- (สัญลักษณ์บอกการเริ่มต้นไฟล์ YAML)
- name: Update Web Servers # นี่คือ Play (List item แรก)
hosts: webservers # เป้าหมาย (อ้างอิงจาก Inventory)
become: true # ขอสิทธิ์ Root (sudo)
tasks: # รายการงานที่จะทำใน Play นี้
- name: Task 1 - Update apt cache
apt: # เรียกใช้ Module 'apt'
update_cache: yes
- name: Task 2 - Do something else
...
---
- name: Setup Nginx Web Server
hosts: webservers
become: yes
tasks:
- name: Ensure nginx is installed
apt:
name: nginx
state: present
- name: Ensure nginx is running and enabled
service:
name: nginx
state: started
enabled: yes
apt-get install nginx)systemctl start nginx และ systemctl enable nginx)
$ ansible-playbook -i hosts install_nginx.yml
Idempotency คือแนวคิดที่ว่า "คุณสามารถสั่งทำงาน (Execute) สิ่งเดิมซ้ำกี่ครั้งก็ได้ แต่ผลลัพธ์สุดท้ายจะยังคงเหมือนเดิม และจะไม่ทำสิ่งที่ไม่จำเป็น"
ในส่วนของปฏิบัติการ (Laboratory) เราจะเปลี่ยนเครื่องส่วนตัวของคุณเป็น Control Node เพื่อจัดการ Infrastructure
ansible ping (Ad-hoc command)ssh-keygen) และความพร้อมของระบบ Linux ไว้ให้ดี!
เปลี่ยนคอมพิวเตอร์ของคุณให้เป็น Control Node เพื่อสั่งติดตั้งและตั้งค่า Web Server อัตโนมัติ
คุณจะต้องใช้ระบบปฏิบัติการ Linux จำนวน 2 ส่วน (อาจจะเป็น VM, WSL2, หรือเครื่องจริงใน LAN)
เครื่องที่จะใช้เขียนโค้ดและยิงคำสั่ง (เช่น Ubuntu บน WSL2, macOS)
เครื่องที่จะถูกติดตั้ง Nginx (เช่น VM บน VirtualBox หรือวง LAN)
sudo ได้เปิด Terminal บนเครื่องของคุณ (WSL2 หรือ Linux) แล้วรันคำสั่งต่อไปนี้
# 1. อัปเดตรายการ Package
$ sudo apt update
# 2. ติดตั้ง Ansible
$ sudo apt install ansible -y
# 3. ตรวจสอบเวอร์ชันเพื่อยืนยันการติดตั้ง
$ ansible --version
ansible [core 2.x.x] ...
เพื่อให้ Ansible ทำงานอัตโนมัติได้ราบรื่น ควรตั้งค่า SSH Key เพื่อไม่ให้ต้องพิมพ์รหัสผ่านทุกครั้ง
# 1. สร้าง SSH Key บน Control Node (กด Enter ผ่านไปเรื่อยๆ)
$ ssh-keygen
# 2. Copy Key ไปยัง Managed Node (เปลี่ยน IP และ Username)
$ ssh-copy-id target_user@192.168.x.x
# 3. ทดสอบ Login (ถ้าเข้าได้โดยไม่ถาม Password ถือว่าสำเร็จ!)
$ ssh target_user@192.168.x.x
*หมายเหตุ: หากใช้สภาพแวดล้อมที่ห้ามใช้ SSH Key สามารถใช้การถาม Password ตอนรัน Playbook ได้โดยเพิ่ม -k -K
สร้างโฟลเดอร์สำหรับโปรเจกต์และสร้างไฟล์สมุดหน้าเหลือง (Inventory) เพื่อระบุเป้าหมาย
$ mkdir my-ansible-lab && cd my-ansible-lab
$ nano hosts
# เพิ่มเนื้อหาลงในไฟล์ hosts:
[webservers]
192.168.x.x # (เปลี่ยนเป็น IP ของ VM/Managed Node ของคุณ)
[webservers:vars]
ansible_user=target_user # (เปลี่ยนเป็นชื่อ user ของเครื่องเป้าหมาย)
ใช้ Ansible ping module เพื่อตรวจสอบว่า Control Node คุยกับ Managed Node ได้หรือไม่
# สั่ง ping ไปยังกลุ่ม webservers โดยใช้ไฟล์ hosts ที่เราสร้าง
$ ansible webservers -i hosts -m ping
# ผลลัพธ์ที่ควรได้:
192.168.x.x | SUCCESS => {
"changed": false,
"ping": "pong"
}
ก่อนเขียน Playbook ให้สร้างไฟล์ HTML ง่ายๆ บนเครื่อง Control Node เพื่อเตรียม Copy ไปยัง Web Server
$ nano index.html
# พิมพ์โค้ด HTML เบื้องต้น:
<html>
<head><title>Ansible Lab</title></head>
<body style="background-color: #282c34; color: white; text-align: center; margin-top: 50px;">
<h1>🚀 Hello DevOps!</h1>
<p>This web server was configured automatically by Ansible.</p>
</body>
</html>
สร้างไฟล์ setup-web.yml และกำหนดโครงสร้างของ Play พร้อม Task แรก
$ nano setup-web.yml
---
- name: Setup Web Server
hosts: webservers
become: yes # ขอสิทธิ์ sudo ในการทำงาน
tasks:
- name: Install Nginx package
apt: # ใช้โมดูล apt (สำหรับ Ubuntu/Debian)
name: nginx
state: present # ต้องการให้มีการติดตั้งอยู่ (Declarative)
update_cache: yes # เหมือนสั่ง apt update ก่อน
ต่อจาก Task เดิม ให้เพิ่มคำสั่ง copy นำไฟล์ HTML ไปวางที่เซิร์ฟเวอร์ปลายทาง
... (ต่อจากโค้ดสไลด์ที่แล้ว)
- name: Copy custom index.html
copy: # ใช้โมดูล copy
src: index.html # ไฟล์ต้นทางที่เครื่อง Control Node
dest: /var/www/html/index.html # ตำแหน่งปลายทางบน Managed Node
mode: '0644' # กำหนด Permission ให้ไฟล์
ปิดท้ายด้วยการใช้โมดูล service เพื่อให้มั่นใจว่า Nginx ทำงานอยู่
... (ต่อจากโค้ดสไลด์ที่แล้ว)
- name: Ensure Nginx is started and enabled
service: # ใช้โมดูล service
name: nginx # ชื่อ service
state: started # ให้รันอยู่เสมอ
enabled: yes # ให้ start อัตโนมัติเมื่อเปิดเครื่อง (systemctl enable)
ถึงเวลาแสดงพลังของ IaC! รัน Playbook เพื่อตั้งค่าเซิร์ฟเวอร์ทั้งหมดด้วยคำสั่งเดียว
# รัน Playbook โดยใช้ Inventory (-i) ที่เราสร้างไว้
$ ansible-playbook -i hosts setup-web.yml -K
(-K จะถามรหัสผ่าน sudo (BECOME password) ของเครื่องเป้าหมาย)
PLAY [Setup Web Server] *************************************************
TASK [Gathering Facts] **************************************************
ok: [192.168.x.x]
TASK [Install Nginx package] ********************************************
changed: [192.168.x.x]
TASK [Copy custom index.html] *******************************************
changed: [192.168.x.x]
PLAY RECAP **************************************************************
192.168.x.x : ok=4 changed=2 unreachable=0 failed=0
นำ IP Address ของเครื่อง Managed Node (เช่น http://192.168.x.x) ไปเปิดใน Browser บนเครื่องของคุณ
This web server was configured automatically by Ansible.
$ ansible-playbook -i hosts setup-web.yml -K
คุณจะเห็นว่าสถานะเปลี่ยนจาก changed เป็น ok ทั้งหมด เพราะ Ansible รู้ว่าติดตั้งเรียบร้อยแล้วและไม่มีการเปลี่ยนแปลง
สาเหตุ: Ansible เชื่อมต่อ SSH ไปเครื่องเป้าหมายไม่ได้
วิธีแก้: เช็ค IP ว่าถูกต้องไหม, เครื่องเปิดอยู่หรือเปล่า, และทดสอบใช้คำสั่ง ssh user@IP ด้วยตัวเองดูก่อน
สาเหตุ: Task ต้องการสิทธิ์ Root (become: yes) แต่ไม่ได้ให้รหัสผ่าน
วิธีแก้: เติม -K หรือ --ask-become-pass ตอนรันคำสั่ง ansible-playbook
สาเหตุ: ย่อหน้าผิด หรือใช้ Tab แทน Space
วิธีแก้: ตรวจสอบการเว้นวรรคให้ตรงกันทุกบรรทัดระดับเดียวกัน และเช็คเครื่องหมาย : (ต้องมีช่องว่างตามหลังเสมอ)
สาเหตุ: ไม่พบไฟล์ต้นทางที่กำหนดใน src
วิธีแก้: ตรวจสอบว่าคุณสร้างไฟล์ index.html ไว้ในโฟลเดอร์เดียวกับที่รันคำสั่ง ansible หรือระบุ path ผิด
hosts (Inventory)setup-web.yml (Playbook)index.htmlansible-playbook สำเร็จ (แสดง PLAY RECAP)