Ansible user module ใช้จัดการ Linux account ครอบคลุมตั้งแต่การสร้าง, ลบ, แก้ไข home directory, ตั้งรหัสผ่าน, กำหนด group, ไปจนถึง SSH authorized keys โดยไม่ต้องใช้ command รัน useradd หรือ usermod ตรง ๆ ซึ่งมักไม่ idempotent
บทความนี้อธิบายการใช้ user module ครอบคลุม parameters หลัก, การสร้างและลบ account, การกำหนด group และ shell, การตั้งรหัสผ่าน, การจัดการ SSH key ด้วย authorized_key module และ pattern สำหรับ deploy บัญชีข้ามหลายเซิร์ฟเวอร์
user Module พื้นฐาน
user module ต้องการ parameter name เป็นอย่างน้อย และใช้ state ควบคุมว่าจะสร้าง (present) หรือลบ (absent) บัญชี
---
- name: Basic user module usage
hosts: all
become: true
tasks:
- name: Create user account
user:
name: deploy
state: present
- name: Create user with full options
user:
name: appuser
state: present
comment: "Application Service User"
shell: /bin/bash
home: /opt/appuser
create_home: true
- name: Remove user account
user:
name: olduser
state: absent
remove: true # ลบ home directory และ mail spool ด้วย
module ตรวจสอบว่าบัญชีมีอยู่แล้วหรือไม่ก่อนดำเนินการ ถ้ามีอยู่แล้วและ state เป็น present จะไม่ทำอะไร — ทำให้ Playbook เป็น idempotent โดยอัตโนมัติ
Group — กำหนด Primary และ Supplementary Groups
ใช้ group สำหรับ primary group และ groups สำหรับ supplementary groups ส่วน append ควบคุมว่าจะเพิ่มหรือแทนที่ groups ที่มีอยู่
---
- name: User group management
hosts: all
become: true
tasks:
- name: Create account with specific primary group
user:
name: webmaster
group: www-data # primary group
state: present
- name: Add account to supplementary groups
user:
name: deploy
groups: sudo,docker # supplementary groups
append: true # เพิ่มเข้าไป ไม่แทนที่ groups เดิม
state: present
- name: Set exact groups (replace existing)
user:
name: svcuser
groups: appgroup,loggroup
append: false # แทนที่ groups ทั้งหมด
state: present
- name: Add account to docker group
user:
name: "{{ ansible_user }}"
groups: docker
append: true
state: present
ข้อสำคัญ: append: true เป็น idempotent — ถ้าบัญชีอยู่ใน group นั้นแล้วจะไม่ทำอะไร แต่ append: false จะ replace groups ทุกครั้งที่รัน ระวังการใช้
UID, Shell, และ Home Directory
กำหนด UID ตายตัวเพื่อให้ consistent ข้ามหลาย server โดยเฉพาะ NFS หรือ shared filesystem ที่ต้องการ UID ตรงกัน
---
- name: UID, shell and home management
hosts: all
become: true
tasks:
# กำหนด UID ตายตัว (สำคัญมากสำหรับ NFS/shared storage)
- name: Create account with fixed UID
user:
name: appuser
uid: 1500
group: appgroup
shell: /bin/bash
home: /opt/appuser
create_home: true
state: present
# system account ไม่มี login shell และไม่ต้อง home
- name: Create system account (no login)
user:
name: mysql
uid: 106
system: true # UID < 1000, ไม่มี home, ไม่มี password
shell: /bin/false
create_home: false
state: present
# เปลี่ยน shell ของบัญชีที่มีอยู่แล้ว
- name: Change shell
user:
name: deploy
shell: /bin/zsh
state: present
# ปิด login โดยตั้ง shell เป็น nologin
- name: Disable login for service account
user:
name: svcaccount
shell: /sbin/nologin
state: present
ตั้งรหัสผ่าน
รหัสผ่านใน user module ต้องเป็น hashed password เท่านั้น ห้ามใส่ plain text โดยตรง ใช้ ansible.builtin.password_hash filter สำหรับ hash และเก็บ password ต้นฉบับใน Ansible Vault
---
- name: Password management
hosts: all
become: true
vars:
account_password: "{{ vault_account_password }}" # เก็บใน Ansible Vault
tasks:
# ตั้งรหัสผ่านโดย hash ตอน runtime
- name: Set password
user:
name: deploy
password: "{{ account_password | password_hash('sha512') }}"
state: present
# ตั้งรหัสผ่านเฉพาะตอนสร้าง ไม่เปลี่ยนถ้ามีอยู่แล้ว
- name: Set password only on creation
user:
name: newaccount
password: "{{ 'InitialPass123!' | password_hash('sha512') }}"
update_password: on_create # ไม่เปลี่ยนถ้าบัญชีมีอยู่แล้ว
state: present
# ล็อค account (ใส่ ! นำหน้า hash)
- name: Lock account
user:
name: suspendaccount
password_lock: true
state: present
# บังคับ reset รหัสผ่านครั้งต่อไปที่ login
- name: Force password change on next login
user:
name: newemployee
password: "{{ 'TempPass!' | password_hash('sha512') }}"
update_password: always
state: present
ระวัง: ห้ามเขียน password plain text ใน Playbook โดยตรง — ใช้ ansible-vault encrypt ก่อนเสมอ และใช้ update_password: on_create เพื่อป้องกัน Ansible reset password ทุกครั้งที่รัน
authorized_key — จัดการ SSH Public Keys
authorized_key module ใช้ร่วมกับ user module เพื่อ deploy SSH public key ให้กับบัญชีต่าง ๆ ทำให้ login แบบ passwordless ได้อย่างปลอดภัยและ idempotent
---
- name: SSH key management
hosts: all
become: true
tasks:
# เพิ่ม SSH key จากไฟล์บน control node
- name: Add SSH authorized key
authorized_key:
user: deploy
state: present
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
# เพิ่ม key จาก variable
- name: Add SSH key from variable
authorized_key:
user: deploy
state: present
key: "{{ deploy_ssh_public_key }}"
# เพิ่มหลาย keys พร้อมกัน
- name: Add multiple SSH keys
authorized_key:
user: deploy
state: present
key: "{{ item }}"
loop: "{{ ssh_public_keys }}"
# ลบ key ที่ไม่ต้องการออก
- name: Remove SSH key
authorized_key:
user: oldaccount
state: absent
key: "{{ old_ssh_key }}"
Pattern: สร้าง Deploy Account ข้ามหลายเซิร์ฟเวอร์
ตัวอย่าง Playbook สร้างบัญชี deploy พร้อม SSH key, sudo access และ directory structure บน server ทุกตัวในคราวเดียว
---
- name: Create deploy account across all servers
hosts: all
become: true
vars:
deploy_name: deploy
deploy_uid: 1500
deploy_groups: "sudo,docker"
deploy_ssh_key: "{{ lookup('file', '~/.ssh/deploy_rsa.pub') }}"
tasks:
- name: Create deploy group
group:
name: "{{ deploy_name }}"
gid: "{{ deploy_uid }}"
state: present
- name: Create deploy account
user:
name: "{{ deploy_name }}"
uid: "{{ deploy_uid }}"
group: "{{ deploy_name }}"
groups: "{{ deploy_groups }}"
append: true
shell: /bin/bash
home: "/home/{{ deploy_name }}"
create_home: true
state: present
- name: Add SSH key
authorized_key:
user: "{{ deploy_name }}"
state: present
key: "{{ deploy_ssh_key }}"
- name: Allow passwordless sudo
copy:
content: "{{ deploy_name }} ALL=(ALL) NOPASSWD: ALL\n"
dest: "/etc/sudoers.d/{{ deploy_name }}"
owner: root
group: root
mode: '0440'
validate: 'visudo -cf %s'
- name: Create application directories
file:
path: "{{ item }}"
state: directory
owner: "{{ deploy_name }}"
group: "{{ deploy_name }}"
mode: '0755'
loop:
- /opt/apps
- /var/log/apps
สรุป
user module เป็นวิธีที่ถูกต้องในการจัดการ Linux accounts ด้วย Ansible แทนการรัน useradd/usermod โดยตรง รองรับ state present/absent, การกำหนด UID, group, shell, home directory และ password ได้ในคำสั่งเดียว
Pattern ที่ควรจำ: ใช้ append: true เมื่อเพิ่ม supplementary groups เพื่อไม่ให้ลบ groups เดิม, ใช้ update_password: on_create เพื่อป้องกัน password reset ทุกรัน, เก็บ password ใน Ansible Vault เสมอ และใช้ authorized_key module ควบคู่กันสำหรับ SSH key management

