# group\_by with random key values

**URL:** <https://forum.ansible.com/t/group-by-with-random-key-values/33158>\
**Category:** Ansible Project\
**Created:** [June 11, 2020, 6:39pm UTC](https://forum.ansible.com/t/group-by-with-random-key-values/33158 "2020-06-11T18:39:07Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![mark.tovey](https://avatars.discourse-cdn.com/v4/letter/m/ce73a5/32.png) [@mark.tovey](https://forum.ansible.com/u/mark.tovey)\
**Post date:** [June 11, 2020, 6:39pm UTC](https://forum.ansible.com/t/group-by-with-random-key-values/33158/1 "2020-06-11T18:39:07Z")

</div>

I am trying to develop a playbook to set a common password on groups of servers. The concept is that all servers within a given group would receive one randomly generated password, all servers within the next group would receive a different randomly generated password, and so on. The issue I have is that this playbook needs to be able to act upon multiple inventories, each containing arbitrary group names.

So for example, my inventories can look something this:

inventory\_file\_1  
[INV1\_PRD]  
prdhost1  
prdhost2

[INV\_DEV]  
devhost1  
devhost2

inventory\_file\_2  
[INV2\_PRD]  
prdhost3  
prdhost4

[INV2\_DEV]  
devhost3  
devhost4

In general, the playbook looks something like this:

- name: Generate random password  
set\_fact:  
password: “{{lookup(‘password’, ‘/dev/null’)}}”  
run\_once: true

- name: Set password on host  
user:  
name: “{{account}}”  
password: “{{lookup(‘vars’, account)|password\_hash(‘sha\_512’)}}”

- name: Store password in external vault  
…

This works fine as long as I run the playbook once for each group (i.e. once for INV1\_PRD, again for INV1\_DEV, etc.). All hosts in a single run get the same password. But we would like to run it once for each inventory file and have a different password set for each group within that inventory. I tried to set a group variable for each group and then use ‘group\_by’ with that variable as the key to break the groups out, but then I could not come up with a way of arbitrarily specifying hosts after that:

- group\_by:  
key: my\_group\_var

- hosts: “{{my\_group\_var}}”  
tasks:

- name: Generate random password  
etc.

This returns “The field ‘hosts’ has an invalid value, which includes an undefined variable. The error was: ‘my\_group\_var’ is undefined” The ‘- hosts:’ line seems to be expecting predefined names, with a ‘- hosts:’ line for every possible group. That is not what we want to do here as there could be any number of inventory files, each with its own set of group names.  
So, does anyone have any suggestions?  
Mark

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [June 11, 2020, 9:10pm UTC](https://forum.ansible.com/t/group-by-with-random-key-values/33158/2 "2020-06-11T21:10:03Z")

</div>

It's possible to use "pass" to generate and store the passwords  
[https://www.passwordstore.org/](https://www.passwordstore.org/)  
, and to use "passwordstore" Ansible lookup plugin to retrieve, create or  
update passwords  
[https://docs.ansible.com/ansible/latest/plugins/lookup/passwordstore.html](https://docs.ansible.com/ansible/latest/plugins/lookup/passwordstore.html)

FWIW, here is my task to use the plugin  
[https://github.com/vbotka/ansible-lib/blob/master/tasks/al\_pws\_user\_host.yml](https://github.com/vbotka/ansible-lib/blob/master/tasks/al_pws_user_host.yml)  
, and here is a task how to use it in Linux  
[https://github.com/vbotka/ansible-linux-postinstall/blob/master/tasks/passwords.yml](https://github.com/vbotka/ansible-linux-postinstall/blob/master/tasks/passwords.yml)

---

<div class="post-metadata">

**Author:** ![mark.tovey](https://avatars.discourse-cdn.com/v4/letter/m/ce73a5/32.png) [@mark.tovey](https://forum.ansible.com/u/mark.tovey)\
**Post date:** [June 12, 2020, 3:20pm UTC](https://forum.ansible.com/t/group-by-with-random-key-values/33158/3 "2020-06-12T15:20:45Z")

</div>

Unfortunately, I am under the constraint that I must use the password store that the company has chosen to use (Passwordstate). I have that part working fine. I am able to push passwords into it and pull them back out with no problem. But the general structure of your code will probably be useful in laying out my playbook.  
The problem I have is in grouping servers within the playbook. I need to be able to separate out servers in an inventory file by their environment group and run the play once for each of those groups. This all works fine if I run the playbook multiple times, limiting each run to just one environment group at a time, but we want to run the playbook just once for each inventory file and let it separate out the servers by environment group. The “group\_by” module looks like it should do this, but only if there is a way to dynamically specify what is specified in the following “hosts:” statement.  
Or maybe it is a data structure problem. I tried to set up a structure that looks like this:

> structure:

> > envgroup:
> 
> > > account:
> 
> > > > password: some\_password

Then I can refer to it as:

> {{structure[‘INV1\_PRD’][account].password}}

Unfortunately, every server gets its own private copy of “structure”, not a shared copy. I need some way sharing that between all servers within an environment group.  
ANy suggestions for this method?

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [June 12, 2020, 5:35pm UTC](https://forum.ansible.com/t/group-by-with-random-key-values/33158/4 "2020-06-12T17:35:07Z")

</div>

If the top-down decomposition is too complicated I'd suggest to try bottom-up  
approach. Let the remote hosts periodically check for updates, including  
passwords  
[https://docs.ansible.com/ansible/latest/cli/ansible-pull.html](https://docs.ansible.com/ansible/latest/cli/ansible-pull.html)
