简体   繁体   English

Ansible循环变量

[英]Ansible loop over variables

i am using ansible to update configuration file of newly added NIC for that i have defined some variables in separate yml file 我正在使用ansible来更新新添加的NIC的配置文件,因为我已经在单独的yml文件中定义了一些变量

/tmp/ip.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

Playbook 剧本

- 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'

similarly repeated for second interface. 类似地重复第二个界面。

Even Though this method works for 2 NIC,this is too difficult to manage ,that is for each new NIC added i need to modify playbook and update corresponding variable in /tmp/ip.yml . 即使这种方法适用于2个NIC,这也很难管理,即每增加一个新的NIC我需要修改playbook并更​​新/tmp/ip.yml中的相应变量。

Is there a way to add variables to /tmp/ip.yml and may be using some separator parse it to playbook with out modifying playbook each time for plugging in new NIC. 有没有办法将变量添加到/tmp/ip.yml,并且可能正在使用某个分隔符将其解析为playbook,而不是每次都插入新的NIC来修改playbook。

There is a lot to say here. 这里有很多话要说。 First, try to avoid lineinfile like plague. 首先,尽量避免像瘟疫这样的lineinfile It is really a last-resort solution. 这真的是最后的解决方案。 lineinfile makes it hard to write consistent and idempotents playbooks. lineinfile使得编写一致的和幂等的剧本变得很困难。

Now, since you're trying to populate RH style interface files, it is quite easy to do. 现在,由于您正在尝试填充RH样式的界面文件,因此很容易实现。

Organize your variables 组织你的变量

The first thing to do is to have a proper structure for your variables. 首先要做的是为变量建立一个合适的结构。 You'll want to loop over your interfaces so you have to make stuff 'loopable'. 你需要遍历你的接口,所以你必须使东西“loopable”。 Having interface1 , interface2 ... interfaceN is not scalable as you mentioned. 如上所述,拥有interface1interface2 ... interfaceN是不可扩展的。

Here is a suggestion : 这是一个建议:

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

Write your template 写下你的模板

Now that you have your data, you need a template to create your OS config file. 现在您已拥有数据,您需要一个模板来创建操作系统配置文件。

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')}}

I included two variations : you can skip outputting a line when it's not set ( {% if ... %} construct) or provide default values (for instance {{item.onboot|default('no')}} ). 我包含了两个变体:您可以在未设置时跳过输出行( {% if ... %}构造)或提供默认值(例如{{item.onboot|default('no')}} )。

Your mileage may vay, depending if you want to use a default or to skip with the if construct. 您的里程可能会有所不同,具体取决于您是否要使用默认值或跳过if结构。

Create a task 创建一个任务

Finally, here is a task that will create interface configuration files for each interface : 最后,这是一个为每个接口创建接口配置文件的任务:

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

This should do it all. 这应该做到这一切。

Of course, best way to use this task is to add it to some "network" role, and call it from a playbook. 当然,使用此任务的最佳方法是将其添加到某个“网络”角色,并从剧本中调用它。

Good luck. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM