Variables คือหัวใจสำคัญของ Playbook ที่ทำให้ automation ยืดหยุ่นและนำกลับมาใช้ซ้ำได้ แทนที่จะเขียน value ตายตัวลงในแต่ละ task ตรง ๆ การใช้ variables ช่วยให้ปรับค่าต่าง ๆ ได้จากจุดเดียวโดยไม่ต้องแก้ไข task ทั้งหมด
บทความนี้อธิบายครบ 3 ประเภทหลักที่ใช้บ่อยที่สุด ได้แก่ Local Variables (กำหนดในไฟล์), Facts (ข้อมูลระบบที่รวบรวมอัตโนมัติ), และ Extra Variables (ส่งผ่าน command line) พร้อม Variable Precedence ที่บอกว่าเมื่อ variable ซ้ำกัน ตัวไหนจะ override
Local Variables: กำหนดค่าในไฟล์ Playbook
Local variables คือค่าที่กำหนดตรงในไฟล์ Playbook หรือไฟล์ vars แยกต่างหาก มี 3 วิธีหลัก
1. vars block ใน Playbook
วิธีที่ง่ายที่สุดคือกำหนดใต้ vars: ในไฟล์ Playbook โดยตรง
---
- name: Deploy web application
hosts: webservers
become: true
vars:
app_name: myapp
app_port: 8080
app_user: www-data
app_dir: /var/www/myapp
tasks:
- name: Create app directory
ansible.builtin.file:
path: "{{ app_dir }}"
owner: "{{ app_user }}"
state: directory
- name: Start application on port {{ app_port }}
ansible.builtin.debug:
msg: "Starting {{ app_name }} on port {{ app_port }}"
2. vars_files: โหลดจากไฟล์แยก
สำหรับ variables จำนวนมาก หรือที่ต้องแชร์ระหว่างหลาย Playbook ควรแยกออกเป็นไฟล์ YAML ต่างหาก
# vars/app_config.yml
app_name: myapp
app_port: 8080
db_host: localhost
db_name: myapp_db
db_user: app_user
# playbook.yml
---
- name: Configure application
hosts: webservers
become: true
vars_files:
- vars/app_config.yml
tasks:
- name: Configure database connection
ansible.builtin.template:
src: templates/db.conf.j2
dest: /etc/myapp/db.conf
3. host_vars และ group_vars: กำหนดต่อ host/group
สำหรับค่าที่แตกต่างกันในแต่ละ host หรือ group ให้สร้างไดเรกทอรี host_vars/ หรือ group_vars/ โดยชื่อไฟล์ต้องตรงกับชื่อ host หรือ group
# group_vars/webservers.yml (ใช้กับทุก host ใน group webservers)
nginx_worker_processes: 4
max_connections: 1024
# group_vars/dbservers.yml (ใช้กับทุก host ใน group dbservers)
mysql_max_connections: 200
innodb_buffer_size: 2G
# host_vars/web01.example.com.yml (ใช้กับ host นี้เท่านั้น)
nginx_worker_processes: 8 # override ค่าของ group
server_role: primary
ค่าใน host_vars/ จะ override ค่าใน group_vars/ เสมอ ทำให้ตั้งค่า default ที่ group แล้ว override เฉพาะ host ที่ต้องการได้
Ansible Facts: ข้อมูลระบบที่รวบรวมอัตโนมัติ
เมื่อรัน Playbook ระบบจะรวบรวม facts จากแต่ละ host อัตโนมัติก่อน task แรกเสมอ (ผ่าน module setup) ข้อมูลเหล่านี้เข้าถึงได้ผ่าน ansible_facts
---
- name: Show system facts
hosts: all
tasks:
- name: Display OS information
ansible.builtin.debug:
msg: >
Host: {{ ansible_hostname }}
OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
Memory: {{ ansible_memtotal_mb }} MB
Facts ที่ใช้บ่อยที่สุดในทางปฏิบัติ:
# ตรวจสอบ OS แล้วใช้ package manager ที่ถูกต้อง
- name: Install nginx (Debian/Ubuntu)
ansible.builtin.apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
- name: Install nginx (RHEL/CentOS)
ansible.builtin.dnf:
name: nginx
state: present
when: ansible_os_family == "RedHat"
Custom Facts: กำหนด Facts เอง
นอกจาก built-in facts ยังสร้าง custom facts ได้โดยวางไฟล์ .fact ไว้ที่ /etc/ansible/facts.d/ บน host
# /etc/ansible/facts.d/app.fact (ไฟล์บน remote host)
[app]
version=2.5.1
env=production
deploy_date=2026-04-16
# ใช้งานใน Playbook
- name: Show custom fact
ansible.builtin.debug:
msg: "App version: {{ ansible_local.app.app.version }}"
ปิด Fact Gathering เมื่อไม่จำเป็น
การรวบรวม facts ใช้เวลาประมาณ 1-2 วินาทีต่อ host เมื่อรัน Playbook ที่ไม่ต้องการ facts ควรปิดเพื่อประหยัดเวลา
---
- name: Quick task (no facts needed)
hosts: all
gather_facts: false # ปิด fact gathering
tasks:
- name: Create directory
ansible.builtin.file:
path: /tmp/mydir
state: directory
Extra Variables: ส่งค่าผ่าน Command Line
Extra variables หรือ -e / --extra-vars คือวิธีส่งค่า variable จากภายนอกตอนรัน command ซึ่งมี priority สูงสุด — override ทุก variable อื่นในระบบ
# ส่ง variable เดี่ยว
ansible-playbook deploy.yml -e "app_version=2.5.1"
# ส่งหลาย variables พร้อมกัน
ansible-playbook deploy.yml -e "app_version=2.5.1 env=staging"
# ส่งจากไฟล์ YAML (ใส่ @ นำหน้า)
ansible-playbook deploy.yml -e "@vars/override.yml"
Extra variables มีประโยชน์มากใน CI/CD pipeline โดยส่งค่า version หรือ environment ตอนรัน Playbook โดยไม่ต้องแก้ไขไฟล์ใด ๆ
---
- name: Flexible deployment
hosts: "{{ target_env }}_servers" # กำหนด host group จาก extra var
become: true
vars:
app_version: "1.0.0" # default ถ้าไม่ส่ง -e
tasks:
- name: Deploy version {{ app_version }}
ansible.builtin.debug:
msg: "Deploying {{ app_version }} to {{ target_env }}"
รัน Playbook นี้ด้วย:
ansible-playbook deploy.yml -e "target_env=staging app_version=2.5.1"
ansible-playbook deploy.yml -e "target_env=production app_version=2.5.1"
Variable Precedence: ลำดับความสำคัญ
เมื่อ variable ชื่อเดียวกันถูกกำหนดจากหลายที่พร้อมกัน ระบบจะใช้ลำดับ priority นี้ (จากต่ำไปสูง — ค่าที่มี priority สูงกว่าจะ override)
# ลำดับ priority จากต่ำ → สูง (ค่าสูงกว่า override ค่าต่ำกว่า)
# 1. role defaults
# 2. inventory vars (group_vars/all)
# 3. group_vars/<groupname>
# 4. host_vars/<hostname>
# 5. play vars (vars: ใน Playbook)
# 6. vars_files
# 7. set_fact / registered variables
# 8. extra vars (-e) ← สูงสุด
# ตัวอย่างเชิงปฏิบัติ:
# group_vars/all.yml
app_port: 80
# group_vars/production.yml
app_port: 443 # override ค่าจาก all
# host_vars/web01.yml
app_port: 8443 # override ค่าจาก production group
# command line: -e "app_port=9443"
# → ใช้ 9443 (override ทุกอย่าง)
หลักง่าย ๆ คือ: ยิ่งเฉพาะเจาะจงมากเท่าไร priority ยิ่งสูง และ -e สูงสุดเสมอ
set_fact: สร้าง Variable แบบ Dynamic
บางครั้งต้องคำนวณหรือสร้าง variable ระหว่างรัน Playbook ใช้ module set_fact สำหรับงานนี้
---
- name: Dynamic variables example
hosts: all
tasks:
- name: Set backup filename with timestamp
ansible.builtin.set_fact:
backup_file: "backup_{{ ansible_hostname }}_{{ ansible_date_time.date }}.tar.gz"
- name: Use the dynamic variable
ansible.builtin.debug:
msg: "Will create: {{ backup_file }}"
- name: Compute memory threshold (80% of total)
ansible.builtin.set_fact:
memory_threshold: "{{ (ansible_memtotal_mb * 0.8) | int }}"
- name: Show threshold
ansible.builtin.debug:
msg: "Alert when memory > {{ memory_threshold }} MB"
ตัวแปรที่สร้างด้วย set_fact จะคงอยู่ตลอด play และสามารถใช้ใน task ถัด ๆ ไปได้ทันที
สรุป
การเลือกประเภท variable ที่เหมาะสมทำให้ Playbook อ่านง่ายและจัดการได้ดี: ใช้ vars_files + group_vars สำหรับค่าที่แตกต่างกันตาม environment, ใช้ facts สำหรับข้อมูลระบบที่ต้องการ real-time, และใช้ -e สำหรับค่าที่ต้องการ override ตอนรัน เช่น version ใน pipeline
จุดที่ต้องระวัง: Variable Precedence คือสาเหตุหลักของ bug ที่หาสาเหตุยาก ถ้า Playbook ทำงานผิดปกติให้ตรวจสอบว่ามี variable ชื่อเดียวกันถูกกำหนดจากหลายที่หรือไม่ โดยเพิ่ม task - debug: var=ชื่อ_variable เพื่อดูค่าที่ใช้จริง

