I inherited a project where all database users have the same password (bad!). This password is stored in an Ansible Vault (good). I want to modify the roles so that each user has a unique password stored in the vault.
Current Vault:
---
DB_USER: secretpass
Current Vars:
mysql_remote_users_enabled:
- user: user1
host: ip_address1
- user: user2
host: ip_address2
Current Task:
- name: "mysql remote users present"
mysql_user:
login_user: root
login_password: "{{ mysql_root_passwd }}"
name: "{{ remote_user.user }}"
host: "{{ remote_user.host }}"
password: "{{ DB_PASS }}"
state: present
with_items:
"{{ mysql_remote_users_enabled }}"
loop_control:
loop_var: remote_user
How can I store a unique password for each user in the vault and access these vault variables dynamically in my Ansible task?
The more practical way of doing it is to do the encryption at the value level:
## The password for those two vaulted value is `foobar`
mysql_remote_users_enabled:
- user: user1
host: ip_address1
password: !vault |
$ANSIBLE_VAULT;1.1;AES256
3633353366323334653265343961373732346331363565336139326136623
1343661633131323938383465396565363364333237383436323139633232
3336310a62316362623361393730343765346234343266386165663038636
2656562363834653534376565653335623432646366646433363735333034
313662646166620a653965646263366133336362376332333435653932313
2613664353533326230
- user: user2
host: ip_address2
password: !vault |
$ANSIBLE_VAULT;1.1;AES256
3538333130323831313136653338316261643832336237646639646264343
5303832306663663936383637326233643733316565323133356536613432
6530640a31373161323238663062623035346338613766653239633432393
2396666666437336235316334353463643737356262313662646339633831
393833646162630a656636636331633532396532373863666366636162663
2303366666538663962
Then, use it in the task:
- name: MySQL remote users
mysql_user:
login_user: root
login_password: "{{ mysql_root_passwd }}"
name: "{{ remote_user.user }}"
host: "{{ remote_user.host }}"
password: "{{ remote_user.password }}"
state: present
loop: "{{ mysql_remote_users_enabled }}"
loop_control:
loop_var: remote_user
To vault a single value, use the encrypt_string
command of ansible-vault
:
# For example to encrypt `foo`
$ ansible-vault encrypt_string 'foo'
New Vault password:
Confirm New Vault password:
Encryption successful
!vault |
$ANSIBLE_VAULT;1.1;AES256
3633353366323334653265343961373732346331363565336139326136623
1343661633131323938383465396565363364333237383436323139633232
3336310a62316362623361393730343765346234343266386165663038636
2656562363834653534376565653335623432646366646433363735333034
313662646166620a653965646263366133336362376332333435653932313
2613664353533326230
Note: you can also use it with a different vault ID or a password files, for more options see the documentation, or the --help
of ansible-vault
.
As for accessing a variable dynamically, this is unrelated to vaulting, the way to access a dynamic variable, vaulted or not, is to use the vars
lookup.
For example:
- debug:
msg: "{{ lookup('vars', 'DB_' ~ remote_user.user | upper ~ '_PASS') }}"
vars:
remote_user:
user: user1
DB_USER1_PASS: foobar
Would yield
ok: [localhost] =>
msg: foobar