如何在Ansible中合并多主机指纹结果为单个变量?
解决Ansible多主机指纹收集与合并问题
问题分析
当前任务仅在单台主机上收集指纹,且直接对字符串类型的stdout使用join(',')无法实现多主机指纹的汇总。要完成需求,需先收集每台主机的指纹数据,再通过hostvars获取所有主机的结果并合并。
解决方案
1. 修正单台主机的指纹收集
利用stdout_lines自动将命令输出按行拆分为列表,确保单台主机的指纹数据以列表形式存储:
- name: Collect fingerprint from each host become: yes command: cut -d" " -f2 {{ dataDir }}/{{ name }}_{{ port }}/fingerprint register: fingerprint
此时每台主机的fingerprint.stdout_lines就是该主机的指纹列表(示例中为['AAAAAAAAAAAAA', 'BBBBBBBBBBBBB', 'CCCCCCCCCCCC'])。
2. 汇总所有主机指纹并生成合并字符串
添加任务遍历所有目标主机,收集所有指纹并合并为逗号分隔的字符串:
- name: Combine all fingerprints into a single string set_fact: all_fingerprints: "{{ ansible_play_hosts | map('extract', hostvars, 'fingerprint') | map(attribute='stdout_lines') | flatten | join(',') }}" run_once: true # 仅在一台主机执行汇总,避免重复计算
ansible_play_hosts:当前Play的所有目标主机列表map('extract', hostvars, 'fingerprint'):从每台主机的hostvars中提取fingerprint注册变量map(attribute='stdout_lines'):获取每台主机的指纹行列表flatten:将多台主机的指纹列表扁平化为一个大列表join(','):将扁平列表用逗号连接为目标格式字符串
3. 验证及后续使用
添加调试任务查看结果,后续任务可直接使用all_fingerprints变量:
- name: Debug combined fingerprints debug: msg: "All fingerprints: {{ all_fingerprints }}" # 后续任务示例 - name: Use combined fingerprints debug: msg: "Applying fingerprints: {{ all_fingerprints }}"
执行后将得到期望格式:AAAAAAAAAAAAA,BBBBBBBBBBBBB,CCCCCCCCCCCC(多台主机场景会包含所有主机的指纹)。
完整Playbook示例
- name: Collect and combine fingerprints hosts: all vars: dataDir: "/path/to/data" name: "service" port: "1234" tasks: - name: Collect fingerprint from each host become: yes command: cut -d" " -f2 {{ dataDir }}/{{ name }}_{{ port }}/fingerprint register: fingerprint - name: Combine all fingerprints into a single string set_fact: all_fingerprints: "{{ ansible_play_hosts | map('extract', hostvars, 'fingerprint') | map(attribute='stdout_lines') | flatten | join(',') }}" run_once: true - name: Debug combined fingerprints debug: msg: "All fingerprints: {{ all_fingerprints }}" - name: Use combined fingerprints in task debug: msg: "Using merged fingerprints: {{ all_fingerprints }}"
内容的提问来源于stack exchange,提问作者MrCoinSiX
相关产品推荐
相关产品推荐

