基于主机变量从Ansible清单筛选主机:Wireguard Peer列表生成失败
问题:Ansible动态生成WireGuard服务器对应的客户端Peer列表失败
我正尝试用Ansible搭建需要互联的WireGuard客户端与服务器。服务器需要知晓要连接的Peer,因此需要动态生成对应服务器的客户端主机列表——该列表需基于每个客户端的target_server变量值匹配服务器的inventory_hostname。但下方最小复现示例中的Jinja2表达式始终返回空列表,导致任务跳过,不知如何改进。
复现代码
Playbook
- 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 }}"
Inventory
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
解决方案
你的表达式存在两个核心问题:
- 错误地从
servers组中筛选,而客户端主机都在clients组里 - 使用
select('match', ...)是用正则匹配主机名,而非匹配客户端的target_server变量值
修正后的任务代码如下:
- name: Figure out peers for this server become: false ansible.builtin.debug: var: item.inventory_hostname loop: "{{ groups['clients'] | map('extract', hostvars) | selectattr('target_server', 'equalto', inventory_hostname) | list }}"
代码解释
groups['clients']:获取所有客户端主机的名称列表map('extract', hostvars):将每个客户端名称转换为对应的主机变量对象selectattr('target_server', 'equalto', inventory_hostname):筛选出target_server变量值等于当前服务器inventory_hostname的客户端- 最终得到的列表就是当前服务器需要关联的所有WireGuard客户端
运行修正后的任务,Wireguard-Server会输出Wireguard-Client-1,符合预期。
内容的提问来源于stack exchange,提问作者Geert Smelt
相关产品推荐
相关产品推荐

