2014-10-28 193 views
5

我使用ansible更新新添加的NIC 的,我已经在不同的YML文件中定义的一些变量的配置文件Ansible遍历变量

/tmp/ip.yml

#first interface 
interface1: eth1 
bootproto1: static 
ipaddress1: 192.168.211.249 
netmask1: 255.255.255.0 
gateway: 192.168.211.2 
DNS1: 192.168.211.2 

#second interface 
interface2: eth2 
bootproto2: static 
ipaddress2: 10.0.0.100 
netmask2: 255.0.0.0 

剧本

- include_vars: /tmp/ip.yml 

- name: configuring interface 
    lineinfile: 
    state=present 
    create=yes 
    dest=/etc/sysconfig/network-scripts/ifcfg-{{interface1}} 
    regexp="{{ item.regexp }}" 
    line="{{ item.line }}" 
    with_items: 
    - { regexp: '^BOOTPROTO=.*', line: 'BOOTPROTO={{interface1}}' } 
    - { regexp: '^IPADDR=.*', line: 'IPADDR={{ipaddress1}' } 
    - { regexp: '^NETMASK=.*', line: 'NETMASK={{netmask1}}' } 
    - { regexp: '^GATEWAY=.*', line: 'GATEWAY={{gateway}}' } 
    - { regexp: '^PEERDNS=.*', line: 'PEERDNS=no' } 
    - { regexp: '^DNS1=.*', line: 'DNS1={{DNS1}}' } 
    - { regexp: '^ONBOOT=.*', line: 'ONBOOT={{onboot}}' } 
when: bootproto1 == 'static' 

- name: configuring for DHCP 
    lineinfile: 
    state=present 
    create=yes 
    dest=/etc/sysconfig/network-scripts/ifcfg-{{interface1}} 
    regexp="{{ item.regexp }}" 
    line="{{ item.line }}" 
    with_items: 
    - { regexp: '^BOOTPROTO=.*',line: 'BOOTPROTO={{bootproto1}}' } 
    - {regexp: '^PEERDNS=.*',line: 'PEERDNS=yes' } 
    - { regexp: '^ONBOOT=.*', line: 'ONBOOT={{onboot}}' } 
when: bootproto1 == 'dhcp' 

类似地重复用于第二接口。

尽管这种方法适用于2个NIC,但这太难管理了,即每增加一个新NIC,我都需要修改Playbook并更​​新/tmp/ip.yml中的相应变量

有没有办法将变量添加到/tmp/ip.yml,并且可能使用某些分隔符将其解析为playbook,而无需每次修改playbook以插入新的NIC。

回答

20

这里有很多要说的。 首先,尽量避免lineinfile之类的瘟疫。这真的是最后一招的解决方案。 lineinfile很难写出一致的幂等手册。

现在,由于您试图填充RH样式的接口文件,因此很容易做到。

组织您的变量

要做的第一件事就是为你的变量结构合理。你会想要循环你的接口,所以你必须让东西'loopable'。有interface1interface2 ... interfaceN不像您提到的那样可缩放。

这里有一个建议:

interfaces_ipv4: 
    - name: eth0 
    bootproto: static 
    ipaddress: 192.168.211.249 
    netmask: 255.255.255.0 
    gateway: 192.168.211.2 
    dns: 192.168.211.2 
    - name: eth2 
    bootproto: static 
    ipaddress: 10.0.0.100 
    netmask: 255.0.0.0 

写你的模板

现在,你有你的数据,你需要一个模板来创建你的操作系统配置文件。

BOOTPROTO={{item.bootproto}} 
IPADDR={{item.ipaddress}} 
NETMASK={{item.netmask}} 
{% if item.gateway is defined %} 
GATEWAY={{item.gateway}} 
{% endif %} 
PEERDNS=no 
DNS1={{item.dns}} 
ONBOOT={{item.onboot|default('no')}} 

我包括两个变化:你可以跳过输出线,当它没有设置({% if ... %}结构)或提供(例如{{item.onboot|default('no')}})的默认值。

您的里程可能会有所不同,具体取决于您是否要使用默认值或跳过if构造。

创建任务

最后,这里是将创建接口配置文件为每个接口一个任务:

- name: Push template 
    template: 
    src=/path/to/the/above/template.j2 
    dest=/etc/sysconfig/network-scripts/ifcfg-{{item.name}}.cfg 
    with_items: 
    - "{{ interfaces_ipv4 }}" 

这应该做到这一切。

当然,使用此任务的最佳方式是将其添加到某个“网络”角色,并从剧本中调用它。

祝你好运。

+0

感谢@leucos如果我像你提到的http://pastebin.com/ev8gSnH6更改var文件,那么我仍然可以使用现有的方法。 ,因为该变量文件将包含更多的功能。 – 2014-10-29 05:13:47

+0

在你的pastebin中,你覆盖了你的变量:你将'interface'定义为'eth1',然后将它重新定义为'eth2'。这就是为什么变量必须在列表中。见上面的'interfaces_ipv4'(注意:这部分已经被编辑,因为它是错误的)。 – leucos 2014-10-29 08:59:46