Ansible如何过滤列表中的AnsibleUndefined值以提取Docker Swarm worker节点join-token
问题根因
使用map('extract', hostvars, ...)批量遍历所有play主机提取字段时,对未执行过community.general.docker_swarm模块、不存在result.swarm_facts.JoinTokens.Worker字段路径的节点,extract操作不会抛出任务失败,而是返回AnsibleUndefined占位值,最终这些无效值会混入生成的列表。
实现方案
直接在变量表达式末尾链式追加过滤器完成过滤、去重、取值,不需要额外写判断任务,修改后的配置如下:
- name: Get join-token for worker nodes set_fact: join_token_worker: >- {{ ansible_play_hosts_all | map('extract', hostvars, ['result', 'swarm_facts', 'JoinTokens', 'Worker']) | select('defined') | unique | first }} run_once: true - debug: msg: "{{ join_token_worker }}" run_once: true
各过滤器作用
select('defined'):筛选所有通过defined测试的有效项,所有AnsibleUndefined占位值都会被完全剔除unique:同一Docker Swarm集群下所有管理节点存储的Worker Join Token是完全相同的,过滤完无效值后会出现大量重复项,该过滤器会合并重复值,仅保留唯一的Token字符串first:取去重后列表的第一个元素,直接拿到纯字符串格式的有效Token,不需要后续遍历列表取值
补充:如果需要进一步校验Token格式,可在
select('defined')后追加select('match', '^SWMTKN-')过滤器,仅保留符合Swarm Token格式的字符串,避免其他已定义的非Token值混入结果。
实际运行效果
对应你之前的输出场景,原列表中的6个AnsibleUndefined值会被全部过滤,2个重复的同值Token经过unique处理后合并为单值,最终debug输出为纯字符串格式的有效Token,无任何无效占位内容。
内容的提问来源于stack exchange,提问作者SantaXL
相关产品推荐
相关产品推荐

