我必须在相对较短的时间内对网络进行多次更改,以便节省时间,因此我决定使用Ansible。
我在多个环境中都有多种类型的服务器,因此需要遍历每种环境和每种类型的服务器并设置新的IP,子网等。
例如在ENV1中,我可能拥有Web和DB,例如在192.168.64上具有ENV1,而Web为.10,DB为.20。
因此,使用Ansible并定义两个列表并在嵌套循环中使用它们,我希望能够根据服务器的环境和类型来做到这一点。
我可以使用命令行变量并为每个变量设置环境子网,但是如果可以避免的话,我想这样做。
剧本。
---
- hosts: web:db
become: yes
vars_files:
- vars/network-vars.yaml
tasks:
- name: Update the ifcfg-eth0 file
template:
src: templates/ifcfg-template.yaml
dest: /etc/sysconfig/network-scripts/ifcfg-eth0.new
owner: root
group: root
mode: 0644
when: item.type in group_names and item.env in group_names
with_items:
- "{{ ips }}"
- "{{ subnets }}"
各种文件:
---
- netmask: 255.255.255.0
- network: 192.168.64
- dns1: 192.168.64.254
- search: lab.int
- subnets:
- { env: "env1", net: "192.168.64.2" }
- ips:
- { type: "web", ip: "10" }
- { type: "db", ip: "20" }
失败! => {“ msg”:“ group_names中的条件检查'item.type和group_names中的'{{env}}''失败。错误是:评估条件时出错(group_names中的item.type和'{{env} }”(在组名中):“ env”未定义
我尝试了with_nested,但是遇到了类似的错误。我几乎已经筋疲力尽地阅读手册页并寻找解决方案,因此我为什么在这里。
TIA。
答案 0 :(得分:0)
您可以为此使用product过滤器。
可以在Loops页面上的官方文档中找到有关ansible循环构造的更多文档。
#!/usr/bin/env ansible-playbook
- name: Lets do some loops
hosts: localhost
gather_facts: false
become: false
vars:
arr_one:
- env: dev
- env: prod
arr_two:
- type: web
- type: db
tasks:
- name: Only print when env=dev and type=db
debug:
msg: "{{ item.0.env }} {{ item.1.type }}"
when: (item.0.env == 'dev') and
(item.1.type == 'db')
loop: "{{ arr_one
| product(arr_two)
| list }}"
PLAY [Lets do some loops] ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************
TASK [Only print when for env=dev and type=db] *****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
skipping: [localhost] => (item=[{'env': 'dev'}, {'type': 'web'}])
ok: [localhost] => (item=[{'env': 'dev'}, {'type': 'db'}]) => {
"msg": "dev db"
}
skipping: [localhost] => (item=[{'env': 'prod'}, {'type': 'web'}])
skipping: [localhost] => (item=[{'env': 'prod'}, {'type': 'db'}])
PLAY RECAP ******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0
答案 1 :(得分:0)
关于错误:
'item.type in group_names and '{{env}}' in group_names
由于中间{{env}}
的嵌套,您会看到它。
when
语句的内容隐含在jinja {{...}}
上下文中,并且{{...}}
个标记。 您可以将这些表达式写为:
when: item.type in group_names and env in group_names
但这可能不是解决问题的好方法。
答案 2 :(得分:0)
我想分享一下如何在不循环的情况下运行它,并且不确定为什么我一开始就没有想到这一点。我在每个系统上设置一个事实,首先声明网络。简单的解决方案有时最容易遗漏。
- name: set the network
set_fact: net="{{ item.net }}"
when: item.env in group_names
with_items:
- "{{ subnets }}"