如何在Ansible中从动态变量提取开放端口并赋值
解决Ansible从loop结果中提取开放端口并设置默认值的问题
刚好我之前处理过类似的Ansible端口检测场景,给你整理个清晰的解决方案:
核心思路
你的temp_port_check变量里存储了loop任务的所有结果,每个结果条目包含failed(是否检测失败,即端口关闭)和_ansible_item_label(原始的端口号)两个关键字段。我们需要用Jinja2过滤器筛选出failed: false的条目,提取对应的端口号,再处理默认值的情况。
完整Playbook示例
- name: check open port wait_for: host: '0.0.0.0' port: '{{ item }}' delay: 0 state: started timeout: 1 ignore_errors: true loop: - 22222 - 33333 - 44444 register: temp_port_check - name: Extract open port or set default set_fact: # 提取第一个开放的端口,若无则用默认11111 open_port: "{{ temp_port_check.results | selectattr('failed', 'equalto', false) | map(attribute='_ansible_item_label') | first | default('11111', true) }}" - name: Verify the result debug: var: open_port
代码解释
逐个拆解set_fact里的过滤器:
temp_port_check.results:获取loop任务返回的所有结果列表selectattr('failed', 'equalto', false):筛选出端口检测成功(即端口开放)的条目map(attribute='_ansible_item_label'):从筛选后的条目中提取原始的端口号first:取第一个开放的端口(如果有多个开放端口,会优先选列表里的第一个)default('11111', true):当筛选后的端口列表为空(所有端口都关闭)时,启用默认值11111;true参数确保空列表也会触发默认值(如果不加true,只有变量未定义时才会生效)
扩展:收集所有开放端口
如果你需要收集所有开放的端口,而不是只取第一个,可以把first换成list,并调整默认值为列表形式:
- name: Extract all open ports or set default set_fact: open_ports: "{{ temp_port_check.results | selectattr('failed', 'equalto', false) | map(attribute='_ansible_item_label') | list | default(['11111'], true) }}"
这样就能完美实现你要的需求啦~
内容的提问来源于stack exchange,提问作者Aleksey
相关产品推荐
相关产品推荐

