Ansible in-memory inventory from openstack.cloud.server_info

I need to create a in-memory inventory to run playbook over overcloud instance, all instance are not directly exposed, only one server is exposed and can be used as "gateway" aka "JumpHost" aka "ProxyHost".

I have been accomplish this task whit the following tasks:

Get infos on the server I'm interested

...
  - name: detect gateway for the {{ project }} tenant
    openstack.cloud.server_info:
      cloud: "{{ project }}"
      server: "*gw*"
    register: gw_info
...

Then I extract the information of the FloatingIP associated to this instance:

...
- name: Register info of gateway for {{ project }} tenant
  set_fact:
    gw_ip: "{{ item.interface_ip }}"
  loop: "{{ gw_info.openstack_servers }}"
...

Once I get the infos I need I collect infos to all instances in the tenant

...
- name: fetch instances on {{ project }} tenant
  openstack.cloud.server_info:
    cloud: "{{ project }}"
  register: servers_info
...

And finally create the in memory inventory with the necessary group from the instances metadata to run others play

...
- name: create in memory inventory
  add_host:
    hostname: "{{ item.name }}"
    ansible_ssh_host: "{{ item.private_v4 }}"
    ansible_user: "{{ ansible_user }}"
    ansible_ssh_common_args: '-o ProxyCommand="ssh -i {{ ssh_priv_ key }} -W %h:%p -q ansible@{{ gw_ip }}"'
    group:
      - "{{ item.metadata.tool }}"
      - "{{ item.metadata.environment }}"
  loop: "{{ servers_info.openstack_servers }}"
...

It's working play but are there a way to do this in a better way, maybe more "elegant"?

I have also a doubt on ansible module openstack.cloud.server_info, in the documentation have the parameter filter, I try to filter on metadata of the instance but it does not work.

I would prefer to use metadata instead server name for filter my gateway because like this if another instance get a name with the "gw" letter will be selected and my playbook may fails because the gw_ip facts may contain the wrong information.


Consider reducing the number of tasks needed to run to generate this host list, with inventory plugins and DNS. Also makes standard inventory features possible, like caching for improved performance.

Create and use an openstack.cloud.openstack inventory config and let it enumerate the hosts. Probably want to set private: yes. Use keyed_groups to add groups named after the values of metadata, as this inventory implements Constructable

Define in vars what the jump host's name is. Possibly in group_vars so they only apply to this tenant/project/whatever.

# DNS FQDN of jump host
jumphost: jumphost.{{ project }}.example.net
# ProxyCommand or ProxyJump can be defined as ansible vars
ansible_ssh_common_args: '-o ProxyCommand="ssh -i {{ ssh_priv_key }} -W %h:%p -q ansible@{{ jumphost }}"'

Run a play on localhost to fill in what the jump host is. Use openstack.cloud.server_info if that makes sense. Update AAAA and A DNS records of {{ jumphost }} with a task. As long as this IP doesn't change, no tasks need to run to find it again.