Ansible stat module ใช้ตรวจสอบสถานะของ filesystem object บน remote server ก่อนดำเนินการอื่น — เช่น ตรวจว่ามีไฟล์อยู่หรือไม่, ขนาด, permissions, owner, checksum หรือว่าเป็น symlink โดยไม่ต้องรัน command: ls -la ตรง ๆ
บทความนี้ครอบคลุม parameters หลัก, การอ่านค่าจาก stat result, การใช้ร่วมกับ when conditional เพื่อสร้าง idempotent tasks, การตรวจสอบ checksum และ pattern สำหรับ pre-deploy verification
stat Module พื้นฐาน
stat module ต้องใช้คู่กับ register เสมอ เพราะข้อมูลทั้งหมดจะถูกเก็บไว้ใน registered variable ไม่ได้ทำการเปลี่ยนแปลงอะไรบน server — changed จะเป็น false เสมอ
---
- name: Basic stat module usage
hosts: all
tasks:
# ตรวจสอบว่าไฟล์มีอยู่หรือไม่
- name: Check if config file exists
stat:
path: /etc/myapp/app.conf
register: config_stat
# ดูข้อมูลทั้งหมดที่ได้
- name: Show file info
debug:
var: config_stat.stat
# ใช้ when conditional ตามผล stat
- name: Create config if not exists
template:
src: app.conf.j2
dest: /etc/myapp/app.conf
when: not config_stat.stat.exists
# ตรวจว่าเป็น directory
- name: Check if directory exists
stat:
path: /opt/myapp/data
register: data_dir
- name: Create directory if missing
file:
path: /opt/myapp/data
state: directory
owner: appuser
mode: '0755'
when: not data_dir.stat.exists
Fields ที่ได้จาก stat
เมื่อ stat.exists เป็น true จะมี fields เพิ่มเติมให้ใช้ได้ หาก exists เป็น false จะมีแค่ stat.exists เท่านั้น
---
- name: Reading stat fields
hosts: all
tasks:
- name: Get file stats
stat:
path: /opt/myapp/bin/myapp
register: app_bin
- name: Check various stat fields
debug:
msg:
- "Exists: {{ app_bin.stat.exists }}"
- "Is file: {{ app_bin.stat.isreg | default(false) }}"
- "Is directory: {{ app_bin.stat.isdir | default(false) }}"
- "Is symlink: {{ app_bin.stat.islnk | default(false) }}"
- "Size: {{ app_bin.stat.size | default(0) }} bytes"
- "Owner: {{ app_bin.stat.pw_name | default('N/A') }}"
- "Group: {{ app_bin.stat.gr_name | default('N/A') }}"
- "Mode: {{ app_bin.stat.mode | default('N/A') }}"
- "Executable: {{ app_bin.stat.executable | default(false) }}"
- "Writeable: {{ app_bin.stat.writeable | default(false) }}"
when: app_bin.stat.exists
Checksum — ตรวจสอบความถูกต้องของไฟล์
ใช้ checksum_algorithm เพื่อคำนวณ hash ของไฟล์ ช่วยตรวจสอบว่าไฟล์ถูกแก้ไขหรือ download ครบถ้วนหรือไม่
---
- name: Checksum verification
hosts: all
tasks:
# คำนวณ SHA256 checksum
- name: Get file checksum
stat:
path: /opt/myapp/bin/myapp
checksum_algorithm: sha256
register: bin_stat
- name: Verify checksum matches expected
assert:
that:
- bin_stat.stat.checksum == "{{ expected_sha256 }}"
fail_msg: "Checksum mismatch! File may be corrupted."
success_msg: "Checksum verified OK."
when: bin_stat.stat.exists
# MD5 checksum (เร็วกว่า SHA256 แต่ไม่ปลอดภัยเท่า)
- name: Get MD5 checksum
stat:
path: /etc/myapp/app.conf
checksum_algorithm: md5
register: conf_stat
- name: Show MD5
debug:
msg: "MD5: {{ conf_stat.stat.checksum }}"
when: conf_stat.stat.exists
ตรวจสอบ Symlink
stat module ช่วยตรวจสอบ symlink ได้อย่างละเอียด — ทั้งว่าเป็น symlink หรือไม่, link ชี้ไปที่ไหน และ target ยังมีอยู่จริงหรือไม่
---
- name: Symlink inspection
hosts: all
tasks:
- name: Check current symlink
stat:
path: /opt/myapp/current
register: current_link
- name: Show symlink info
debug:
msg:
- "Is symlink: {{ current_link.stat.islnk }}"
- "Points to: {{ current_link.stat.lnk_target | default('N/A') }}"
- "Target exists: {{ current_link.stat.lnk_source | default('N/A') }}"
when: current_link.stat.exists and current_link.stat.islnk
# ตรวจสอบก่อน overwrite symlink
- name: Check if symlink needs update
debug:
msg: "Symlink already points to {{ current_link.stat.lnk_target }}"
when:
- current_link.stat.exists
- current_link.stat.islnk
- current_link.stat.lnk_target == "/opt/myapp/releases/v2.5.0"
ตรวจสอบ Permissions และ Ownership
ใช้ stat ตรวจ permissions และ owner ก่อนแก้ไข เพื่อ skip task ที่ไม่จำเป็น หรือ fail early ถ้า permissions ไม่ถูกต้อง
---
- name: Permission and ownership checks
hosts: all
tasks:
- name: Check config file permissions
stat:
path: /etc/myapp/secret.conf
register: secret_stat
# fail ถ้า permissions ไม่ถูกต้อง (ควรเป็น 0600)
- name: Assert secret file has correct permissions
assert:
that:
- secret_stat.stat.mode == "0600"
- secret_stat.stat.pw_name == "root"
fail_msg: "secret.conf permissions are wrong: mode={{ secret_stat.stat.mode }}, owner={{ secret_stat.stat.pw_name }}"
when: secret_stat.stat.exists
# แก้ permissions เฉพาะเมื่อไม่ถูกต้อง
- name: Fix permissions if wrong
file:
path: /etc/myapp/secret.conf
mode: '0600'
owner: root
group: root
when:
- secret_stat.stat.exists
- secret_stat.stat.mode != "0600"
Pattern: Pre-Deploy Verification
ตัวอย่าง Playbook ตรวจสอบ prerequisites ก่อน deploy application — ตรวจว่า binary มีอยู่, config ถูกต้อง, directory พร้อม และ symlink ชี้ถูกต้อง
---
- name: Pre-deploy verification
hosts: appservers
vars:
app_name: myapp
app_version: "{{ deploy_version }}"
release_path: "/opt/{{ app_name }}/releases/{{ app_version }}"
tasks:
# ตรวจ release directory
- name: Check release directory
stat:
path: "{{ release_path }}"
register: release_dir
- name: Fail if release not found
fail:
msg: "Release directory {{ release_path }} not found — run deploy first"
when: not release_dir.stat.exists or not release_dir.stat.isdir
# ตรวจ binary executable
- name: Check application binary
stat:
path: "{{ release_path }}/bin/{{ app_name }}"
register: app_bin
- name: Fail if binary missing or not executable
fail:
msg: "Application binary not found or not executable"
when: not app_bin.stat.exists or not app_bin.stat.executable
# ตรวจ config file
- name: Check config file
stat:
path: "{{ release_path }}/config/app.conf"
checksum_algorithm: sha256
register: app_conf
- name: Fail if config missing
fail:
msg: "Config file not found"
when: not app_conf.stat.exists
# ตรวจ log directory
- name: Check log directory writable
stat:
path: "/var/log/{{ app_name }}"
register: log_dir
- name: Create log directory if missing
file:
path: "/var/log/{{ app_name }}"
state: directory
owner: appuser
mode: '0755'
when: not log_dir.stat.exists
- name: Pre-deploy checks passed
debug:
msg: "All checks passed — proceeding with deployment"
สรุป
stat module เป็นเครื่องมือสำคัญสำหรับสร้าง idempotent Playbook รองรับการตรวจสอบ existence, type, permissions, owner, checksum และ symlink target ของ filesystem object โดยต้องใช้ร่วมกับ register เสมอ
Pattern ที่ควรจำ: ตรวจ stat.exists ก่อนเข้าถึง field อื่นเสมอ เพราะถ้า exists: false fields อื่นจะไม่มีค่า, ใช้ | default(false) เพื่อป้องกัน undefined variable error และใช้ assert ร่วมกับ stat เพื่อ fail early แทนการปล่อยให้ task ถัดไป error แบบไม่มี context

