group_by with random key values

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

It's possible to use "pass" to generate and store the passwords
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

FWIW, here is my task to use the plugin
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

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?

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