Create a user on a remote server using Ansible (with code)
A practical example on how Ansible is a time saver and a reliable tool to perform operations on a remote machine
Ansible is a really good tool for managing multiple servers using SSH and well defined files called playbooks, in which a developer can set a list of commands to perform on a remote machine.
TLDR: The playbook is available here.
In the first lines, it is specified the playbook name, the hosts on which this playbook will be executed (defined in the inventory file) and a command to perform privilege escalation (become
), otherwise we would not be able to create the user. It is important to run the playbook with a user having sudo privileges.
- name: Add user with SSH key and sudo privileges
hosts: [HOSTS] # set the hosts name according to the inventory
become: yes
After that, we define the variables. In our case, the name of the new user and his SSH public key using the file location. The lookup function allows us to use external sources such as files. For example, in my case I save the public keys in “staff_keys/name.pub
”. The relative path must starts from where you launch the ansible-playbook command!
vars:
new_user: [USERNAME]
ssh_public_key_file: "{{ lookup('file', [USERPATH]) }}"
Next, there are the tasks, so what the playbook has to perform.
It starts with the account creation, using the default ansible user module. Clearly, the user name is taken from the variable. If you are not using bash as your shell, change the path.
- name: Create the user
user:
name: "{{ new_user }}"
state: present
groups: sudo
shell: /bin/bash
Now, we have to set the SSH key for the new user, and it can be done by the authorized_key built-in module.
- name: Set up authorized_keys for the user
authorized_key:
user: "{{ new_user }}"
state: present
key: "{{ ssh_public_key_file }}"
Now we get the first optional task. If you want to set the user as capable to perform sudo operations, you need to include the following task (present in the gist). This will add the line [USERNAME] ALL=(ALL) NOPASSWD: ALL
in the sudoers file. Thanks to the Ansible nature, this task (and in general almost each task with a built in module) will add the user to the sudoers only if it wasn’t already added. So it will not write one line for each time you run the playbook.
- name: Allow sudo without password for the user
lineinfile:
path: /etc/sudoers
state: present
regexp: "^{{ new_user }}"
line: "{{ new_user }} ALL=(ALL) NOPASSWD: ALL"
validate: "/usr/sbin/visudo -cf %s"
Another important thing I do is to disable the password authentication for the user, allowing him only to access using his SSH key. As you can see, it’s setting PasswordAuthentication
to the value “no
”
- name: Disable password authentication for the user
lineinfile:
path: /etc/ssh/sshd_config
state: present
regexp: "^PasswordAuthentication"
line: "PasswordAuthentication no"
notify: Restart SSH
Finally, you can see that in the last task there is a notify called “Restart SSH
”. In fact, when you add a new user or update a configuration, you have to restart the SSH service. To perform this, it is sufficient to create an handler in the playbook file called “Restart SSH” like the following.
handlers:
- name: Restart SSH
service:
name: sshd
state: restarted
This will restart the sshd
service that manages SSH.
✅ Congratulations! You learned how to create a user through Ansible, enabling SSH access, sudo access and disabling authentication.