ThorneLabs

Ansible Manage the Same Users Across Servers with Different Passwords

• Updated March 17, 2019


Recently, I was setting up a handful of servers that all needed the same user created but with a different password for that user on each server. After Google searching, I did not find a definitive way to manage users, and most of what I found consisted of bits and pieces of what I was looking for. I ultimately settled on the following solution.

This solution can definitely be improved upon by using group_vars and variable overrides to remove redundant attributes.

This post assumes you have some experience with Ansible and already have an existing Ansible Environment. If you are new to Ansible, learn how to install Ansible, create your first inventory file, create and run Ansible Playbooks, and run Ansible commands.

Ansible Directory

My Ansible Environment exists within directory ~/Development/ansible-lab on my workstation. Any files or directories created in this post will be created within this directory.

Ansible Inventory File

As mentioned above, I had five servers that all needed the same user created but with a different password for that user on each server, so I created file ~/Development/ansible-lab/hosts with the following contents:

server1.example.com
server2.example.com
server3.example.com
server4.example.com
server5.example.com

Ansible Host Variables

Next, I created a host_vars directory and changed into that directory:

mkdir ~/Development/ansible-lab/host_vars

cd ~/Development/ansible-lab/host_vars

Inside the host_vars directory, I created five files named after the sever’s Ansible Inventory Name, so one file named server1.example.com, a second file named server2.example.com, etc. The host_vars files must be named exactly as they are named in the Ansible Inventory File so the Ansible Task can reference the variables.

Each host_vars file contained the following contents but the hashed password would be different for each file (learn how to hash user passwords):

---
users:
 mal:
   password: $1$.NUoqVPD$RX8Bkhy/LBuuO0MDztQU.1
   shell: /bin/bash
   state: present

Ansible Playbook

Next, I changed back into the ansible-lab directory:

cd ~/Development/ansible-lab

I created a playbooks directory and changed into that directory:

mkdir ~/Development/ansible-lab/playbooks

cd ~/Development/ansible-lab/playbooks

Inside of the playbooks directory, I created an Ansible Playbook called users.yml with the following contents:

---
- hosts: all

  tasks:
  - name: Add users from host_vars file
    action: user name={{ item.key }} password={{ item.value.password }} shell={{ item.value.shell }} state={{ item.value.state }} update_password=always
    with_dict: users

This particular task will loop through all of the users defined in each server’s host_vars file. Because there is only one user, only one user will be created, but if there were N number of users, N number of users would be created.

If a particular user’s password needs to be changed, go to the particular host_vars file for the server the user’s password needs to be changed on, modify the password, and re-run the users.yml Ansible Playbook to update the user’s password.

In addition, if a particular user needs to be removed from a particular server, go to the particular host_vars file for the server that the user needs to be removed from, change the value of the state attribute from present to absent, and re-run the users.yml Ansible Playbook to remove that user.

Additional functionality can be added to this Ansible Task by using the other attributes available in the Ansible User Module.

References