Site logo
Tác giả
  • avatar Nguyễn Đức Xinh
    Name
    Nguyễn Đức Xinh
    Twitter
Ngày xuất bản
Ngày xuất bản

Ansible Ad-Hoc Commands: Hướng dẫn chạy lệnh nhanh trên nhiều server

Running Ad-Hoc Commands trong Ansible

Chạy lệnh nhanh trên server mà không cần viết Playbooks

Ansible không chỉ mạnh mẽ với Playbooks mà còn rất tiện lợi khi chạy lệnh tạm thời trên nhiều server cùng lúc – đó là Ad-Hoc Commands. Đây là công cụ tuyệt vời để:

  • Kiểm tra trạng thái server
  • Cài package nhanh
  • Copy file nhỏ
  • Restart service
  • Troubleshoot vấn đề nhanh
  • Thực hiện các tác vụ maintenance đơn giản

Mà không cần tạo playbook riêng.

Ad-Hoc Commands là gì?

Ad-Hoc Commands trong Ansible là các lệnh đơn giản được thực thi trực tiếp từ command line mà không cần phải viết Playbook. Chúng rất hữu ích khi bạn cần:

  • Thực hiện một tác vụ đơn giản và nhanh
  • Kiểm tra trạng thái hệ thống
  • Thử nghiệm một module trước khi đưa vào Playbook
  • Thực hiện các thao tác maintenance không lặp lại

Khi nào nên dùng Ad-Hoc Commands?

Tình huống Ad-Hoc Commands Playbooks
Kiểm tra kết nối nhanh
Deploy ứng dụng phức tạp
Restart service khẩn cấp
Cài đặt môi trường từ đầu
Check disk space
Orchestration nhiều bước

1️⃣ Cú pháp cơ bản

ansible <hosts> -i <inventory> -m <module> -a "<module_args>"
Tham số Ý nghĩa
<hosts> Nhóm host hoặc host đơn
-i <inventory> File inventory
-m <module> Module Ansible dùng (ping, shell, command, apt, yum, service…)
-a "<args>" Tham số truyền cho module

2️⃣ Kiểm tra kết nối (Ping)

ansible all -i inventory.ini -m ping

Kết quả:

web01 | SUCCESS => {"changed": false, "ping": "pong"}
db01  | SUCCESS => {"changed": false, "ping": "pong"}

✅ Đây là cách nhanh để kiểm tra kết nối SSH tới managed hosts.


3️⃣ Chạy lệnh shell / command

Sự khác biệt giữa commandshell module

Module Hỗ trợ pipe/redirect Hỗ trợ environment variables Use case
command Lệnh đơn giản, an toàn hơn
shell Lệnh phức tạp với pipe, redirect

Ví dụ với command module

# Chạy lệnh đơn giản
ansible web -i inventory.ini -m command -a "uptime"

# Kiểm tra phiên bản
ansible web -i inventory.ini -m command -a "nginx -v"

# List files
ansible web -i inventory.ini -m command -a "ls -la /var/www"

Ví dụ với shell module

# Dùng shell để hỗ trợ pipe
ansible web -i inventory.ini -m shell -a "df -h | grep /dev/sda1"

# Sử dụng redirect
ansible web -i inventory.ini -m shell -a "cat /etc/hosts > /tmp/hosts_backup"

# Dùng environment variables
ansible web -i inventory.ini -m shell -a "echo $HOME"

# Multiple commands
ansible web -i inventory.ini -m shell -a "cd /var/www && ls -la"

⚠️ Lưu ý bảo mật: Ưu tiên dùng command module khi có thể vì nó an toàn hơn (không thông qua shell nên tránh được shell injection).

4️⃣ Cài package nhanh

Trên Ubuntu/Debian:

ansible web -i inventory.ini -m apt -a "name=nginx state=present" --become

Trên CentOS/RHEL:

ansible web -i inventory.ini -m yum -a "name=httpd state=present" --become

5️⃣ Restart service

ansible web -i inventory.ini -m service -a "name=nginx state=restarted" --become

6️⃣ Copy file nhanh

Copy file đơn giản

ansible web -i inventory.ini -m copy -a "src=./localfile dest=/tmp/remotefile mode=0644" --become

Copy với ownership và permissions

# Copy với owner và group cụ thể
ansible web -i inventory.ini -m copy -a "src=./app.conf dest=/etc/nginx/conf.d/app.conf owner=nginx group=nginx mode=0644" --become

# Copy directory
ansible web -i inventory.ini -m copy -a "src=./configs/ dest=/etc/myapp/ owner=root group=root mode=0755" --become

# Copy với backup
ansible web -i inventory.ini -m copy -a "src=./nginx.conf dest=/etc/nginx/nginx.conf backup=yes" --become

✅ Thích hợp copy config nhỏ, script hoặc file tạm.

7️⃣ Quản lý user và group

Tạo user

# Tạo user mới
ansible web -i inventory.ini -m user -a "name=deploy state=present shell=/bin/bash" --become

# Tạo user với home directory
ansible web -i inventory.ini -m user -a "name=deploy state=present createhome=yes home=/home/deploy" --become

# Xóa user
ansible web -i inventory.ini -m user -a "name=olduser state=absent remove=yes" --become

Quản lý group

# Tạo group
ansible web -i inventory.ini -m group -a "name=developers state=present" --become

# Add user vào group
ansible web -i inventory.ini -m user -a "name=deploy groups=developers,sudo append=yes" --become

8️⃣ Quản lý file và directory

Tạo directory

# Tạo directory
ansible web -i inventory.ini -m file -a "path=/opt/myapp state=directory mode=0755" --become

# Tạo directory với owner cụ thể
ansible web -i inventory.ini -m file -a "path=/var/www/html state=directory owner=www-data group=www-data mode=0755" --become

Xóa file/directory

# Xóa file
ansible web -i inventory.ini -m file -a "path=/tmp/oldfile state=absent" --become

# Xóa directory và contents
ansible web -i inventory.ini -m file -a "path=/tmp/olddir state=absent" --become
ansible web -i inventory.ini -m file -a "src=/opt/app/current dest=/var/www/app state=link" --become

9️⃣ Thu thập thông tin hệ thống (Gather Facts)

Lấy tất cả facts

# Thu thập tất cả thông tin hệ thống
ansible web -i inventory.ini -m setup

# Lọc facts theo pattern
ansible web -i inventory.ini -m setup -a "filter=ansible_distribution*"

# Chỉ lấy thông tin network
ansible web -i inventory.ini -m setup -a "filter=ansible_default_ipv4"

# Lấy thông tin memory
ansible web -i inventory.ini -m setup -a "filter=ansible_memory_mb"

Facts hữu ích

# OS information
ansible web -i inventory.ini -m setup -a "filter=ansible_os_family"

# Hostname
ansible web -i inventory.ini -m setup -a "filter=ansible_hostname"

# IP addresses
ansible web -i inventory.ini -m setup -a "filter=ansible_all_ipv4_addresses"

# Disk information
ansible web -i inventory.ini -m setup -a "filter=ansible_mounts"

🔟 Sử dụng với loops và variables (Extra vars)

Truyền variables

Bạn có thể truyền biến tạm thời:

# Truyền single variable
ansible web -i inventory.ini -m debug -a "msg='Deploy version {{ version }}'" -e "version=1.2.3"

# Truyền multiple variables
ansible web -i inventory.ini -m debug -a "msg='{{ env }} - {{ version }}'" -e "env=production version=1.2.3"

# Truyền từ JSON file
ansible web -i inventory.ini -m debug -a "msg='{{ app_name }}'" -e "@vars.json"

Sử dụng với conditionals

# Chỉ chạy trên Ubuntu servers
ansible all -i inventory.ini -m shell -a "apt update" --limit "ansible_distribution:Ubuntu" --become

# Check disk usage và alert nếu > 80%
ansible all -i inventory.ini -m shell -a "df -h / | awk 'NR==2 {print $5}' | sed 's/%//'"

1️⃣1️⃣ Module hữu ích khác

Fetch module - Download file từ remote

# Download file từ remote về local
ansible web -i inventory.ini -m fetch -a "src=/var/log/nginx/error.log dest=/tmp/logs/ flat=yes"

Git module - Clone repository

# Clone git repository
ansible web -i inventory.ini -m git -a "repo=https://github.com/user/repo.git dest=/opt/app version=main" --become

Cron module - Quản lý cron jobs

# Tạo cron job
ansible web -i inventory.ini -m cron -a "name='backup database' minute=0 hour=2 job='/usr/local/bin/backup.sh'" --become

# Xóa cron job
ansible web -i inventory.ini -m cron -a "name='backup database' state=absent" --become

Systemd/Service module - Quản lý services

# Enable service khi boot
ansible web -i inventory.ini -m systemd -a "name=nginx enabled=yes" --become

# Check service status
ansible web -i inventory.ini -m systemd -a "name=nginx" --become

Reboot module - Reboot servers

# Reboot và đợi server online
ansible web -i inventory.ini -m reboot -a "reboot_timeout=300" --become

1️⃣2️⃣ Options và flags hữu ích

Privilege Escalation

# Chạy với sudo
ansible web -i inventory.ini -m shell -a "systemctl restart nginx" --become

# Chỉ định user để become
ansible web -i inventory.ini -m shell -a "whoami" --become --become-user=nginx

# Nhập sudo password
ansible web -i inventory.ini -m shell -a "apt update" --become --ask-become-pass

Parallel Execution

# Chạy trên 10 hosts cùng lúc (default là 5)
ansible all -i inventory.ini -m ping -f 10

# Serial execution - chạy từng host một
ansible all -i inventory.ini -m ping -f 1

Limiting Hosts

# Chỉ chạy trên một host cụ thể
ansible all -i inventory.ini -m ping --limit "web01"

# Chạy trên nhiều hosts
ansible all -i inventory.ini -m ping --limit "web01,web02"

# Exclude hosts
ansible all -i inventory.ini -m ping --limit "all:!db01"

# Sử dụng pattern
ansible all -i inventory.ini -m ping --limit "web*"

Check Mode (Dry Run)

# Xem sẽ thay đổi gì mà không thực hiện
ansible web -i inventory.ini -m apt -a "name=nginx state=present" --check --become

Verbose Mode

# Debug level 1
ansible web -i inventory.ini -m ping -v

# Debug level 2
ansible web -i inventory.ini -m ping -vv

# Debug level 3 (rất chi tiết)
ansible web -i inventory.ini -m ping -vvv

1️⃣3️⃣ Lưu ý khi chạy Ad-Hoc

Common errors và troubleshooting

Lỗi thường gặp Nguyên nhân Cách xử lý
SSH timeout Network issue, firewall Kiểm tra inventory, user, key, firewall rules
Permission denied Không có quyền sudo Thêm --become hoặc dùng đúng user có sudo rights
Module không tồn tại Version Ansible cũ Cài Ansible đúng version, dùng ansible-doc -l để xem module
Unreachable host SSH không connect được Check SSH key, user, port trong inventory
Authentication failure SSH key không đúng Verify ansible_ssh_private_key_file trong inventory

Best Practices

Luôn test với --check mode trước

ansible web -i inventory.ini -m apt -a "name=nginx state=present" --check --become

Sử dụng command thay vì shell khi có thể (an toàn hơn)

Document các lệnh quan trọng bằng comment hoặc note

Sử dụng variables thay vì hardcode values

Test trên staging trước khi chạy production

Sử dụng --limit để test trên một host trước

ansible web -i inventory.ini -m command -a "systemctl restart nginx" --limit "web01" --become

Tránh chạy lệnh nguy hiểm trên production mà không kiểm tra

Không nên dùng Ad-Hoc cho automation phức tạp (dùng Playbooks thay vì)

Idempotency với Ad-Hoc Commands

Một số module là idempotent (chạy nhiều lần cho kết quả giống nhau):

  • apt, yum - ✅ Idempotent
  • copy - ✅ Idempotent
  • service - ✅ Idempotent
  • command, shell - ❌ Không idempotent (phụ thuộc vào lệnh)
# Idempotent - chạy nhiều lần OK
ansible web -i inventory.ini -m apt -a "name=nginx state=present" --become

# Không idempotent - có thể gây lỗi nếu chạy lại
ansible web -i inventory.ini -m shell -a "useradd newuser"

🎯 Tóm tắt

  • Ad-Hoc Command = chạy lệnh nhanh không cần playbook
  • Dùng module phổ biến: ping, command, shell, apt, yum, service, copy, user, file, setup, fetch, git, cron, systemd, reboot
  • Có thể dùng với loops, extra vars, conditionals
  • Hỗ trợ nhiều options: --become, --check, --limit, -f, -v
  • Ưu tiên command hơn shell vì an toàn hơn
  • Luôn test với --check mode trước khi thực hiện thay đổi quan trọng
  • Tiết kiệm thời gian khi làm troubleshoot, check trạng thái hoặc patch nhanh
  • Không thay thế được Playbooks cho automation phức tạp

Bài tập cơ bản

  1. Ping tất cả server trong inventory
ansible all -i inventory.ini -m ping
  1. Kiểm tra dung lượng ổ đĩa trên tất cả servers
ansible all -i inventory.ini -m shell -a "df -h"
  1. Cài package htop trên web servers
ansible web -i inventory.ini -m apt -a "name=htop state=present" --become
  1. Restart nginx service
ansible web -i inventory.ini -m service -a "name=nginx state=restarted" --become
  1. Thu thập thông tin OS của tất cả servers
ansible all -i inventory.ini -m setup -a "filter=ansible_distribution*"

Bài tập nâng cao

  • Tạo user deploy với SSH key trên tất cả web servers
  • Copy nginx config và restart service nếu config thay đổi (combine nhiều commands)
  • Check uptime của tất cả servers và lưu kết quả vào file local
  • Setup cron job để backup database hàng ngày lúc 2AM
  • Tìm tất cả servers có disk usage > 80%

📚 Tài liệu tham khảo


Bước tiếp theo

Sau khi đã thành thạo Ad-Hoc Commands, bạn đã sẵn sàng để tìm hiểu Ansible Playbooks - nơi bạn có thể viết automation phức tạp, có tổ chức và tái sử dụng được.