目录
前言
简介
with_x的用法
1. with_items
2. with_list
3. with_flattened
4. with_together
5. with_nested
6. with_indexed_items
7. with_dict
8. with_file
9. with_fileglob
10. with_lines
ansible在2.5版本之前,playbook中的循环语法都是使用的with_x,其中with_x包括:with_item,with_list,with_dic等等;在ansible的2.5版本开始到之后,playbook循环语法推荐的是loop,实际上loop和with_x的使用时如初一则的,后面我们就对这两种形式来展开说说。
我们在编写playbook的时候,不可避免的要执行一些重复性操作,比如指安装软件包,批量创建用 户,操作某个目录下的所有文件等。正如我们所说,ansible一门简单的自动化语言,所以流程控 制、循环语句这些编程语言的基本元素它同样都具备。
在Ansible 2.5以前,playbook通过不同的循环语句以实现不同的循环,这些语句使用 with_ 作为前 缀。这些语法目前仍然兼容,但在未来的某个时间点,会逐步废弃。
下面是一些比较常见的with_x循环语句:(加粗的为重点)
· with_items
· with_flattened
· with_list
· with_together
· with_nested
· with_indexed_items
· with_sequence
· with_random_choice
· with_dict
· with_subelement
· with_file
· with_fileglob
· with_lines
简单的列表循环
示例1: 循环打印inventory中all的主机
[root@clinet ansible_2]# cat hosts
[dbserver:children]
mdb
sdb
[mdb]
192.168.194.130 mysql_type=master server_id=1
[sdb]
192.168.194.131 mysql_type=slave server_id=2
[root@clinet ansible_2]#
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg: "{{ item }}"
with_items: "{{ groups['all'] }}"
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item=192.168.194.130) => {
"msg": "192.168.194.130"
}
ok: [192.168.194.130] => (item=192.168.194.131) => {
"msg": "192.168.194.131"
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
示例2: 直接在with_items中定义循环的列表
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg:
- "{{ item }}"
with_items:
- 'xhz'
- 'flf'
- 'wsz'
- 'xjl'
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item=xhz) => {
"msg": [
"xhz"
]
}
ok: [192.168.194.130] => (item=flf) => {
"msg": [
"flf"
]
}
ok: [192.168.194.130] => (item=wsz) => {
"msg": [
"wsz"
]
}
ok: [192.168.194.130] => (item=xjl) => {
"msg": [
"xjl"
]
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
[root@clinet ansible_2]#
也可以写成:
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg:
- "{{ item }}"
with_items: ['xhz', 'flf', 'wsz', 'xjl']
[root@clinet ansible_2]#
示例3: 在with_items中定义复杂的列表。
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg:
- "{{ item.path1 }}/{{ item.path2 }}"
with_items:
- {'path1': 'one', 'path2': 'two'}
- {'path1': 'three', 'path2': 'four'}
[root@clinet ansible_2]#
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item={u'path2': u'two', u'path1': u'one'}) => {
"msg": [
"one/two"
]
}
ok: [192.168.194.130] => (item={u'path2': u'four', u'path1': u'three'}) => {
"msg": [
"three/four"
]
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
与 with_items 一样,也是用于循环列表。区别是,如果列表的值也是列表, with_items 会将第一层 嵌套的列表拉平,而 with_list 会将值作为一个整体返回。
示例1: 使用with_items循环列表[[1,2], [a,b]]
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg:
- "{{ item }}"
with_items:
- [1,2]
- [a,b]
[root@clinet ansible_2]#
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item=1) => {
"msg": [
1
]
}
ok: [192.168.194.130] => (item=2) => {
"msg": [
2
]
}
ok: [192.168.194.130] => (item=a) => {
"msg": [
"a"
]
}
ok: [192.168.194.130] => (item=b) => {
"msg": [
"b"
]
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
示例1: 使用with_list循环列表[[1,2], [a,b]]
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg:
- "{{ item }}"
with_list:
- [1,2]
- [a,b]
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item=[1, 2]) => {
"msg": [
[
1,
2
]
]
}
ok: [192.168.194.130] => (item=[u'a', u'b']) => {
"msg": [
[
"a",
"b"
]
]
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
注意:
with_list:
- [1,2]
- [a,b]等价于====>
with_list: [[1,2], [a,b]]
with_flattened 与 with_items 类似,当处理复杂的多级列表嵌套时,会将所有的列表全部拉平。
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg:
- "{{ item }}"
with_flattened:
- [1,2,[3,4,[x,y]]]
- [a,b]
[root@clinet ansible_2]#
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item=1) => {
"msg": [
1
]
}
ok: [192.168.194.130] => (item=2) => {
"msg": [
2
]
}
ok: [192.168.194.130] => (item=3) => {
"msg": [
3
]
}
ok: [192.168.194.130] => (item=4) => {
"msg": [
4
]
}
ok: [192.168.194.130] => (item=x) => {
"msg": [
"x"
]
}
ok: [192.168.194.130] => (item=y) => {
"msg": [
"y"
]
}
ok: [192.168.194.130] => (item=a) => {
"msg": [
"a"
]
}
ok: [192.168.194.130] => (item=b) => {
"msg": [
"b"
]
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
with_together 可以将两个列表中的元素对齐合并。
示例1: 使用with_together循环两个相同长度列表 。
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
vars:
alpha: ['a', 'b']
numbers: [1,2]
tasks:
- name: debug groups all
debug:
msg:
- "{{ item[0] }}"
- "{{ item[1] }}"
with_together:
- "{{ alpha}}"
- "{{ numbers }}"
[root@clinet ansible_2]#
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item=[u'a', 1]) => {
"msg": "a and 1"
}
ok: [192.168.194.130] => (item=[u'b', 2]) => {
"msg": "b and 2"
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
示例2: 使用with_together循环两个不同长度列表
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
vars:
alpha: ['a', 'b', 'c']
numbers: [1,2]
tasks:
- name: debug groups all
debug:
msg: "{{ item[0] }} and {{ item[1] }}"
with_together:
- "{{ alpha}}"
- "{{ numbers }}"
[root@clinet ansible_2]#
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item=[u'a', 1]) => {
"msg": "a and 1"
}
ok: [192.168.194.130] => (item=[u'b', 2]) => {
"msg": "b and 2"
}
ok: [192.168.194.130] => (item=[u'c', None]) => {
"msg": "c and "
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
嵌套循环。
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg: "{{ item[0] }} and {{ item[1] }}"
with_nested:
- ['alice','bob']
- [1, 2, 3]
[root@clinet ansible_2]#
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item=[u'alice', 1]) => {
"msg": "alice and 1"
}
ok: [192.168.194.130] => (item=[u'alice', 2]) => {
"msg": "alice and 2"
}
ok: [192.168.194.130] => (item=[u'alice', 3]) => {
"msg": "alice and 3"
}
ok: [192.168.194.130] => (item=[u'bob', 1]) => {
"msg": "bob and 1"
}
ok: [192.168.194.130] => (item=[u'bob', 2]) => {
"msg": "bob and 2"
}
ok: [192.168.194.130] => (item=[u'bob', 3]) => {
"msg": "bob and 3"
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
在循环处理列表时,为列表中的每一项添加索引(从0开始的数字索引)
示例1: with_indexed_items循环简单列表
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg: "{{ item[0] }} and {{ item[1] }}"
with_indexed_items:
- test1
- test2
- test3
[root@clinet ansible_2]#
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item=[0, u'test1']) => {
"msg": "0 and test1"
}
ok: [192.168.194.130] => (item=[1, u'test2']) => {
"msg": "1 and test2"
}
ok: [192.168.194.130] => (item=[2, u'test3']) => {
"msg": "2 and test3"
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
示例2: with_indexed_items循环复杂列表。
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg: "{{ item[0] }} and {{ item[1] }}"
with_indexed_items:
- test1
- ['test2', 'test3']
- test4
[root@clinet ansible_2]#
[root@clinet ansible_2]#
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item=[0, u'test1']) => {
"msg": "0 and test1"
}
ok: [192.168.194.130] => (item=[1, u'test2']) => {
"msg": "1 and test2"
}
ok: [192.168.194.130] => (item=[2, u'test3']) => {
"msg": "2 and test3"
}
ok: [192.168.194.130] => (item=[3, u'test4']) => {
"msg": "3 and test4"
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
可以看到,其在处理更复杂列表的时候,会将列表拉平,类似于 with_items 。 与 with_items 一样,其也只会拉平第一层列表,如果存在多层列表嵌套,则更深的嵌套不会被拉 平。
循环字典。
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
vars:
users:
xhz:
name: xiaohaizhou
iphone: 185xxx
flf:
name: fulifang
iphone: 132xxx
tasks:
- name: debug groups all
debug:
msg: "user {{ item['key'] }} name is {{ item['value']['name'] }} iphone is {{ item['value']['iphone'] }}"
with_dict: "{{ users }}"
[root@clinet ansible_2]#
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item={u'key': u'xhz', u'value': {u'name': u'xiaohaizhou', u'iphone': u'185xxx'}}) => {
"msg": "user xhz name is xiaohaizhou iphone is 185xxx"
}
ok: [192.168.194.130] => (item={u'key': u'flf', u'value': {u'name': u'fulifang', u'iphone': u'132xxx'}}) => {
"msg": "user flf name is fulifang iphone is 132xxx"
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
用于循环主控端的文件列表,获取文件中的内容。(注意: 循环的是主控端的文件列表,不是被控端的)
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg: "{{ item }}"
with_file:
- /etc/passwd
- /etc/shadow
- /root/ansible_test/ansible_2/hosts
上面 with_file 用于获取文件的内容,而 with_fileglob 则用于匹配文件名称。可以通过该关键字, 在指定的目录中匹配符合模式的文件名。与 with_file 相同的是, with_fileglob 操作的文件也是主 控端的文件而非被控端的文件。
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg: "{{ item }}"
with_fileglob:
- /root/ansible_test/ansible_2/yum_file/*.yml
[root@clinet ansible_2]#
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item=/root/ansible_test/ansible_2/yum_file/creat_user.yml) => {
"msg": "/root/ansible_test/ansible_2/yum_file/creat_user.yml"
}
ok: [192.168.194.130] => (item=/root/ansible_test/ansible_2/yum_file/123.yml) => {
"msg": "/root/ansible_test/ansible_2/yum_file/123.yml"
}
ok: [192.168.194.130] => (item=/root/ansible_test/ansible_2/yum_file/234.yml) => {
"msg": "/root/ansible_test/ansible_2/yum_file/234.yml"
}
ok: [192.168.194.130] => (item=/root/ansible_test/ansible_2/yum_file/nging_web.yml) => {
"msg": "/root/ansible_test/ansible_2/yum_file/nging_web.yml"
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
with_lines循环结构会让你在控制主机上执行任意命令,并对命令的输出进行逐行迭代。
[root@clinet ansible_2]# cat yum_file/with_x/with_x.yml
- hosts: mdb
gather_facts: no
tasks:
- name: debug groups all
debug:
msg: "{{ item }}"
with_lines:
- cat /root/ansible_test/ansible_2/hosts
[root@clinet ansible_2]#
[root@clinet ansible_2]#
[root@clinet ansible_2]# ansible-playbook yum_file/with_x/with_x.yml
PLAY [mdb] **********************************************************************************************************************************************************
TASK [debug groups all] *********************************************************************************************************************************************
ok: [192.168.194.130] => (item=[dbserver:children]) => {
"msg": "[dbserver:children]"
}
ok: [192.168.194.130] => (item=mdb) => {
"msg": "mdb"
}
ok: [192.168.194.130] => (item=sdb) => {
"msg": "sdb"
}
ok: [192.168.194.130] => (item=) => {
"msg": ""
}
ok: [192.168.194.130] => (item=[mdb]) => {
"msg": "[mdb]"
}
ok: [192.168.194.130] => (item=192.168.194.130 mysql_type=master server_id=1) => {
"msg": "192.168.194.130 mysql_type=master server_id=1"
}
ok: [192.168.194.130] => (item=) => {
"msg": ""
}
ok: [192.168.194.130] => (item=[sdb]) => {
"msg": "[sdb]"
}
ok: [192.168.194.130] => (item=192.168.194.131 mysql_type=slave server_id=2) => {
"msg": "192.168.194.131 mysql_type=slave server_id=2"
}
PLAY RECAP **********************************************************************************************************************************************************
192.168.194.130 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#