Ansible wait_for module ใช้หยุดรอให้เงื่อนไขบน remote server เป็นจริงก่อนดำเนินการ task ถัดไป ไม่ว่าจะเป็นรอให้ port เปิด, service พร้อม, ไฟล์ปรากฏ, หรือ connection ปิด — เหมาะสำหรับ deployment workflow ที่ต้องการให้ service พร้อมก่อน proceed ต่อ
บทความนี้ครอบคลุม parameters หลัก, การรอ port, การรอ service พร้อมด้วย path และ search string, การตั้ง timeout และ pattern สำหรับ zero-downtime rolling deployment
wait_for Module พื้นฐาน — รอ Port เปิด
ใช้บ่อยที่สุดคือรอให้ port เปิดหลัง start service ใช้ host และ port เพื่อระบุ endpoint ที่ต้องการตรวจสอบ และ timeout กำหนดเวลาสูงสุดที่ยอมรอ (default 300 วินาที)
---
- name: Basic wait_for usage
hosts: all
tasks:
# รอให้ port 80 เปิดบน localhost
- name: Wait for web server to start
wait_for:
host: localhost
port: 80
timeout: 60
# รอ port บน remote host
- name: Wait for database port
wait_for:
host: db.example.com
port: 5432
timeout: 120
# รอ port เฉพาะ interface
- name: Wait for app on specific interface
wait_for:
host: 0.0.0.0
port: 8080
timeout: 90
# รอ port พร้อมกำหนด delay ก่อนเริ่มตรวจ
- name: Wait for service with initial delay
wait_for:
host: localhost
port: 3306
delay: 10 # รอ 10 วินาทีก่อนเริ่มตรวจ
timeout: 120
รอ Port ปิด — หลัง Stop Service
ใช้ state: stopped เพื่อรอให้ port ปิดสนิทก่อนดำเนินการต่อ เช่น รอให้ service เก่าหยุดทำงานก่อน start service ใหม่ หรือรอให้ connection drain ครบ
---
- name: Wait for port to close
hosts: all
tasks:
# รอให้ port ปิดหลัง stop service
- name: Stop old application
service:
name: myapp
state: stopped
- name: Wait for port to be released
wait_for:
host: localhost
port: 8080
state: stopped # รอให้ port ไม่มีอะไร listen อยู่
timeout: 60
# รอ port ทั้งหมดใน list ปิด
- name: Wait for all app ports to close
wait_for:
host: localhost
port: "{{ item }}"
state: stopped
timeout: 30
loop:
- 8080
- 8081
- 8082
รอไฟล์ปรากฏหรือหายไป
ใช้ path แทน port เพื่อรอไฟล์ เช่น รอไฟล์ lock หายไป, รอ PID file ปรากฏ หรือรอ log file มีเนื้อหาที่ต้องการ
---
- name: Wait for file conditions
hosts: all
tasks:
# รอไฟล์ปรากฏ
- name: Wait for PID file to appear
wait_for:
path: /var/run/myapp.pid
state: present
timeout: 60
# รอไฟล์หายไป (lock file ถูกลบ)
- name: Wait for lock file to be removed
wait_for:
path: /tmp/deploy.lock
state: absent
timeout: 300
# รอไฟล์มีข้อความที่ต้องการ (log ขึ้น "ready")
- name: Wait for application ready message in log
wait_for:
path: /var/log/myapp/app.log
search_regex: "Application started successfully"
timeout: 120
# รอ log ขึ้น "ready" หรือ "error" (ตรวจ error ด้วย)
- name: Wait for startup or error
wait_for:
path: /var/log/myapp/app.log
search_regex: "(started|FAILED)"
timeout: 120
register: startup_result
รอ Connection ได้รับการตอบกลับ
ใช้ state: started (default) ร่วมกับ search_regex เพื่อรอให้ service ตอบกลับด้วยข้อความที่กำหนด — เหมาะสำหรับ service ที่ต้องการตรวจสอบ response จริง ๆ ไม่ใช่แค่ port เปิด
---
- name: Wait for service response
hosts: all
tasks:
# รอ SSH พร้อมหลัง reboot
- name: Wait for SSH to come back
wait_for:
host: "{{ inventory_hostname }}"
port: 22
state: started
delay: 30 # รอ 30 วินาทีให้ reboot เริ่ม
timeout: 300
delegate_to: localhost
# รอ database accept connection
- name: Wait for MySQL to accept connections
wait_for:
host: localhost
port: 3306
state: started
timeout: 120
# รอ Redis พร้อม
- name: Wait for Redis
wait_for:
host: 127.0.0.1
port: 6379
timeout: 60
wait_for_connection — รอ Host กลับมา
wait_for_connection module (ต่างจาก wait_for) ใช้รอให้ Ansible สามารถเชื่อมต่อกลับไปยัง host ได้ เหมาะสำหรับหลัง reboot หรือหลัง provision server ใหม่
---
- name: wait_for_connection usage
hosts: all
tasks:
# reboot แล้วรอกลับมา
- name: Reboot server
reboot:
reboot_timeout: 300
# หรือใช้ wait_for_connection หลัง reboot manual
- name: Trigger reboot
command: shutdown -r +1 "Rebooting for kernel update"
async: 1
poll: 0
- name: Wait for host to come back online
wait_for_connection:
delay: 60 # รอ 60 วินาทีก่อนเริ่มลอง
timeout: 300 # รอสูงสุด 300 วินาที
sleep: 10 # probe ทุก 10 วินาที
connect_timeout: 5 # timeout ต่อ attempt
- name: Continue after reconnect
debug:
msg: "Host is back online — continuing deployment"
Pattern: Zero-Downtime Rolling Deployment
ตัวอย่าง Playbook ที่ใช้ wait_for เพื่อรับรองว่า service พร้อมรับ traffic ก่อน proceed ในแต่ละขั้นตอนของ rolling deployment
---
- name: Rolling deployment with wait_for
hosts: appservers
serial: 1 # deploy ทีละ server
vars:
app_name: myapp
app_port: 8080
health_log: "/var/log/{{ app_name }}/startup.log"
tasks:
# หยุด service เดิม
- name: Stop application service
service:
name: "{{ app_name }}"
state: stopped
# รอ port ปิดก่อน deploy ใหม่
- name: Wait for old process to release port
wait_for:
host: localhost
port: "{{ app_port }}"
state: stopped
timeout: 60
# deploy version ใหม่
- name: Deploy new version
git:
repo: "{{ app_repo }}"
dest: "/opt/{{ app_name }}/current"
version: "{{ deploy_version }}"
force: true
# start service ใหม่
- name: Start application service
service:
name: "{{ app_name }}"
state: started
# รอ port เปิด
- name: Wait for application port to open
wait_for:
host: localhost
port: "{{ app_port }}"
state: started
timeout: 120
# รอ log บอกว่า ready
- name: Wait for application ready signal
wait_for:
path: "{{ health_log }}"
search_regex: "Server started on port {{ app_port }}"
timeout: 60
- name: Deployment complete on this server
debug:
msg: "{{ app_name }} v{{ deploy_version }} is running on {{ inventory_hostname }}"
สรุป
wait_for module เป็น building block สำคัญสำหรับสร้าง deployment workflow ที่น่าเชื่อถือ รองรับการรอ port เปิด/ปิด, ไฟล์ปรากฏ/หายไป, และ log ขึ้น pattern ที่กำหนด ผ่าน parameters ที่ชัดเจนพร้อม timeout และ delay ที่ควบคุมได้
Pattern ที่ควรจำ: ตั้ง delay ให้เหมาะสมเพื่อหลีกเลี่ยง probe ที่ไม่จำเป็น, ใช้ search_regex ใน log file เพื่อรอ “ready” message จริง ๆ แทนแค่รอ port เปิด, ใช้ state: stopped ก่อน deploy ใหม่เพื่อให้แน่ใจว่า process เก่าหยุดแล้ว และใช้ wait_for_connection แทน wait_for port: 22 สำหรับหลัง reboot เพราะ handle reconnect logic ได้ดีกว่า

