Reputation: 13561
I have this idea for my Ansible inventory: I want to have only ONE vaulted value, a seed whicht gives birth to all the passwords I need in my inventory.
Something like this:
---
# I only have this to generate randomly, and vault
inventory_seed: "a strong random string"
# Then all my other password are derived from this seed.
# I feed the salted seed to a filter that creates a password directly sourced from the string I give him.
# will output, say, `wgSqz$@+SU^nw2;I` everytime I invoke ansible for the same inventory_hostname
machine_root_password: "{{ inventory_hostname + inventory_seed + 'root password' | to_strong_password }}"
# same: dp_password will be the same strong password everytime I invoke ansible
db_password: "{{ inventory_seed + 'db password' | to_strong_password }}"
# ... etc. All my inventory-specific passwords (and other keys) are derived from the same seed
This approach would help with the following issues:
Also I would expand this to generate keypairs, certificates and so on. Starting up a new inventory would be reduced to only specifying one or two vars instead of dozens.
Does this exist in the (comprehensive) Jinja / Ansible filters?
I am aware of the lookup( 'password', xxx)
method, but this is not reproducible: it doesn't take a seed as input to output the same password if the same seed is provided. I also know that this is an often asked question here, but every time the password is saved locally which I don't want.
Will I have to implement this on my own?
How would you expand to generate other sensible but required data (X509 certs, keypairs, etc.)
Upvotes: 5
Views: 837
Reputation: 11
I use something like this.
- name: Create idempotent secret
ansible.builtin.set_fact:
secret: "{{ lookup('ansible.builtin.password', '/dev/null seed={{ inventory_hostname }} length=40 chars=ascii_letters') }}"
- name: Debug
ansible.builtin.debug:
var: secret
More information available in the docs but I'm afraid the documentation is incorrect/outdated.
Upvotes: 0
Reputation: 12142
Reading your requirements it sound for me like an old fashioned codebook or one-time-pad (OTP). You may find more information @https://crypto.stackexchange.com/.
I want to have only ONE vaulted value ...
Whereby your one vaulted value would be the codebook, which could be in example a very long random string or file (How do I create a 1GB random file?). You could define a character set and make it as long as you like, hundreds of kilobytes. It could also be a huge text file or just a video.
a seed which gives birth to all the passwords
The seed would you be a pointer to a position in that codebook or file and by defining the length you can just read out passwords you like.
Upvotes: 1
Reputation: 4294
The solution is to use password_hash
which can also be combined with a salt and a seed.
Here are some examples:
# uses a random salt
# -> output changes on each run
{{ 'rootpassword' | password_hash('sha512') }}
# uses a user defined salt
# -> output always stays the same
{{ 'rootpassword' | password_hash('sha512', 'secretsalt') }}
# creates a random numeric salt by using the inventory_hostname as a seed
# -> output is unique for every host and stays the same on each run
{{ 'rootpassword' | password_hash('sha512', 12345 | random(seed=inventory_hostname) | string) }}
Upvotes: 3