Ansible vs Shell Script: เมื่อไหร่ควรใช้ Ansible แทน Bash

เมื่อเริ่มต้นใช้ Ansible หนึ่งในคำถามที่พบบ่อยที่สุดคือ “แล้วเมื่อไหร่ควรใช้ Ansible แทน Bash script ที่เขียนอยู่แล้ว?” ทั้งสองเป็นเครื่องมือที่ใช้ automate งาน sysadmin ได้เหมือนกัน แต่มีจุดแข็งและข้อจำกัดที่ต่างกันอย่างชัดเจน

บทความนี้อธิบายความแตกต่างระหว่าง Ansible กับ Shell Script พร้อมเกณฑ์ชัดเจนว่าสถานการณ์ไหนควรใช้อะไร เพื่อให้ตัดสินใจได้ถูกต้องและไม่ over-engineer โดยไม่จำเป็น

Shell Script คืออะไรและทำอะไรได้บ้าง

Shell Script (Bash, sh, zsh) คือไฟล์คำสั่ง shell ที่รันตามลำดับ เหมาะกับงาน automation ง่าย ๆ บนเครื่องเดียว เช่น backup ไฟล์, ติดตั้ง package, หรือ restart service ข้อดีคือรันได้บนทุกระบบที่มี shell โดยไม่ต้องติดตั้งอะไรเพิ่ม

อย่างไรก็ตาม Shell Script มีข้อจำกัดสำคัญ: ไม่ Idempotent โดย default (รันซ้ำอาจทำให้เกิดปัญหา), จัดการ error handling ยาก, และเมื่อต้องรันบนหลายเซิร์ฟเวอร์ต้องใช้ loop + SSH เอง ซึ่งซับซ้อนและเสี่ยงผิดพลาด

Idempotency ในตัว

ความแตกต่างที่ใหญ่ที่สุดคือ Idempotency Ansible module ส่วนใหญ่ตรวจสอบสถานะปัจจุบันก่อนทำงาน เช่น module package จะติดตั้ง package เฉพาะเมื่อยังไม่ได้ติดตั้ง ถ้าติดตั้งแล้วก็ข้ามไป ไม่มีผลข้างเคียง

Shell Script ต้องเขียน check เองว่า “ถ้า X ยังไม่มีให้ทำ Y” ซึ่งทำให้โค้ดซับซ้อนและมักถูกข้ามเพราะขี้เกียจเขียน ส่งผลให้รันซ้ำไม่ได้อย่างปลอดภัย

Multi-host Management

Ansible ออกแบบมาสำหรับจัดการหลายเซิร์ฟเวอร์พร้อมกัน การรัน task บน 50 เซิร์ฟเวอร์ทำได้ด้วย Inventory file เพียงไฟล์เดียว Shell Script ต้องวน loop ผ่าน SSH list เอง ซึ่งยุ่งยากและ debug ยากมากเมื่อมีบางเครื่อง fail

Error Handling และ Reporting

Ansible รายงานผลแต่ละ task อย่างชัดเจน บอกว่าเครื่องไหน OK, changed, หรือ failed และหยุดทำงานอัตโนมัติเมื่อเกิด error ที่กำหนด Shell Script ต้องเขียน error handling เองทุกบรรทัด และ output มักอ่านยากเมื่อรันหลายเซิร์ฟเวอร์

Reusability ผ่าน Roles

Ansible มีระบบ Roles ที่ช่วย package และ reuse configuration ได้ เช่น Role สำหรับตั้งค่า Nginx สามารถใช้ซ้ำในหลายโปรเจกต์ Shell Script ที่เขียนสำหรับโปรเจกต์หนึ่ง มักต้องแก้ไขมากก่อนจะใช้กับโปรเจกต์อื่น

เมื่อไหร่ควรใช้ Shell Script

Shell Script ยังคงเหมาะสมในหลายสถานการณ์ ไม่ควรมองว่าเครื่องมือนี้แทน Shell ได้ทุกกรณี

  • งานบนเครื่องเดียว ไม่ซับซ้อน: เช่น cron job backup ไฟล์, rotate logs, หรือ simple health check ที่รันบนเครื่องเดิมทุกวัน
  • ต้องการ output pipe และ text processing: Shell เก่งเรื่อง pipe, grep, awk, sed ที่ Ansible module ทำได้ยากกว่า
  • Environment ไม่มี Python: Ansible ต้องการ Python บน managed node ถ้าเครื่องปลายทางไม่มี Python (เช่น embedded systems) Shell Script ทำงานได้เลย
  • Quick one-liner สำหรับ admin: งาน ad-hoc ง่าย ๆ ที่ไม่ต้องการ track หรือ repeat เช่น ดู disk usage หรือ kill process

เมื่อไหร่ควรเปลี่ยนไปใช้ Ansible

มีสัญญาณชัดเจนที่บอกว่าถึงเวลาเปลี่ยนจาก Shell Script มาใช้เครื่องมือ configuration management แล้ว

  • Script ต้องรันบนหลายเซิร์ฟเวอร์: เมื่อต้องวน loop SSH หรือ copy script ไปรันบนหลายเครื่อง นี่คือสัญญาณแรกที่ควรย้ายมา Ansible
  • Script ยาวขึ้นเรื่อย ๆ และยากต่อการ maintain: เมื่อ Bash script เกิน 100-200 บรรทัด และเริ่มมี nested if-else เยอะ ความอ่านยากของ YAML น้อยกว่าความอ่านยากของ Bash ที่ซับซ้อน
  • ต้องการ Idempotency: เมื่อ script นั้นต้องรันได้หลายครั้งโดยไม่เกิดผลข้างเคียง การเขียน idempotency check ใน Bash เองใช้เวลามากกว่าการใช้ module ที่มีให้พร้อมใช้
  • ต้องการ version control และ audit: เมื่อทีมต้องรู้ว่าใคร deploy อะไร เมื่อไหร่ การเก็บ Playbook ใน Git repository ให้ history ที่ดีกว่า
  • ต้องการ Rollback หรือ Dry-run: Ansible มี --check mode ที่ simulate การรันโดยไม่ทำจริง Shell Script ต้องเขียน dry-run mode เอง

เปรียบเทียบตัวอย่างจริง: ติดตั้ง Nginx

ตัวอย่างนี้แสดงให้เห็นความแตกต่างระหว่างการติดตั้ง Nginx บน Ubuntu ด้วยสองวิธี

Shell Script: ต้องเขียน check เองว่า Nginx ติดตั้งแล้วหรือยัง จัดการ error เอง และถ้าต้องรันบน 10 เซิร์ฟเวอร์ต้องเพิ่ม SSH loop เข้าไปอีก

#!/bin/bash
if ! command -v nginx &>/dev/null; then
  apt-get update && apt-get install -y nginx
fi
systemctl enable nginx
systemctl start nginx

Ansible Playbook: Idempotent โดย default รันได้บน hosts ทุกเครื่องใน inventory พร้อมกัน และ module จัดการ error handling ให้เองทั้งหมด

- name: Install and start Nginx
  hosts: webservers
  tasks:
    - name: Install nginx
      apt:
        name: nginx
        state: present
    - name: Enable and start nginx
      service:
        name: nginx
        state: started
        enabled: true

ใช้ทั้งสองร่วมกัน

ในทางปฏิบัติ เครื่องมือทั้งสองมักใช้ร่วมกันได้ดี โดย Ansible มี shell และ command module สำหรับรัน shell command เมื่อไม่มี module เฉพาะ ทำให้ migration ทีละส่วนได้โดยไม่ต้องเขียนใหม่ทั้งหมด เช่น ใช้ Ansible จัดการ infrastructure setup แต่ยังคงใช้ shell script สำหรับ application-specific task ที่ซับซ้อน

สรุป

Shell Script ยังมีที่อยู่สำหรับงาน one-off ง่าย ๆ บนเครื่องเดียว แต่เมื่อต้องจัดการหลายเซิร์ฟเวอร์ ต้องการ idempotency หรือ audit trail การย้ายมา Ansible คือการตัดสินใจที่ถูกต้อง เกณฑ์ง่าย ๆ คือ: ถ้า script นั้นต้องรันบนหลายเซิร์ฟเวอร์หรือต้องรันซ้ำได้อย่างปลอดภัย ให้ใช้ Ansible แทน