3. 使用Ansible Playbook管理用户账户
任务目标
编写一个 Ansible Playbook,用于在目标主机上创建、修改或删除系统用户,并支持设置密码、附加用户组以及授予 sudo 权限。Playbook 需通过变量控制用户状态,实现幂等操作。
环境依赖
- 控制端:Ansible ≥ 2.9
- 目标主机:Linux(支持 user/group 模块),Python ≥ 2.7 或 3.x
- 被管理主机需在控制端 inventory 中定义,并配置 SSH 免密或密码认证
Playbook 实现
创建 manage_users.yml,核心逻辑基于 user 模块的 state 参数区分创建/删除操作。密码使用 password_hash 过滤器生成加密哈希,sudo 权限通过将用户加入 wheel 组(CentOS/RHEL)或 sudo 组(Debian/Ubuntu)实现,具体组名由变量 sudo_group 指定。
---
- name: 管理用户账户
hosts: all
become: yes
vars:
# 用户配置列表,按需增删条目
users:
- name: alice
state: present
uid: 2001
groups: "developers,{{ sudo_group }}"
password: "{{ 'Alice@123' | password_hash('sha512') }}"
shell: /bin/bash
append: yes
- name: bob
state: present
groups: "{{ sudo_group }}"
password: "{{ 'Bob@456' | password_hash('sha512') }}"
shell: /bin/bash
append: yes
- name: tempuser
state: absent
sudo_group: "{{ 'wheel' if ansible_os_family == 'RedHat' else 'sudo' }}"
tasks:
- name: 确保所需的用户组存在
group:
name: developers
state: present
when: users | selectattr('state', 'equalto', 'present') | map(attribute='groups') | select('search', 'developers') | list | length > 0
- name: 创建或修改用户
user:
name: "{{ item.name }}"
state: "{{ item.state }}"
uid: "{{ item.uid | default(omit) }}"
groups: "{{ item.groups | default(omit) }}"
password: "{{ item.password | default(omit) }}"
shell: "{{ item.shell | default(omit) }}"
append: "{{ item.append | default(False) }}"
remove: yes # 删除用户时同时移除家目录
loop: "{{ users }}"
when: item.state == 'present' or item.state == 'absent'
- name: 验证用户状态
command: "id {{ item.name }}"
register: user_check
changed_when: false
failed_when: false
loop: "{{ users }}"
when: item.state == 'present'
运行方式
# 语法检查
ansible-playbook manage_users.yml --syntax-check
# 执行 Playbook(需提前配置 inventory)
ansible-playbook -i your_inventory.ini manage_users.yml
# 仅对特定主机执行
ansible-playbook -i your_inventory.ini manage_users.yml --limit web01
验证方法
- 创建成功:Playbook 执行后无
failed任务,且最后一个验证任务输出uid=2001(alice) ...等用户信息。 - sudo 权限:在目标主机执行
sudo -l -U alice,应显示(ALL) ALL或类似授权条目。 - 删除生效:执行
id tempuser应返回no such user,且/home/tempuser目录不存在。 - 幂等性:再次运行同一 Playbook,所有任务应显示
ok而非changed(除首次执行外)。
关键说明
- 密码哈希由控制端生成,明文密码不会出现在目标主机日志中。若需修改密码,直接更新
users变量中的password字段。 append: yes确保用户附加到指定组时不会移除其默认组;若需覆盖默认组,可设为no。- 删除用户时
remove: yes会同时删除其家目录和邮件池,如不需要可改为remove: no。 - 若目标主机使用 NIS/LDAP 等外部用户源,
user模块可能无法管理,需改用ldap等专用模块。