如何基于网络(子网)成员资格在 Ansible 中创建条件副本

How to create conditional copy in Ansible based on network (subnet) membership

我想将文件的一个版本复制到服务器(如果它在特定子网中有接口),或者如果它在该子网中没有接口则复制不同的版本。下面是一个可行的,但我认为不是最佳解决方案。我希望有更好的方法满足以下条件...

工作版本...

- name: copy file version 1 to server
  copy:
    src: files/myfile.vs1
    dest: /etc/myfile
  when: (ansible_eth0.network == "192.168.0.0") or
        (ansible_eth1.network == "192.168.0.0") or
        (ansible_eth2.network == "192.168.0.0")
        ...

- name: copy file version 2 to server
  copy:
    src: files/myfile.vs2
    dest: /etc/myfile
  when: (ansible_eth0.network != "192.168.0.0") and
        (ansible_eth1.network != "192.168.0.0") and
        (ansible_eth2.network != "192.168.0.0")
        ...

一些 jinja2 忍者技巧,给你:

- copy:
    src: >-
         {{ (
              ansible_interfaces |
              map('regex_replace','^','ansible_') |
              map('extract',hostvars[inventory_hostname]) |
              selectattr('ipv4','defined') |
              selectattr('ipv4.network','equalto','192.168.0.0') |
              list |
              count > 0
            ) | ternary('files/myfile.vs1','files/myfile.vs2')
         }}
    dest: /etc/myfile

解释:

  • ansible_interfaces
  • 获取可用接口列表
  • 在所有接口的名称前添加 ansible_ 以变为(ansible_eth0,等等)
  • 从主机自身提取所有接口的事实hostvars
  • select 仅那些定义了 ipv4 的接口
  • select 仅那些 ipv4.network 等于 192.168.0.0
  • 的接口
  • 转换为列表
  • 计数
  • 如果有一个或多个这样的接口return files/myfile.vs1
  • return files/myfile.vs2 否则

P.S。 >- 用于定义多行字符串并去除任何换行符,否则 src 将设置为 files/myfile.vs2\n.