确保 Ansible 仅存在特定的用户列表

确保 Ansible 仅存在特定的用户列表

我们使用 Ansible 创建用户并执行以下任务:

- name: Create adm users
  user:
    name: "{{ item.name }}"
    group: "{{ common_adm_group }}"
    createhome: yes
    password: "!!"
    update_password: always
    state: present
  with_items: "{{ common_adm_users }}"

common_adm_users 是这样的:

  - name: user1
    comment: "First Last"
    ssh_key: "ssh-rsa AAAAB3Nza..."

这对于创建用户来说很有效,但是当有人离开团队时,仅将其用户从 common_adm_users 中删除并不会导致当我们重新应用包含此任务的角色时将其从服务器中删除。

维护准确的用户列表的最佳做法是什么?

答案1

这与@Konstantin Suvorov 的答案类似,但更加精致,一些细微差别清晰明了,并且经过了实际测试和使用。

使用以下内容,您只需维护一个您希望访问的用户名列表。该列表中的任何添加或删除都将反映在主机访问中。

可选的有用提示:我们实际上选择使用我们的 GitHub 用户名来列出此列表,因为这样我们也可以轻松添加 SSH 密钥。请参阅末尾的示例。

首先,我们group_vars定义我们希望访问的开发人员列表(请注意,这可以通过多种方式定义,而不仅仅是group_vars):

developers:
  - user1
  - user2
  - etc...

其次,我们创建一个小组,并将开发人员分配到以下任务中:

- name: Create "developers" group
  group:
    name: developers
    state: present

第三,我们将我们的开发人员添加到这个组中。groups请注意,我们通过and not属性添加它们group。这会将其添加为次要组并确保它们出现在 中/etc/group。这很关键,因为如果您将它们添加为主要组,它们将不会作为该组的成员出现在 中/etc/group

- name: Add user accounts
  user:
    name: "{{ item }}"
    shell: /bin/bash
    groups: [developers]
    state: present
  with_items: "{{ developers }}"

第四,我们获取当前属于主机上开发人员组的所有用户(请注意,这取决于上一步中提到的主要/次要假设):

- name: Determine existing users
  shell: 'grep developers /etc/group | cut -d: -f4 | tr "," "\n"'
  changed_when: false 
  register: existing_users

第五,确定哪些用户应该被删除(例如,那些未在我们的developersgroup_vars 列表中定义的用户):

- name: Determine removed users
  set_fact:
    removed_users: "{{ existing_users.stdout_lines | difference(developers) }}"

第六步,也是最后一步,删除它们:

- name: Delete removed user accounts
  user:
    name: "{{ item }}"
    state: absent
  with_items: "{{ removed_users }}"

可选的有用步骤 - 如果通过 GitHub 用户名添加用户,您可以轻松地从他们在 GitHub 上提供的公钥授予他们 SSH 访问权限:

- name: Add public ssh keys of users
  authorized_key:
    user: "{{ item }}"
    exclusive: yes
    key: https://github.com/{{ item }}.keys
    state: present
  with_items: "{{ developers }}"

答案2

您需要在这里做一些额外的任务。

添加所有必需的用户后,获取现有用户,例如:

- shell: 'grep {{ common_adm_group }} /etc/group | cut -d: -f4 | tr "," "\n"'
  changed_when: false # Make task green
  register: existing_users

并删除陈旧的:

- user:
    name: "{{ item }}"
    state: absent
  with_items: "{{ existing_users.stdout_lines | difference(common_adm_users | map(attribute='name') | list) }}"

注意:代码未经测试,可能包含拼写错误等。

答案3

您实际上可以向现有任务中添加一个字段:

- name: Create adm users
  user:
    name: "{{ item.name }}"
    group: "{{ common_adm_group }}"
    createhome: yes
    password: "!!"
    update_password: always
    state: "{{ item.state | default('present') }}"
  with_items: "{{ common_adm_users }}"

然后使离职团队成员的数据看起来像这样:

- name: user1
    comment: "First Last"
    ssh_key: "ssh-rsa AAAAB3Nza..."
    state: "absent"

相关内容