Creating the Ansible user
When you create a machine (or rent one from any hosting company), it arrives with only the root user, or other users such as vagrant. Let's start creating a playbook that ensures that an Ansible user is created, it's accessible with an SSH key, and is able to perform actions on behalf of other users (sudo) with no password required. We often call this playbook firstrun.yaml, since we execute it as soon as a new machine is created, but after that, we don't use it, since we disable the default user for security reasons. Our script will look something like the following:
---
- hosts: all
user: vagrant
tasks:
- name: Ensure ansible user exists
user:
name: ansible
state: present
comment: Ansible
become: True
- name: Ensure ansible user accepts the SSH key
authorized_key:
user: ansible
key: https://github.com/fale.keys
state: present
become: True
- name: Ensure the ansible user is sudoer with no password required
lineinfile:
dest: /etc/sudoers
state: present
regexp: '^ansible ALL\='
line: 'ansible ALL=(ALL) NOPASSWD:ALL'
validate: 'visudo -cf %s'
become: True
Before running it, let's look at it a little bit. We have used three different modules (user, authorized_key, and lineinfile) that we have never seen.
The user module, as the name suggests, allows us to make sure a user is present (or absent).
The authorized_key module allows us to ensure that a certain SSH key can be used to log in as a specific user on that machine. This module will not substitute all the SSH keys that are already enabled for that user, but will simply add (or remove) the specified key. If you want to alter this behavior, you can use the exclusive option, which allows you to delete all the SSH keys that are not specified in this step.
The lineinfile module allows us to alter the content of a file. It works in a very similar way to sed (a stream editor), where you specify the regular expression that will be used to match the line, and then specify the new line that will be used to substitute the matched line. If no line is matched, the line is added at the end of the file.
Now let's run it with the following code:
$ ansible-playbook -i test01.fale.io, firstrun.yaml
This will give us the following result:
PLAY [all] *********************************************************
TASK [Gathering Facts] *********************************************
ok: [test01.fale.io]
TASK [Ensure ansible user exists] **********************************
changed: [test01.fale.io]
TASK [Ensure ansible user accepts the SSH key] *********************
changed: [test01.fale.io]
TASK [Ensure the ansible user is sudoer with no password required] *
changed: [test01.fale.io]
PLAY RECAP *********************************************************
test01.fale.io : ok=4 changed=3 unreachable=0 failed=0