Reputation: 1093
I am trying to set up a client and server using Ansible that need to connect to each other (Wireguard client and server in this case). Since the server needs to know the peers that will connect to it, I'm looking to gather a list of hosts that the server will be able to create a peer entry for in its configuration. The list should be dynamically generated (there could be multiple clients connecting to the same server) and generated based on the target_server
variable assigned to each client, the value of which should be equal to the inventory_hostname
of the server it needs to connect to. The jinja2 expression I am using in the MWE below unfortunately keeps coming up empty, but I'm unsure how to improve it.
- name: Set up Wireguard Server
hosts: servers
gather_facts: true
tasks:
- name: Figure out peers for this server
become: false
ansible.builtin.debug:
var: item
loop: "{{ groups['servers'] | select('match', 'target_server={{ inventory_hostname }}') | map('extract', hostvars, 'inventory_hostname') | list }}"
servers:
hosts:
Wireguard-Server:
ansible_host: 2.3.4.5
clients:
hosts:
Wireguard-Client-1:
ansible_host: 1.2.3.4
target_server: Wireguard-Server
Wireguard-Client-2:
ansible_host: 4.3.2.1
target_server: Different-Server
TASK [Figure out peers for this server] ********************************************
skipping: [Wireguard-Server] =>
skipped_reason: No items in the list
Upvotes: 2
Views: 991
Reputation: 68294
Create the dictionary of the clients and target_server
clients: "{{ dict(groups.clients|
zip(groups.clients|
map('extract', hostvars, 'target_server'))) }}"
gives
clients:
Wireguard-Client-1: Wireguard-Server
Wireguard-Client-2: Different-Server
Use it to select the matching clients
my_clients: "{{ clients|dict2items|
selectattr('value', 'eq', inventory_hostname)|
map(attribute='key') }}"
gives
my_clients:
- Wireguard-Client-1
Example of a complete playbook for testing
- hosts: servers
vars:
clients: "{{ dict(groups.clients|
zip(groups.clients|
map('extract', hostvars, 'target_server'))) }}"
my_clients: "{{ clients|dict2items|
selectattr('value', 'eq', inventory_hostname)|
map(attribute='key') }}"
tasks:
- debug:
var: clients
- debug:
var: my_clients
You can select all hosts from the inventory that match target_server
my_clients: "{{ hostvars|dict2items|
selectattr('value.target_server', 'defined')|
selectattr('value.target_server', 'eq', inventory_hostname)|
map(attribute='key') }}"
Upvotes: 3