ansible-logo
Ansible เป็น configuration management ที่เป็น agentless ซึ่งไม่ต้อง require agent เหมือนพวก puppet, Chef, Salt การทำงานของ ansible จะทำงานผ่าน SSH ดังนั้นแค่เครื่องสามารถ remote ด้วย SSH ได้ก็ทำงานได้

Ansible เขียนเป็นไฟล์ YAML เดียวก็สามารถทำงานได้แล้ว แต่ถ้าหากมีขั้นตอนการทำงานที่เยอะจะทำให้ยุ่งยากในการแก้ไข และนำกลับมาใช้ใหม่ ดังนั้นในบทความนี้ผมจะมาอธิบาย directory layout เพื่อให้คนที่เริ่มศึกษาได้เข้าใจหลักการสร้างและกำหนด directory layout ได้ถูกต้อง

Directory Layout

ตัวอย่างข้างล่างคือ Top level ของ directory และไฟล์ต่างๆ

├── production                # ไฟล์ inventory สำหรับ production servers
├── staging                   # ไฟล์ inventory สำหรับ staging
├── dev                       # ไฟล์ inventory สำหรับ development
├── group_vars/
│   ├── group1                # กำหนด variable ในแต่ละ group โดยอ้างอิงจาก inventory file
│   ├── group2                # 
│   └── all                   # ถ้าหากต้องการกำหนด variable เป็น default value หรือใช้งานได้ทั้งหมด
├── host_vars/
│   └── hostname1             # กำหนด variable แบบเฉพาะเจาะจงเครื่อง โดยชื่อไฟล์คือชื่อเครื่องใน inventory file
├── library/                  # custom modules (optional)
├── filter_plugins/           # custom filter plugins (optional)
├── site.yml                  # ไฟล์ playbook หลัก
├── nginxservers.yml          # ไฟล์ playbook ของ nginx server
├── mysqlservers.yml          # playbook ของ MySQL server
│
└── roles/
    ├── common/               # role ชื่อ common
    │   ├── tasks/            # 
    │   │   └── main.yml      #  tasks ต่างๆของ role
    │   ├── handlers/         #
    │   │   └── main.yml      # handlers file
    │   ├── templates/        # Folder สำหรับเก็บไฟล์ template
    │   │   └── ntp.conf.j2   #  - ไฟล์ templates ลงท้ายด้วย .j2
    │   ├── files/            #  ไฟล์ที่ต้องการให้ ansible ทำการ copy ไปยัง folder ที่ต้องการ
    │   │   ├── bar.txt       #  
    │   │   └── foo.sh        #   
    │   ├── vars/             #
    │   │   └── main.yml      #  variable ในระดับ role
    │   ├── defaults/         #
    │   │   └── main.yml      #  lower priority variable สำหรับ role
    │   └── meta/             #
    │       └── main.yml      #  role dependencies
    │
    ├── webtier/              # role ชื่อ webtier โดยมีโครงสร้างของ folder เหมือนกับ common role
    └── monitoring/           # role ชื่อ monitoring โดยมีโครงสร้างของ folder เหมือนกับ common role

จากโครงสร้าง folder ข้างบนจะสามารถแยกอธิบายเป็นส่วนๆได้ตามนี้

Inventory file

ใช้ define hostname และ group ของ hostname เพื่อให้ ansible ทราบว่าจะไปรันที่ server ไหนบ้าง จากตัวอย่างโครงสร้าง file และ folder ด้านบนมีการกำหนด inventory file ไว้ 3 ไฟล์ด้วยกันคือ production, staging และ dev เพื่อเวลาเรียกใช้งานสามารถระบุ environment ที่ต้องการรันได้เลย

ตัวอย่างการรันด้วยการระบุ inventory file

# ansible-playbook -i production site.yml

ตัวอย่าง inventory file

[thailand-nginxservers]
www-th-1.ezylinux.com
www-th-2.ezylinux.com

[singapore-nginxservers:vars]  # Apply variables using :vars
www-sg-1.ezylinux.com
ntp_server=ntp.sg.ezylinux.com

[thailand-mysqlservers]
db-th-1.ezylinux.com
db-th-2.ezylinux.com

[singapore-mysqlservers]
db-sg-1.ezylinux.com

# nginxservers in both Thailand and Singapore 
[nginxservers:children]   # Make groups of groups using the :children suffix.
thailand-nginxservers
singapore-nginxservers

# mysqlservers in both Thailand and Singapore
[dbservers:children]
thailand-mysqlservers
singapore-mysqlservers

# everything in the Thaland
[thailand:children]
thailand-nginxservers
thailand-mysqlservers

# everything in the Singapore
[singapore:children]
singapore-nginxservers
singapore-mysqlservers

Group Variables

เป็นการกำหนด variable สำหรับ group ต่างๆที่ได้ define ไว้ที่ inventory file โดยมีข้อกำหนดว่า

  1. ชื่อไฟล์ต้องเป็นชื่อ group บน inventory file
  2. อยู่ใน folder group_vars

ตัวอย่างเช่น กลุ่ม server ที่ thailand ให้ใช้ ntp server ที่ไทย

---
# file: group_vars/thailand
ntp: th.pool.ntp.org

Host Variables

เป็นการกำหนด variable สำหรับราย host ที่ได้ถูก define ไว้ที่ inventory file

ตัวอย่างเช่น กำหนดให้ db-th-1.ezylinux.com รัน mysql ด้วย port 3307

---
# file: host_vars/db-th-1.ezylinux.com
mysql_port: 3307

Roles

ใน ansible เราสามารถแยกงานต่างๆ ออกเป็น role เพื่อให้ง่ายต่อการใช้งาน แก้ไข และนำกลับมาใช้กับงานใหม่ ตัวอย่างเช่น ตั้งชื่อ folder ว่า common ใน roles หมายถึงว่า role ชื่อ common และภายใน folder common ก็มี folder ต่างๆ ตามตัวอย่าง

** role สามารถมี dependency ซึ่งจะช่วยให้สามารถกำหนดลำดับการทำงานของ role ได้

└── roles/
    ├── common/               # role ชื่อ common
    │   ├── tasks/            # ไฟล์ YAML ที่กำหนดขั้นตอนการทำงาน
    │   ├── handlers/         # ไฟล์ YAML ที่จะถูก notify จาก task เพื่อให้ทำงานที่กำหนด
    │   ├── templates/        # Folder สำหรับเก็บไฟล์ Jinja2 template
    │   ├── files/            # ไฟล์ที่ต้องการให้ ansible ทำการ copy ไปยัง folder ที่ต้องการ
    │   ├── vars/             # variable ที่เกี่ยวข้องกับ role นี้
    │   ├── defaults/         # lower priority variables
    │   └── meta/             # role dependencies