Ansible Tags: รันเฉพาะ Tasks ที่ต้องการด้วย Tags

Tags ใน Ansible ช่วยให้รันเฉพาะ tasks ที่ต้องการโดยไม่ต้องรัน Playbook ทั้งหมด เช่น รันเฉพาะ task ที่เกี่ยวกับ config โดยข้าม task install, หรือข้าม task ที่ใช้เวลานานเมื่อทดสอบ

บทความนี้อธิบายวิธีกำหนด tag, การใช้ --tags และ --skip-tags, special tags ที่มีใน Ansible, และ pattern การใช้ tags ที่เหมาะกับ Playbook ขนาดใหญ่

กำหนด Tags บน Task

ใส่ tags: ลงใน task โดยตรง ระบุได้ทั้ง string เดียวหรือหลาย tag เป็น list

---
- name: Configure web server
  hosts: webservers
  tasks:
    - name: Install nginx
      package:
        name: nginx
        state: present
      tags:
        - install
        - nginx

    - name: Deploy nginx config
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      tags:
        - configure
        - nginx

    - name: Restart nginx
      service:
        name: nginx
        state: restarted
      tags:
        - restart
        - nginx

รัน Task ด้วย –tags และ –skip-tags

ใช้ --tags เพื่อรันเฉพาะ tasks ที่มี tag ที่ระบุ และ --skip-tags เพื่อข้าม tasks ที่มี tag นั้น

# รันเฉพาะ tasks ที่มี tag "configure"
ansible-playbook site.yml --tags configure

# รันหลาย tag (OR logic — รัน task ที่มี tag ใดก็ได้)
ansible-playbook site.yml --tags "configure,restart"

# ข้าม tasks ที่มี tag "install"
ansible-playbook site.yml --skip-tags install

# ดู tasks ทั้งหมดและ tags โดยไม่รันจริง
ansible-playbook site.yml --list-tasks
ansible-playbook site.yml --list-tags

Tags บน Play และ Block

Tags ใส่ได้ไม่เฉพาะ task เดียว แต่ใส่บน play ทั้งหมด หรือ block ของ tasks ก็ได้ ทำให้จัดกลุ่มได้ง่ายโดยไม่ต้องใส่ซ้ำทุก task

---
# Tags บน play ทั้งหมด
- name: Install all packages
  hosts: all
  tags: install
  tasks:
    - name: Install nginx
      package:
        name: nginx
        state: present

    - name: Install mysql
      package:
        name: mysql-server
        state: present

# Tags บน block
- name: Configure services
  hosts: all
  tasks:
    - name: Configure nginx block
      tags: configure
      block:
        - name: Deploy nginx config
          template:
            src: nginx.conf.j2
            dest: /etc/nginx/nginx.conf

        - name: Deploy ssl config
          template:
            src: ssl.conf.j2
            dest: /etc/nginx/ssl.conf

Special Tags: always และ never

Ansible มี special tags 2 ตัวที่มีพฤติกรรมพิเศษ: always รันเสมอแม้ไม่ได้ระบุ tag และ never ไม่รันเว้นแต่เรียกชื่อ tag นั้นโดยตรง

---
- name: Deployment with special tags
  hosts: all
  tasks:
    - name: Pre-flight check (always run)
      debug:
        msg: "Checking system health before deploy"
      tags: always   # รันเสมอ แม้รัน --tags configure

    - name: Deploy application
      shell:
        cmd: /opt/scripts/deploy.sh
      tags: deploy

    - name: Run database migration (dangerous — manual only)
      shell:
        cmd: python manage.py migrate
      tags: never    # ต้องรัน --tags migrate จึงจะทำงาน

    - name: Run migration explicitly
      shell:
        cmd: python manage.py migrate --run-syncdb
      tags:
        - never
        - migrate

Pattern ที่ใช้บ่อยคือใส่ tags: always บน pre-flight checks, notification tasks, หรือ cleanup tasks ที่ต้องรันทุกครั้งไม่ว่าจะเลือก tag ไหน

Tags กับ Roles

ใส่ tag บน Role ทั้งหมดในระดับ Playbook ทำให้รันหรือข้าม Role ทั้งหมดได้ในครั้งเดียว

---
- name: Full server setup
  hosts: all
  become: true
  roles:
    - role: common
      tags: common

    - role: nginx
      tags:
        - nginx
        - webserver

    - role: mysql
      tags:
        - mysql
        - database

    - role: myapp
      tags:
        - app
        - deploy
# รันเฉพาะ Role myapp
ansible-playbook site.yml --tags deploy

# รันทุก Role ยกเว้น mysql
ansible-playbook site.yml --skip-tags database

# รัน nginx และ myapp
ansible-playbook site.yml --tags "webserver,deploy"

Best Practice: Tag Taxonomy

การตั้งชื่อ tag อย่างเป็นระบบช่วยให้ทีมใช้งานได้สอดคล้องกัน โดยแนะนำให้แบ่ง tag ออกเป็นหมวดหมู่ชัดเจน

# Tag taxonomy ที่แนะนำ

# ตามประเภทงาน
install       # ติดตั้ง packages
configure     # แก้ไข config files
restart       # restart/reload services
deploy        # deploy application code
migrate       # database migration (ใช้คู่กับ never)

# ตาม component
nginx
mysql
redis
app

# ตามความถี่ใช้งาน
full          # รัน Playbook ทั้งหมด
quick         # เฉพาะ task ที่เร็ว

สรุป

Tags เปลี่ยน Playbook จาก all-or-nothing เป็นเครื่องมือที่ยืดหยุ่น Pattern ที่ควรจำ: ใช้ always สำหรับ health checks และ notification, ใช้ never สำหรับ task อันตรายที่ต้องรันแบบ explicit, และตั้งชื่อ tag ตาม taxonomy ที่ตกลงกันในทีม

ข้อควรระวัง: การมี tag มากเกินไปโดยไม่มีมาตรฐานทำให้ Playbook ยากต่อการ maintain ควรมี tag taxonomy เอกสารกำกับ และ review การใช้ tag อย่างสม่ำเสมอ