问题
I want to copy one version of a file to a server if it has an interface in a specific subnet, or a different version if it does not have an interface in that subnet. Below is a working, but I think less than optimal solution. I'm hoping there is a better way that meets the following criteria...
- stays dynamic (use facts, I don't want to have to manually set variables for every server and manually create groups for servers in and not in the subnet)
- less repetitive (could it be handled in one task?)
- not have to list out every possible interface name (eg. eth0, eth1, ..., bond0, bond1, ... etc)
working version...
- 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:
Some jinja2 ninja tricks and here you are:
- 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
Explanation:
- take a list of available interfaces from
ansible_interfaces
- prepend all interfaces' names with
ansible_
to become (ansible_eth0
, etc) - extract all interfaces' facts from host own
hostvars
- select only those interfaces where
ipv4
is defined - select only those interfaces where
ipv4.network
equals to192.168.0.0
- convert to list
- count
- if there is one or more such interface return
files/myfile.vs1
- return
files/myfile.vs2
otherwise
P.S. >-
is used to define multiline string and strip any newlines, otherwise src
will be set to files/myfile.vs2\n
.
来源:https://stackoverflow.com/questions/40389857/how-to-create-conditional-copy-in-ansible-based-on-network-subnet-membership