73 lines
3.8 KiB
Markdown
73 lines
3.8 KiB
Markdown
# ansible-mail-infra
|
|
|
|
Set up infrastructure for all things e-mail
|
|
|
|
# Prep
|
|
|
|
On your Ansible controller make sure the `sshpass` binary exists if Ansible has to connect to target machines via SSH username-password authentication instead of SSH key authentication. The binary usually comes with a package of the same name.
|
|
|
|
We're assuming that you're running Ansible as a Python package inside a virtual environment. Install Ansible like so:
|
|
```
|
|
pip install ansible
|
|
```
|
|
|
|
We're also assuming that secrets are stored in a HashiCorp Vault instance to which you have access. These roles access Vault via `hvac`, the HashiCorp Vault API client for Python 3.x, see [github.com/hvac/hvac](https://github.com/hvac/hvac) for reference. Install it like so:
|
|
```
|
|
pip install hvac
|
|
```
|
|
|
|
# Vars
|
|
|
|
* For default variables copy [ansible/roles/20-common-20-ssh/defaults/main.yml.example](ansible/roles/20-common-20-ssh/defaults/main.yml.example) to a proper `ansible/roles/20-common-20-ssh/defaults/main.yml`, adjust as needed.
|
|
|
|
* Create your inventory, copy [ansible/hosts.yml.example](ansible/hosts.yml.example) to a proper `ansible/hosts.yml` file with at least one host in host group `all`.
|
|
|
|
* Replace [ansible/group_vars/all/vars.yml.example](ansible/group_vars/all/vars.yml.example) with a proper `ansible/group_vars/all/vars.yml` file and set at least `ansible_user` and Vault access variables.
|
|
|
|
* In [ansible/roles/20-common-20-ssh/files/root/.ssh](ansible/roles/20-common-20-ssh/files/root/.ssh) copy both [authorized_keys.example](ansible/roles/20-common-20-ssh/files/root/.ssh/authorized_keys.example) and [known_hosts.example](ansible/roles/20-common-20-ssh/files/root/.ssh/known_hosts.example) to proper files. They contain SSH authorized_keys and public SSH host keys you want installed on target machines.
|
|
|
|
# Vault structure
|
|
|
|
In Vault we're assuming that every host in your inventory has a secret stored that contains at least the following keys:
|
|
|
|
* `initial_password`: The operating system's local account password at machine creation. Ansible will use this to SSH into the machine during `first_run`, see section [Run it](#run-it) below.
|
|
* `password`: The new password you want to set for the operating system's local account.
|
|
* `password_salt`: The salt you're going to use. We're hashing the password with SHA-512, the salt is a string of up to 16 characters length.
|
|
|
|
For an example server `fully.qualified.domain.name` and example user `root` Vault secrets are located at `name/domain/qualified/fully/os/root/creds`. Per [ansible/group_vars/all/vars.yml.example](ansible/group_vars/all/vars.yml.example) the default secrets engine mount point is `kv` where this playbook expects a kv secrets engine.
|
|
|
|
# Run it
|
|
|
|
On first run execute it like so:
|
|
```
|
|
ansible-playbook --tags 'first_run' --inventory hosts.yml playbook.yml
|
|
```
|
|
|
|
The `first_run` tag ensures that `ansible_password` variable gets set which in turn causes Ansible to log in to target machines via SSH username-password authentication.
|
|
|
|
On subsequent runs like so:
|
|
```
|
|
ansible-playbook --inventory hosts.yml playbook.yml
|
|
```
|
|
|
|
## first_run
|
|
|
|
To make sure a `first_run` correctly runs all regular tasks plus `first_run`-specific tasks [ansible/roles/20-common-20-ssh/tasks/main.yml](ansible/roles/20-common-20-ssh/tasks/main.yml) has its `import_tasks` tagged as `first_run`.
|
|
|
|
```
|
|
- import_tasks: '20-ssh.yml'
|
|
tags:
|
|
- 'first_run'
|
|
```
|
|
|
|
As a result all tasks in that import inherit `first_run`. Two of them, however, must only run during `first_run` and never during normal operation. They get:
|
|
|
|
```
|
|
- name: '...'
|
|
tags:
|
|
- 'first_run'
|
|
- 'never'
|
|
```
|
|
|
|
This overrides the single `first_run` inherited tag. Ansible special tag `never` ensures that these particular tasks are _**never**_ executed unless `first_run` is called. Tasks outside of `20-common-20-ssh` role are not tagged with `first_run` at all so are ignored during a `first_run`.
|