首页 > 解决方案 > 使用 Ansible 精细管理系统用户

问题描述

我正在使用Ansible剧本来管理用户(取自https://keksi.io/tutorials/2016/12/05/how-to-manage-remote-server-users-with-ansible/):

vars/users.yml文件(用户、用户到组分配、密码、SSH 密钥):

---
users:

  - username: user1
    comment: "User 1"
    group: admin
    password: "sha password"
    keys:
      active:
        - "ssh-rsa etc"
    admin: yes

  - username: user2
    comment: "User 2"
    group: users
    groups: deployer
    keys:
      active:
        - "ssh-rsa etc"

  - username: user3
    [...]

这是剧本:

- hosts: all
  become: true

  tasks:
    - include_vars: ../vars/users.yml

    - name: Install sudo
      apt: name=sudo state=present

    - name: Add the group admin
      group:
        name: admin
        state: present

    - name: Create users
      user:
        name: "{{ item.username }}"
        comment: "{{ item.comment | default('User {{item.username}}') }}"
        password: "{{ item.password | default('!') }}"
        state: "{{ item.state | default('present') }}"
        shell: "{{ item.shell | default('/bin/bash') }}"
        group: "{{ item.group | default('users') }}"
      when: item.username is defined
      with_items: '{{ users }}'

    - name: Setup administrator users with complete sudo access
      user: name={{ item.username }} groups=sudo append=yes
      with_items: '{{ users }}'
      when: item.admin is defined and item.admin == True

    - name: Add SSH-keys to users
      authorized_key:
        user: "{{ item.0.username }}"
        key: "{{ item.1 }}"
      with_subelements:
        - "{{ users }}"
        - keys.active
        - flags:
          skip_missing: True
      when: item.0.state is not defined or item.0.state != "absent"

    - name: Remove old SSH-keys from users
      authorized_key:
        user: "{{ item.0.username }}"
        key: "{{ item.1 }}"
        state: absent
      with_subelements:
        - "{{ users }}"
        - keys.disabled
        - flags:
          skip_missing: True
      when: item.0.state is not defined or item.0.state != "absent"

我可以在所有服务器上正确执行此剧本,并在其上创建和管理管理员和普通用户。

现在我想添加一个新步骤。我有几台服务器,并不是每个用户都应该在每台服务器上配置,一些用户应该只在一些服务器上的附加组中(例如开发服务器上的开发人员)。

所以我希望为主机或主机组上的用户创建一些分配,例如:

- host: host1
  admins:
    - user1
    - user2
  deployers:
    - user2
    - user3
  users:
    - user4
    - user5

- host: hostgroup1
  admins:
    - user2
  users:
    - user3
    - user5

因此,我希望能够在所有服务器上执行剧本,以根据此声明创建或更新用户,而无需为每个主机编写剧本的副本。

我不知道如何实现这一点,你能帮我吗?


编辑:我试图在我的 users.yml 变量文件中添加一个新的“hosts”键,这样:

---
users:

  - username: user1
    comment: "User 1"
    group: admin
    password: "sha password"
    keys:
      active:
        - "ssh-rsa etc"
    admin: yes

  - username: user2
    comment: "User 2"
    group: users
    groups: deployer
    keys:
      active:
        - "ssh-rsa etc"
    hosts:
      user:
        - host1
        - host2
      deployer:
        - host3

我这样修改了任务:

- name: Create users
  user:
    name: "{{ item.username }}"
    comment: "{{ item.comment | default('User {{item.username}}') }}"
    password: "{{ item.password | default('!') }}"
    state: "{{ item.state | default('present') }}"
    shell: "{{ item.shell | default('/bin/bash') }}"
    group: "{{ item.group | default('users') }}"
  with_items: '{{ users }}'
  when: item.username is defined and ((item.admin is defined and item.admin == True) or (item.hosts is defined and item.hosts.user is defined and inventory_hostname in item.hosts.user)

我的解释:如果它是管理员,我需要创建用户(因此必须在每个主机上创建它,或者如果当前主机的 inventory_hostname 列在主机子键数组之一中(在第二步中,我希望扩展此检查,如果当前主机位于 item.hosts 子键之一中列出的主机组中。

问题是这样创建了 user1(因为 item.admin 为 True),但 user2 不是因为其他条件始终为 False。

标签: ansible

解决方案


您可以使用 host_vars 或 group_vars 来存储用户数据,而不是 vars/users.yml

当您针对多个主机运行 playbook 时,将从相关的 group_vars 或 host_cars 文件中读取每个主机或组成员的适当值

有关更多信息,请参见此处:https ://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#splitting-out-host-and-group-specific-data


推荐阅读