Ansible reads from KeePass
For small projects, I’d still like to handle their credentials carefully while keeping the effort small.
Since KeePass is a low-effort Password Manager, why not get automation tools to read credentials from KeePass? Then, having been read, those credentials are available for downstream processes.
I found a way that works with Ansible and KeePass, where the following steps work:
- Save a test entry (e.g., Username) in Keepass.
- Encrypt Password for KeePass and set it in Ansible.
- Ansible uses that encrypted password to read in username and print to console.
tl;dr see code on GitHub
Prepare KeePass
- Create a KeePass database file. There’s an example
AnsiblePrototype.kdbx
in the Ansible folderansible/securevars/files
. - Add an entry with username
test_username
Use Ansible Vault Ids
I used Ansible’s vault-id
as described in a RedHat tutorial.
Trying to encrypt using the file keepass.secret
didn’t work for me. I always get “permission denied” problems. Since I’m using WSL2, I’d rather tackle WSL file permissions another time.
So, I used the encrypt_string
option to encrypt the password of KeePass. More on that later.
Ansible config
1
2
3
4
5
6
# file: ansible/ansible.cfg
/path/to/til/ansible$> cat ansible.cfg
[defaults]
inventory = hosts
# pre-create two vault password files
vault_identity_list = inline@securevars/files/.inline_pass, files@securevars/files/.files_pass
Copy these 2 files .file_pass
and .inline_pass
to /path/to/til/ansible/securevars/files/
Their contents are up to you. Mine look like this:
1
2
3
4
5
6
# file: ansible/ansible.cfg
/path/to/til/ansible$> cat securevars/files/.inline_pass
use-this-to-encrypt-strings
/path/to/til/ansible$> cat securevars/files/.inline_pass
use-this-to-encrypt-files
Update Ansible files
Update Ansible files.
Update hosts
1
2
3
4
5
# file: ansible/hosts
/path/to/til/ansible$> cat hosts
# useful for testing locally.
# https://docs.ansible.com/ansible/latest/inventory/implicit_localhost.html
localhost ansible_connection=local ansible_python_interpreter="{{ansible_playbook_python}}" gather_facts=false
Update main task
Create securevars/tasks/main.yml
1
2
3
4
5
6
7
# file: securevars/tasks/main.yml
- include_tasks: get_from_keepass.yml
with_items:
- "test_a"
- name: Display KeePass Output
debug:
msg: "Keepass Output is '{{ test_a }}'"
Create securevars/tasks/get_from_keepass.yml
. Hint came by way of a reddit comment
1
2
3
4
5
6
# file: securevars/tasks/get_from_keepass.yml
- name: get vars
ansible.builtin.include_vars: host_vars/localhost.yaml
no_log: True
- ansible.builtin.set_fact: "{{ item }}={{ lookup('viczem.keepass.keepass', 'AnsibleWithKeePass/{{ item }}', 'username') }}"
Update variables
In the host_vars
is where we keep the variables that we want to use.
1
2
3
4
5
6
7
8
9
10
# file: securevars/host_vars/localhost.yml
# vars for module, viczem.keepass
# Socket TTL in seconds
keepass_ttl: 30
# path to Keepass database
keepass_dbx: "securevars/files/AnsibleTil.kdbx"
keepass_psw: !vault |
$ANSIBLE_VAULT;1.2;AES256;inline
12345....
Encrypt KeePass password
The password for KeePass should be encrypted. Generate it as follows. I’m running Ansible in its own virtual environment.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$> cd /path/to/til/ansible
# if you have python installed but no venv, run
/path/to/til/ansible$> python3 -m venv venv
# if you have a venv, activate it
/path/to/til/ansible$> source venv/bin/activate
(venv) /path/to/til/ansible$> read -s -p "Enter Keepasswd: " KEEPASS_PASSWD
# enter password for the keepass database
(venv) /path/to/til/ansible$> export KEEPASS_PASSWD
# use vault-id 'inline' to encrypt KEEPASS_PASSWD for variable name 'keepass_psw'
(venv) /path/to/til/ansible$> ansible-vault encrypt_string --encrypt-vault-id inline "$KEEPASS_PASSWD" --name 'keepass_psw'
# output should look like
Encryption successful
keepass_psw: !vault |
$ANSIBLE_VAULT;1.2;AES256;inline
65123...
Copy that whole string, starting from ‘keepass_psw’ and paste it in the file, securevars/host_vars/localhost.yml
where the key, keepass_psw
is.
Run Playbook
1
2
3
4
5
6
7
8
# run playbook
(venv) /path/to/til/ansible$>ansible-playbook setup.yml
# output should have an entry like
TASK [securevars : Display KeePass Output] *****************************
ok: [localhost] => {
"msg": "KeyPass Output is 'test_username' "
}
Troubleshooting
Ensure that the module is installed
If you get the error below, check that you’ve installed the ansible module viczem.keepass.keepass
. Take a look at the module’s installation steps.
1
fatal: [localhost]: FAILED! => {"msg": "lookup plugin (viczem.keepass.keepass) not found"}
Ensure correct KeePass password is encrypted
If you get the error below, check that the password you entered in KEEPASS_PASSWD
is the correct one for the KeePass database.
1
fatal: [localhost]: FAILED! => {"msg": "An unhandled exception occurred while running the lookup plugin 'viczem.keepass.keepass'. Error was a <class 'ansible.errors.AnsibleError'>, original message: KeePass: socket connection failed for /home/wsl/path/to/ansible/securevars/files/AnsibleTilPPrototype.kdbx. KeePass: socket connection failed for home/wsl/path/to/ansible/securevars/files/AnsibleTilPPrototype.kdbx"}