I have a list of users (this is not actual Ansible code, just an example):
users:
-tom
-jerry
-pluto
Now I am trying to create a dynamic structure ( list of dictionaries ?) like this, for setting random (at runtime) passwords to them:
users_and_passwords:
-tom, "random_password_here1"
-jerry, "random_password_here2"
-pluto, "random_password_here3"
How can I write a set_fact task to generate random password for each user and save it for later use?
How can I then read that and use it in other tasks later?
So far I tried declaring a list of users (later to be looped from a file), then an empty list of passwords. Now I am trying to populate the Password list with random strings, then to combine them into a single {user:password} dict.I can't figure out how to do this easier, and I am stuck in the "populate password list" phase.
users:
-top
-jerry
-pluto
passwords: []
tasks:
- name: generate passwords in an empty Dict
set_fact:
passwords: "{{ passwords | default({}) {{ lookup('password', '/dev/null chars=ascii_lowercase,ascii_uppercase,digits,punctuation length=20') }} }}"
with_items: "{{users}}"
CodePudding user response:
Rather than having a complex dictionary that would read:
- tom: password123456
- jerry: password123456789
- muttley: password12345
Aim for a structure that would be normalized, like:
- name: tom
password: password123456
- name: jerry
password: password123456789
- name: muttley
password: password12345
This can be achieved with the task:
- set_fact:
users_with_passwords: >-
{{
users_with_passwords | default([])
[{
'name': item,
'password': lookup(
'password',
'/dev/null chars=ascii_lowercase,ascii_uppercase,digits,punctuation length=20'
)
}]
}}
loop: "{{ users }}"
And, can be easily accessed via something like:
- debug:
msg: "{{ item.name }}'s password is `{{ item.password }}`"
loop: "{{ users_with_passwords }}"
loop_control:
label: "{{ item.name }}"
Given the playbook
- hosts: localhost
gather_facts: no
vars:
users:
- tom
- jerry
- muttley
tasks:
- set_fact:
users_with_passwords: >-
{{
users_with_passwords | default([])
[{
'name': item,
'password': lookup(
'password',
'/dev/null chars=ascii_lowercase,ascii_uppercase,digits,punctuation length=20'
)
}]
}}
loop: "{{ users }}"
- debug:
msg: "{{ item.name }}'s password is `{{ item.password }}`"
loop: "{{ users_with_passwords }}"
loop_control:
label: "{{ item.name }}"
This yields:
TASK [set_fact] *************************************************************
ok: [localhost] => (item=tom)
ok: [localhost] => (item=jerry)
ok: [localhost] => (item=muttley)
TASK [debug] ****************************************************************
ok: [localhost] => (item=tom) =>
msg: tom's password is `tLY>@jg6k/_|sqke{-mm`
ok: [localhost] => (item=jerry) =>
msg: jerry's password is `Liu1wF@gPM$q^z~g|<E1`
ok: [localhost] => (item=muttley) =>
msg: muttley's password is `BGHL_QUTHmbn\(NGW`pJ`
CodePudding user response:
How can I write a
set_facttask to generate random password for each user and save it for later use?
This sound like a task for the password_lookup which "Retrieves or generate a random password, stored in a file", in Example
- name: Create random but idempotent password
set_fact:
toms_password: "{{ lookup('password', '/dev/null', seed=username) }}"
How can I then read that and use it in other tasks later?
Just by Using variable name which was defined during set_fact.
Further readings
