22/02/2026 | อ.บอม (Bom) | SiamCafe.net Since 1997
ถ้าคุณเป็น Sysadmin ที่ต้อง SSH เข้าเครื่อง Server ทีละเครื่อง พิมพ์คำสั่งซ้ำๆ ทุกวัน อัพเดท Package, แก้ Config, Restart Service — คุณกำลังเสียเวลาไปกับงานที่ Robot ทำได้ดีกว่า Ansible คือ Robot ตัวนั้น
Ansible เป็นเครื่องมือ Automation ที่เรียบง่ายที่สุดในตลาด ไม่ต้องติดตั้ง Agent บนเครื่องปลายทาง ไม่ต้องเรียนภาษาใหม่ เขียนเป็น YAML ที่อ่านรู้เรื่องเหมือนภาษาอังกฤษธรรมดา และที่สำคัญที่สุดคือ Idempotent — รันกี่ครั้งก็ได้ผลเหมือนเดิม ไม่ทำซ้ำสิ่งที่ทำไปแล้ว
บทความนี้ผมจะพาคุณเรียนรู้ Ansible จากศูนย์ พร้อมตัวอย่าง Playbook จริงที่ใช้ได้ทันที ตั้งแต่ Setup Server ครั้งแรก ติดตั้ง Docker Deploy Application จนถึง Hardening Security ครับ
Ansible เป็น IT Automation Platform ที่พัฒนาโดย Red Hat ใช้สำหรับ:
ทำไม Sysadmin ควรใช้ Ansible:
| แบบเดิม (Manual) | แบบใช้ Ansible |
|---|---|
| SSH เข้าทีละเครื่อง | รันครั้งเดียวทำทุกเครื่อง |
| จำคำสั่งไม่ได้ ต้องเปิด Note | เขียนเป็น Playbook เก็บใน Git |
| รันซ้ำอาจพัง | Idempotent — รันกี่ครั้งก็ปลอดภัย |
| คนใหม่มา ต้องสอนใหม่ทั้งหมด | อ่าน Playbook = เข้าใจทั้งระบบ |
| เครื่องใหม่ต้อง Setup จากศูนย์ | รัน Playbook เครื่องเดิมเป๊ะ |
# Ubuntu/Debian
sudo apt update
sudo apt install -y ansible
# หรือติดตั้งผ่าน pip (ได้ version ล่าสุด)
pip3 install ansible
# ตรวจสอบ
ansible --version
# ansible [core 2.17.x]
# python version = 3.12.x
Inventory คือรายชื่อ Server ที่ Ansible จะจัดการ เขียนเป็น INI หรือ YAML:
# inventory.ini
[webservers]
web1 ansible_host=192.168.1.101
web2 ansible_host=192.168.1.102
[dbservers]
db1 ansible_host=192.168.1.201
[monitoring]
prometheus ansible_host=192.168.1.50
# ตัวแปรสำหรับทุกเครื่อง
[all:vars]
ansible_user=admin
ansible_ssh_private_key_file=~/.ssh/id_ed25519
ansible_python_interpreter=/usr/bin/python3
# ทดสอบว่า Ansible เข้าถึงได้ทุกเครื่อง
ansible all -i inventory.ini -m ping
# Output ที่ถูกต้อง:
# web1 | SUCCESS => {"ping": "pong"}
# web2 | SUCCESS => {"ping": "pong"}
# db1 | SUCCESS => {"ping": "pong"}
Ad-Hoc คือการรันคำสั่งเดียวบนหลายเครื่องพร้อมกัน ไม่ต้องเขียน Playbook:
# ดู Uptime ทุกเครื่อง
ansible all -i inventory.ini -a "uptime"
# ดู Disk Usage เฉพาะ Web Servers
ansible webservers -i inventory.ini -a "df -h"
# Restart NGINX ทุก Web Server
ansible webservers -i inventory.ini -m service -a "name=nginx state=restarted" --become
# ติดตั้ง Package
ansible all -i inventory.ini -m apt -a "name=htop state=present" --become
# Copy ไฟล์ไปทุกเครื่อง
ansible all -i inventory.ini -m copy -a "src=./motd.txt dest=/etc/motd" --become
Playbook คือไฟล์ YAML ที่บอก Ansible ว่าจะทำอะไร กับเครื่องไหน ตามลำดับ:
# setup-server.yml
---
- name: Initial Server Setup
hosts: all
become: yes # รันด้วย sudo
tasks:
- name: Update apt cache
apt:
update_cache: yes
cache_valid_time: 3600
- name: Upgrade all packages
apt:
upgrade: dist
- name: Install essential packages
apt:
name:
- vim
- curl
- wget
- htop
- tree
- unzip
- git
- ufw
- fail2ban
state: present
- name: Set timezone to Bangkok
timezone:
name: Asia/Bangkok
- name: Enable UFW
ufw:
state: enabled
policy: deny
- name: Allow SSH
ufw:
rule: allow
port: "22"
proto: tcp
- name: Ensure fail2ban is running
service:
name: fail2ban
state: started
enabled: yes
# รัน Playbook
ansible-playbook -i inventory.ini setup-server.yml
# PLAY RECAP *********************************************
# web1 : ok=8 changed=5 unreachable=0 failed=0
# web2 : ok=8 changed=5 unreachable=0 failed=0
# db1 : ok=8 changed=5 unreachable=0 failed=0
สังเกต changed=5 หมายความว่า 5 Tasks มีการเปลี่ยนแปลงจริง ถ้ารันซ้ำอีกครั้ง จะได้ changed=0 เพราะทุกอย่างเป็นไปตามที่ต้องการแล้ว นี่คือ Idempotent!
# vars ใน Playbook
---
- name: Configure Web Server
hosts: webservers
become: yes
vars:
http_port: 80
server_name: "siamcafe.net"
doc_root: "/var/www/html"
tasks:
- name: Create document root
file:
path: "{{ doc_root }}"
state: directory
owner: www-data
group: www-data
# templates/nginx-vhost.conf.j2
server {
listen {{ http_port }};
server_name {{ server_name }};
root {{ doc_root }};
index index.html;
access_log /var/log/nginx/{{ server_name }}_access.log;
error_log /var/log/nginx/{{ server_name }}_error.log;
location / {
try_files $uri $uri/ =404;
}
}
# ใช้ใน Playbook:
- name: Deploy NGINX vhost config
template:
src: templates/nginx-vhost.conf.j2
dest: "/etc/nginx/sites-available/{{ server_name }}.conf"
notify: Reload NGINX
Handler จะรันก็ต่อเมื่อถูก Notify จาก Task ที่มีการ changed เท่านั้น ป้องกัน Restart Service โดยไม่จำเป็น:
handlers:
- name: Reload NGINX
service:
name: nginx
state: reloaded
- name: Restart MySQL
service:
name: mysql
state: restarted
ถ้า Config ไม่เปลี่ยน Template Task จะไม่ Trigger Notify ดังนั้น NGINX จะไม่ถูก Reload ประหยัด Downtime
เมื่อ Playbook ยาวขึ้น ควรแยกเป็น Role ซึ่งมีโครงสร้างมาตรฐาน:
# สร้าง Role
ansible-galaxy init roles/nginx
# โครงสร้าง Role
roles/nginx/
├── defaults/
│ └── main.yml # Default Variables
├── files/ # Static Files
├── handlers/
│ └── main.yml # Handlers
├── meta/
│ └── main.yml # Role Metadata
├── tasks/
│ └── main.yml # Tasks หลัก
├── templates/ # Jinja2 Templates
└── vars/
└── main.yml # Variables
# roles/nginx/tasks/main.yml
---
- name: Install NGINX
apt:
name: nginx
state: present
- name: Deploy vhost config
template:
src: vhost.conf.j2
dest: "/etc/nginx/sites-available/{{ server_name }}.conf"
notify: Reload NGINX
- name: Enable vhost
file:
src: "/etc/nginx/sites-available/{{ server_name }}.conf"
dest: "/etc/nginx/sites-enabled/{{ server_name }}.conf"
state: link
notify: Reload NGINX
- name: Ensure NGINX is running
service:
name: nginx
state: started
enabled: yes
# ใช้ Role ใน Playbook
---
- name: Setup Web Servers
hosts: webservers
become: yes
roles:
- nginx
- certbot
- monitoring-agent
# เข้ารหัสไฟล์ Variables ที่มี Password
ansible-vault create vars/secrets.yml
# เนื้อหา secrets.yml (เข้ารหัสแล้ว):
db_password: "SuperSecretP@ss"
api_key: "sk-xxxxxxxxxxxx"
ssl_cert_passphrase: "cert-pass-123"
# ใช้ใน Playbook
vars_files:
- vars/secrets.yml
# รัน Playbook ที่มี Vault
ansible-playbook -i inventory.ini site.yml --ask-vault-pass
# หรือใส่ Password File
ansible-playbook -i inventory.ini site.yml --vault-password-file ~/.vault_pass
# lemp-stack.yml — ติดตั้ง Linux + NGINX + MariaDB + PHP
---
- name: Install LEMP Stack
hosts: webservers
become: yes
vars:
php_version: "8.3"
db_name: "webapp"
db_user: "webuser"
db_password: "{{ vault_db_password }}"
tasks:
- name: Install NGINX
apt:
name: nginx
state: present
- name: Install MariaDB
apt:
name:
- mariadb-server
- mariadb-client
- python3-mysqldb
state: present
- name: Install PHP {{ php_version }}
apt:
name:
- "php{{ php_version }}-fpm"
- "php{{ php_version }}-mysql"
- "php{{ php_version }}-curl"
- "php{{ php_version }}-mbstring"
- "php{{ php_version }}-xml"
- "php{{ php_version }}-zip"
- "php{{ php_version }}-gd"
state: present
- name: Create MySQL database
mysql_db:
name: "{{ db_name }}"
state: present
- name: Create MySQL user
mysql_user:
name: "{{ db_user }}"
password: "{{ db_password }}"
priv: "{{ db_name }}.*:ALL"
state: present
- name: Start all services
service:
name: "{{ item }}"
state: started
enabled: yes
loop:
- nginx
- mariadb
- "php{{ php_version }}-fpm"
# security-hardening.yml
---
- name: Security Hardening
hosts: all
become: yes
tasks:
- name: Disable root SSH login
lineinfile:
path: /etc/ssh/sshd_config
regexp: "^PermitRootLogin"
line: "PermitRootLogin no"
notify: Restart SSH
- name: Disable password authentication
lineinfile:
path: /etc/ssh/sshd_config
regexp: "^PasswordAuthentication"
line: "PasswordAuthentication no"
notify: Restart SSH
- name: Set SSH MaxAuthTries
lineinfile:
path: /etc/ssh/sshd_config
regexp: "^MaxAuthTries"
line: "MaxAuthTries 3"
notify: Restart SSH
- name: Install and configure fail2ban
apt:
name: fail2ban
state: present
- name: Deploy fail2ban config
copy:
content: |
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
dest: /etc/fail2ban/jail.local
notify: Restart fail2ban
- name: Configure automatic security updates
apt:
name: unattended-upgrades
state: present
- name: Enable automatic updates
copy:
content: |
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";
dest: /etc/apt/apt.conf.d/20auto-upgrades
handlers:
- name: Restart SSH
service:
name: sshd
state: restarted
- name: Restart fail2ban
service:
name: fail2ban
state: restarted
# docker-deploy.yml
---
- name: Deploy Docker Application
hosts: webservers
become: yes
tasks:
- name: Install Docker prerequisites
apt:
name:
- apt-transport-https
- ca-certificates
- curl
- gnupg
state: present
- name: Add Docker GPG key
apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present
- name: Add Docker repository
apt_repository:
repo: "deb https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
state: present
- name: Install Docker
apt:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin
state: present
- name: Pull and run NGINX container
community.docker.docker_container:
name: web-app
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- "/var/www/html:/usr/share/nginx/html:ro"
restart_policy: unless-stopped
state: started
pip install ansible-lint && ansible-lint site.ymlansible-playbook site.yml --checkansible-playbook site.yml --tags nginx💡 อ่านเพิ่มเติม: iCafeForex.com — แหล่งความรู้ Forex และ Gold Trading จากผู้เชี่ยวชาญ | XMSignal.com/th — สัญญาณเทรด XM
📚 แนะนำ: SiamLancard.com — รีวิวอุปกรณ์ IT | iCafeForex สอนเทรด Forex
อนาคตของ infrastructure management คือ automation และ Ansible คือจุดเริ่มต้นที่ดีที่สุดครับ
เริ่มต้นเรียน Ansible วันนี้ ลงทุนเวลาแค่สองสัปดาห์ คุณจะได้ทักษะที่ใช้ได้ตลอดอาชีพการทำงาน ประหยัดเวลาได้หลายชั่วโมงต่อสัปดาห์ครับ
สำหรับ sysadmin ที่ดูแล server มากกว่า 5 เครื่อง Ansible จะช่วยประหยัดเวลาและลดความผิดพลาดได้อย่างมาก ทุกอย่างที่คุณทำด้วยมือวันนี้ สามารถเขียนเป็น playbook แล้วรันอัตโนมัติได้ทุกครั้ง ไม่ต้องกังวลว่าจะลืมขั้นตอนใดขั้นตอนหนึ่งครับ
Ansible เปลี่ยนวิธีที่ sysadmin ทำงานอย่างแท้จริง จากการต้อง SSH เข้าทีละเครื่องพิมพ์คำสั่งซ้ำๆ มาเป็นเขียน playbook ครั้งเดียวแล้วรันได้กับ server ร้อยตัวพร้อมกัน ได้ผลเหมือนกันทุกครั้ง จากประสบการณ์ที่ใช้ Ansible มากว่า 8 ปี ผมพบว่า ROI ของการเรียนรู้ Ansible คุ้มค่ามาก ลงทุนเวลาเรียนสัก 2 สัปดาห์ แล้วจะประหยัดเวลาได้หลายชั่วโมงต่อสัปดาห์ตลอดอาชีพการทำงานของคุณ สิ่งสำคัญคือเริ่มจาก playbook ง่ายๆ ก่อน แล้วค่อยๆ เพิ่มความซับซ้อนทีละนิดครับ
Ansible เปลี่ยนวิธีที่ Sysadmin ทำงาน จากการ SSH เข้าทีละเครื่องพิมพ์คำสั่งซ้ำๆ มาเป็นเขียน Playbook ครั้งเดียวแล้วรันได้ทุกเครื่อง ทุกครั้ง ได้ผลเหมือนเดิมเสมอ
สิ่งที่ควรทำตอนนี้:
เมื่อคุณเริ่มใช้ Ansible แล้ว คุณจะไม่อยากกลับไป SSH ทีละเครื่องอีกเลยครับ
สนใจ Automation ไม่เฉพาะ Server? iCafeForex.com สอน Forex Automation ด้วย EA Trading อัตโนมัติ — เหมือน Ansible Playbook ที่เทรดให้คุณ 24/7 ไม่ต้องนั่งเฝ้าจอ
รับ สัญญาณเทรด Forex ฟรีจาก XMSignal — Automate การลงทุนของคุณ