Ensure only specific list of users exist with Ansible
This is a similar answer to @Konstantin Suvorov's but a bit more refined, with some nuances clearly spelled out, and actually tested and in-use.
Using the following, you only need maintain a single list of usernames you wish to have access. Any additions or removals from that list will be reflected in host access.
Optional helpful tip: We actually choose to use our GitHub usernames for this list, as then we can easily add SSH keys as well. See the end for an example.
First, in our group_vars
we define our list of developers we wish to have access (note that this can be defined in multiple ways, not just group_vars
):
developers:
- user1
- user2
- etc...
Second, we create a group for which we will assign our developers to:
- name: Create "developers" group
group:
name: developers
state: present
Third, we add our developers to this group. NOTE that we add them via the groups
and not group
property. This adds it as a secondary group and ensures they appear in /etc/group
. This is critical because if you add them as a primary group, they will not appear as a member of that group in /etc/group
:
- name: Add user accounts
user:
name: "{{ item }}"
shell: /bin/bash
groups: [developers]
state: present
with_items: "{{ developers }}"
Fourth, we then get all users that currently belong to the developers group on the host (Note that this is dependent on the primary/secondary assumption mentioned in the prior step) :
- name: Determine existing users
shell: 'grep developers /etc/group | cut -d: -f4 | tr "," "\n"'
changed_when: false
register: existing_users
Fifth, determine which of those users should be removed (e.g. those that are not defined in our developers
group_vars list):
- name: Determine removed users
set_fact:
removed_users: "{{ existing_users.stdout_lines | difference(developers) }}"
Sixth and last, remove them:
- name: Delete removed user accounts
user:
name: "{{ item }}"
state: absent
with_items: "{{ removed_users }}"
Optional helpful step - If adding users by GitHub username, you can easily grant them SSH access from the public key they have available on GitHub:
- name: Add public ssh keys of users
authorized_key:
user: "{{ item }}"
exclusive: yes
key: https://github.com/{{ item }}.keys
state: present
with_items: "{{ developers }}"
You need to do some extra tasks here.
After adding all required users, grab existing users, e.g.:
- shell: 'grep {{ common_adm_group }} /etc/group | cut -d: -f4 | tr "," "\n"'
changed_when: false # Make task green
register: existing_users
and remove stale ones:
- user:
name: "{{ item }}"
state: absent
with_items: "{{ existing_users.stdout_lines | difference(common_adm_users | map(attribute='name') | list) }}"
Note: code is not tested, may contain typos etc.