Inventory file คือหัวใจของการกำหนดว่าจะจัดการ server ไหนบ้าง ทุกครั้งที่รัน playbook หรือ ad-hoc command ระบบต้องรู้ว่า managed node มีกี่เครื่อง อยู่ที่ address ไหน และแต่ละเครื่องเป็นส่วนหนึ่งของ group ใด การออกแบบ inventory ที่ดีตั้งแต่แรกช่วยให้ expand ระบบได้โดยไม่ต้องแก้ playbook
บทความนี้อธิบายโครงสร้าง inventory file แบบ INI และ YAML พร้อมการจัดกลุ่ม hosts ตั้งค่า variables และเทคนิคที่ใช้บ่อยในโปรเจกต์จริง
รูปแบบ INI — เริ่มต้นง่ายที่สุด
รูปแบบ INI เป็น default ที่เขียนได้เร็วที่สุด เหมาะสำหรับโปรเจกต์ขนาดเล็กถึงกลาง ชื่อ group อยู่ในวงเล็บเหลียมเป็น section header แต่ละบรรทัดใต้ section คือ 1 host ที่จะถูก manage
# inventory.ini
[webservers]
web1.example.com
web2.example.com
192.168.1.10
[dbservers]
db1.example.com ansible_port=2222
db2.example.com
[monitoring]
mon1.example.com
# กำหนด variables สำหรับทุก host ใน inventory
[all:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file=~/.ssh/control_key
รูปแบบ YAML — อ่านง่ายกว่าในโปรเจกต์ใหญ่
สำหรับ inventory ที่ซับซ้อนหรือต้องการ nested groups รูปแบบ YAML มีโครงสร้างชัดเจนและ maintain ได้ดีกว่าในระยะยาว โดยทุก group อยู่ภายใต้ children ของ all
# inventory.yml
all:
children:
webservers:
hosts:
web1.example.com:
web2.example.com:
ansible_port: 8022
dbservers:
hosts:
db1.example.com:
db2.example.com:
monitoring:
hosts:
mon1.example.com:
vars:
ansible_user: ubuntu
Groups พิเศษ: all และ ungrouped
ทุก inventory มี 2 groups ที่สร้างอัตโนมัติ ได้แก่ all ซึ่งครอบคลุม host ทุกเครื่องในไฟล์ และ ungrouped ซึ่งรวม host ที่ไม่ได้อยู่ใน group ใดเลย การระบุ group ใน command จะจำกัดขอบเขตการทำงานให้แม่นยำกว่าการรันกับ all เสมอ
# รัน task กับทุก host
ansible all -m ping
# รัน task กับ group เฉพาะ
ansible webservers -m ping
Nested Groups — จัดกลุ่มซ้อนกัน
สามารถสร้าง parent group ที่รวม child group หลาย ๆ กลุ่มเข้าด้วยกัน ช่วยให้รัน playbook กับทั้ง environment ได้ด้วยชื่อ group เดียว โดยใช้ [groupname:children] ในรูปแบบ INI
[webservers]
web1.example.com
web2.example.com
[dbservers]
db1.example.com
# production รวม webservers + dbservers
[production:children]
webservers
dbservers
[production:vars]
env=production
Host Aliases — ชื่อแทน IP
เมื่อต้องการใช้ชื่อที่จดจำง่ายแทน IP address หรือ hostname ที่ยาว ใช้ alias ร่วมกับ ansible_host ได้ ทำให้ output ที่แสดงผลอ่านง่ายขึ้นและ inventory file มีความหมายมากขึ้น
[webservers]
web-prod ansible_host=203.0.113.10
web-staging ansible_host=10.0.1.5 ansible_port=2222
db-primary ansible_host=10.0.1.20
Host Range — กำหนดหลาย Host ด้วยรูปแบบสั้น
เมื่อมี server หลายเครื่องที่ชื่อต่างกันแค่ตัวเลขหรือตัวอักษร ใช้ range notation เพื่อประหยัดการเขียนได้ รูปแบบนี้ช่วยลดความผิดพลาดจากการพิมพ์รายชื่อ host ทีละบรรทัด
[webservers]
# ครอบคลุม web1 ถึง web10
web[1:10].example.com
[dbservers]
# ครอบคลุม db-a, db-b, db-c
db-[a:c].example.com
ตรวจสอบ Inventory ก่อนใช้งาน
ใช้ ansible-inventory เพื่อตรวจสอบว่าระบบอ่านไฟล์ inventory ถูกต้องก่อนรัน playbook จริง คำสั่งนี้แสดง hosts, groups, และ variables ที่จะถูก apply ทั้งหมด
# แสดง hosts ทั้งหมดในรูปแบบ JSON
ansible-inventory -i inventory.ini --list
# แสดงโครงสร้าง groups แบบ tree
ansible-inventory -i inventory.ini --graph
# ดู variables ของ host เฉพาะ
ansible-inventory -i inventory.ini --host web1.example.com
ข้อควรระวัง
มีหลายจุดที่มักทำให้ inventory ทำงานไม่ตามที่คาด ได้แก่ การใส่ host ซ้ำกันในหลาย group (ไม่ใช่ปัญหา เพราะ host สามารถอยู่หลาย group ได้พร้อมกัน), การใช้ชื่อ group เป็น keyword เช่น all หรือ local, และการลืมระบุ ansible_user ทำให้ system พยายาม login ด้วยชื่อ user ของ control node ซึ่งอาจไม่มีอยู่บน managed node นอกจากนี้ควรระมัดระวังเรื่อง indentation ใน YAML format เพราะ space ผิดเพียงระดับเดียวทำให้ parser อ่าน structure ผิดพลาดได้
สรุป
Inventory file กำหนดขอบเขตของระบบที่ต้องการ manage ทั้งหมด การจัดกลุ่มที่ดีช่วยให้รัน playbook ตรงกลุ่มเป้าหมาย และ nested groups ทำให้จัดการหลาย environment ในไฟล์เดียวได้สะดวก ควรเริ่มด้วยรูปแบบ INI สำหรับโปรเจกต์เล็ก และย้ายไป YAML เมื่อ inventory เริ่มซับซ้อนขึ้น

