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 等专用模块。