When configuring a new server with Ansible, I wanted to create a new user, then switch to that new user for the remainder of the playbook. As with any Ansible playbook, it should be idempotent. The way to do accomplish this was not straightforward, due to the way the Ansible SSH user behaves.
The playbook layout
There are two roles:
maybecreateuser role wraps the
createuser with logic to test if the user exists and to handle the variable setup required to swap
createuser role contains the user creation tasks.
Testing if the user exists
- Stash the
ansible_userinto another variable, before swapping in the value of
initial_useris a variable defined by this role and should be the name of the initial root user on the server.
- Test if the user already exists by trying to SSH explicitly
Creating the user
- Create a user with no password set, to avoid dealing with password handling
- Copy the
initial_user, in order to SSH in as this new user. This assumes your
authorized_keysfile already (this is true on DigitalOcean if you provide your pubkey before creating the server).
- Give the user sudo rights without a password
None of these are hard requirements. You may want your user to have a password and not give it
nopasswd sudo. You may want to use a different SSH key.
Using it in a playbook
When using the
gather_facts: no must be set in the playbook. Otherwise, ansible will try to do
gather_facts which requires an SSH connection, but the
ansible_user might not exist yet.
initial_user if necessary to configure hosts whose initial user is not
ansible_user to whatever you want, or don't set it.