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

时间:2016-11-02 21:10:57

标签: ansible ansible-playbook ansible-2.x

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

  • 保持动态(使用事实,我不想为每个服务器手动设置变量,并为子网中的服务器手动创建组,而不是在子网中)
  • 重复性较低(可以在一个任务中处理吗?)
  • 不必列出所有可能的接口名称(例如eth0,eth1,...,bond0,bond1,......等)

工作版......

- 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")
        ...

1 个答案:

答案 0 :(得分:4)

一些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
  • 中提取所有接口的事实
  • 仅选择定义了ipv4的接口
  • 仅选择ipv4.network等于192.168.0.0
  • 的接口
  • 转换为列表
  • 计数
  • 如果有一个或多个此类界面返回files/myfile.vs1
  • 否则返回files/myfile.vs2

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