Ansible循环变量

Kev*_*ker 8 ansible ansible-playbook

我正在使用ansible来更新新添加的NIC的配置文件,因为我已经在单独的yml文件中定义了一些变量

/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
Run Code Online (Sandbox Code Playgroud)

剧本

- 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'
Run Code Online (Sandbox Code Playgroud)

类似地重复第二个界面.

即使这种方法适用于2个NIC,这也很难管理,即每增加一个新的NIC我需要修改playbook并更​​新/tmp/ip.yml中的相应变量.

有没有办法将变量添加到/tmp/ip.yml,并且可能正在使用某个分隔符将其解析为playbook,而不是每次都插入新的NIC来修改playbook.

leu*_*cos 27

这里有很多话要说.首先,尽量避免lineinfile瘟疫.这真的是最后的解决方案.lineinfile难以编写一致的和幂等的剧本.

现在,由于您正在尝试填充RH样式的界面文件,因此很容易实现.

组织你的变量

首先要做的是为变量建立一个合适的结构.你需要遍历你的接口,所以你必须使东西"loopable".有interface1,interface2... 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
Run Code Online (Sandbox Code Playgroud)

写下你的模板

现在您已拥有数据,您需要一个模板来创建操作系统配置文件.

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')}}
Run Code Online (Sandbox Code Playgroud)

我包括两个变体:您可以在未设置({% 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 }}"
Run Code Online (Sandbox Code Playgroud)

这应该做到这一切.

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

祝好运.