You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从多主机ansible_facts生成非10.开头公网IP列表并用于后续任务

如何从Ansible Facts中筛选非10段内网IP并生成公网IP列表?

我需要生成包含所有目标主机公网IP的列表,要求筛选出ansible_all_ipv4_addresses中不以10.开头的IPv4地址,并用这个列表完成后续的端口检测任务。

当前我用以下Playbook提取所有IP,但无法筛选:

- hosts: facts
  become: true
  gather_facts: True
  tasks:
    - debug:
        msg: "The ip: {{ item }}"
      with_items: "{{ ansible_all_ipv4_addresses }}" 

后续要将筛选后的IP列表用于这个wait_for任务:

- wait_for:
    host: "{{ item[0] }}"
    port: "{{ item[1] }}"
    state: started
    delay: 0
    timeout: 2
  delegate_to: localhost
  become: false
  ignore_errors: no
  ignore_unreachable: yes
  register: result
  failed_when: not result.failed  
  with_nested:
    - [ IP LIST HERE]
    - [443,80,9200,9300,22,5432,6432]

实现步骤

1. 在目标主机上筛选公网IP并存储

用Ansible的select过滤器结合regex_notmatch,过滤掉以10.开头的IP,再用set_fact把每个主机的公网IP列表存到主机变量中:

- hosts: facts
  become: true
  gather_facts: True
  tasks:
    - name: 筛选不以10.开头的公网IP
      set_fact:
        public_ips: "{{ ansible_all_ipv4_addresses | select('regex_notmatch', '^10\\.') | list }}"

2. 收集所有主机的公网IP到全局列表

在localhost上通过hostvars遍历所有目标主机,把每个主机的public_ips合并成一个全局列表:

- hosts: localhost
  become: false
  tasks:
    - name: 收集所有主机的公网IP到全局列表
      set_fact:
        global_public_ips: "{{ groups['facts'] | map('extract', hostvars, 'public_ips') | flatten | unique }}"

3. 在wait_for任务中使用全局列表

直接把global_public_ips填入with_nested的IP列表位置:

- name: 检测公网IP端口状态
  wait_for:
    host: "{{ item[0] }}"
    port: "{{ item[1] }}"
    state: started
    delay: 0
    timeout: 2
  delegate_to: localhost
  become: false
  ignore_errors: no
  ignore_unreachable: yes
  register: result
  failed_when: not result.failed  
  with_nested:
    - "{{ global_public_ips }}"
    - [443,80,9200,9300,22,5432,6432]

完整Playbook示例

把以上步骤整合为一个完整的Playbook:

- name: 收集并筛选主机公网IP
  hosts: facts
  become: true
  gather_facts: True
  tasks:
    - name: 筛选不以10.开头的公网IP
      set_fact:
        public_ips: "{{ ansible_all_ipv4_addresses | select('regex_notmatch', '^10\\.') | list }}"

- name: 收集全局公网IP列表并执行端口检测
  hosts: localhost
  become: false
  tasks:
    - name: 收集所有主机的公网IP到全局列表
      set_fact:
        global_public_ips: "{{ groups['facts'] | map('extract', hostvars, 'public_ips') | flatten | unique }}"

    - name: 检测公网IP端口状态
      wait_for:
        host: "{{ item[0] }}"
        port: "{{ item[1] }}"
        state: started
        delay: 0
        timeout: 2
      ignore_errors: no
      ignore_unreachable: yes
      register: result
      failed_when: not result.failed  
      with_nested:
        - "{{ global_public_ips }}"
        - [443,80,9200,9300,22,5432,6432]

关键说明

  • regex_notmatch: '^10\\.':正则表达式匹配以10.开头的IP,^表示字符串起始,\\.是转义后的点号(因为点号在正则中是通配符)。
  • flatten:把多个主机的IP列表合并成一个一维列表。
  • unique:去重,避免同一IP被多次检测。

内容的提问来源于stack exchange,提问作者Leandro Montesoro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 02:35:22