本来打算自己写一波 ansible 系列的,后来发现一老哥写的太好了,「点击此处直达」,我这里也就边看边对该系列文章做下笔记,方便以后查阅,ansible 入门的话墙裂建议阅读前方链接博文~~~
with_items
with_items
用来进行遍历操作,当要遍历的对象是嵌套结构时,仅会遍历前两层的子元素。
例 1:循环输出 groupall
组中的所有主机别名。
---
- hosts: B
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_items: {{groups.grouall}}
结果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=B) => {
"msg": "B"
}
ok: [B] => (item=C) => {
"msg": "C"
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
例 2:循环列表。
---
- hosts: B
gather_facts: no
tasks:
- debug:
msg: "{{item}}"
with_items:
- 1
- 2
- 3
# 这里的列表也可写成: with_items: [ 1, 2, 3 ]
结果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=1) => {
"msg": 1
}
ok: [B] => (item=2) => {
"msg": 2
}
ok: [B] => (item=3) => {
"msg": 3
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
例 3:循环对象。
---
- hosts: B
gather_facts: no
tasks:
- debug:
msg: "{{item.test1}}"
with_items:
- { test1: a, test2: b }
- { test1: c, test2: d }
结果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item={u'test1': u'a', u'test2': u'b'}) => {
"msg": "a"
}
ok: [B] => (item={u'test1': u'c', u'test2': u'd'}) => {
"msg": "c"
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
例 4:在客户机创建 /opt/{a,b,c,d}
文件夹。
---
- hosts: B
gather_facts: no
vars:
dirs:
- "/opt/a"
- "/opt/b"
- "/opt/c"
- "/opt/d"
tasks:
- file:
path: "{{item}}"
state: directory
with_items: "{{dirs}}"
例 5:循环嵌套列表。
---
- hosts: B
gather_facts: no
tasks:
- debug:
var: item
with_items:
- [ a, b, [ c, d ] ]
- [ 1, 2 ]
结果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=a) => {
"ansible_loop_var": "item",
"item": "a"
}
ok: [B] => (item=b) => {
"ansible_loop_var": "item",
"item": "b"
}
ok: [B] => (item=[u'c', u'd']) => {
"ansible_loop_var": "item",
"item": [
"c",
"d"
]
}
ok: [B] => (item=1) => {
"ansible_loop_var": "item",
"item": 1
}
ok: [B] => (item=2) => {
"ansible_loop_var": "item",
"item": 2
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_flattened
with_flattened
与 with_item
不同的是,不管嵌套结构有多少层,它都会直接遍历所有子元素。
看如下示例:
---
- hosts: B
gather_facts: no
tasks:
- debug:
var: item
with_flattened:
- [ a, b, [ c, d ] ]
- [ 1, 2 ]
结果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=a) => {
"ansible_loop_var": "item",
"item": "a"
}
ok: [B] => (item=b) => {
"ansible_loop_var": "item",
"item": "b"
}
ok: [B] => (item=c) => {
"ansible_loop_var": "item",
"item": "c"
}
ok: [B] => (item=d) => {
"ansible_loop_var": "item",
"item": "d"
}
ok: [B] => (item=1) => {
"ansible_loop_var": "item",
"item": 1
}
ok: [B] => (item=2) => {
"ansible_loop_var": "item",
"item": 2
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_list
with_list
遍历嵌套列表时仅会输出第一层元素,遍历单层结构的对象时效果与 with_item
相同。
例:循环嵌套列表。
---
- hosts: B
gather_facts: no
tasks:
- debug:
var: item
with_list:
- ['a','b']
- [1,2]
结果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=[u'a', u'b']) => {
"ansible_loop_var": "item",
"item": [
"a",
"b"
]
}
ok: [B] => (item=[1, 2]) => {
"ansible_loop_var": "item",
"item": [
1,
2
]
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_together
with_together
可用来对齐合并多个列表的元素,当列表长度不一致时,空缺位用 null
补充。
看如下示例:
---
- hosts: B
gather_facts: no
tasks:
- debug:
var: item
with_together:
- [ 1, 2, 3, 4]
- [ a, b, c ]
结果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=[1, u'a']) => {
"ansible_loop_var": "item",
"item": [
1,
"a"
]
}
ok: [B] => (item=[2, u'b']) => {
"ansible_loop_var": "item",
"item": [
2,
"b"
]
}
ok: [B] => (item=[3, u'c']) => {
"ansible_loop_var": "item",
"item": [
3,
"c"
]
}
ok: [B] => (item=[4, None]) => {
"ansible_loop_var": "item",
"item": [
4,
null
]
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_cartesian
with_cartesian
可以将多个列表做笛卡尔积形式的组合,with_nested
的效果与它相同。
例:在客户机 /opt
目录下创建此结构的目录:mkdir {a,b,c}/{1,2,3} -p
。
---
- hosts: B
gather_facts: no
tasks:
- file:
path: "/opt/{{item.0}}/{{item.1}}"
state: directory
with_cartesian:
- [ a, b, c ]
- [ 1, 2, 3 ]
效果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [file] ***************************************************************************************************************************
changed: [B] => (item=[u'a', 1])
changed: [B] => (item=[u'a', 2])
changed: [B] => (item=[u'a', 3])
changed: [B] => (item=[u'b', 1])
changed: [B] => (item=[u'b', 2])
changed: [B] => (item=[u'b', 3])
changed: [B] => (item=[u'c', 1])
changed: [B] => (item=[u'c', 2])
changed: [B] => (item=[u'c', 3])
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_indexed_items
with_indexed_items
的作用就是在循环处理列表时为列表中的每一项添加数字索引,当要遍历的对象为嵌套结构时,同 with_item
相同仅会遍历到第二层的每一个子元素。
看如下示例:
---
- hosts: B
gather_facts: no
tasks:
- debug:
var: item
with_indexed_items:
- [ a, b ]
- [ 1, 2 ]
效果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=[0, u'a']) => {
"ansible_loop_var": "item",
"item": [
0,
"a"
]
}
ok: [B] => (item=[1, u'b']) => {
"ansible_loop_var": "item",
"item": [
1,
"b"
]
}
ok: [B] => (item=[2, 1]) => {
"ansible_loop_var": "item",
"item": [
2,
1
]
}
ok: [B] => (item=[3, 2]) => {
"ansible_loop_var": "item",
"item": [
3,
2
]
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_sequence
with_sequence
可以用来创建一个遍历的数据源,类似于 Python 中的 range
函数。
例 1:在客户机的 /opt
目录下这些文件:touch test{2,4,6,8,10}
。
---
- hosts: B
gather_facts: no
tasks:
- file:
path: /opt/test{{item}}
state: touch
with_sequence: start=2 end=10 stride=2
# start:起始值 end:结束值 stride:步长
也可使用此格式:
# with_sequence:
# start=2
# end=10
# stride=2
结果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [file] ***************************************************************************************************************************
changed: [B] => (item=2)
changed: [B] => (item=4)
changed: [B] => (item=6)
changed: [B] => (item=8)
changed: [B] => (item=10)
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
例 2:输出 1 ~ 5 之间的数字。
---
- hosts: B
gather_facts: no
tasks:
- debug:
var: item
with_sequence: count=5
# count 可用来输出连续的序列,默认步长为 1,起始值为 1。
效果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=1) => {
"ansible_loop_var": "item",
"item": "1"
}
ok: [B] => (item=2) => {
"ansible_loop_var": "item",
"item": "2"
}
ok: [B] => (item=3) => {
"ansible_loop_var": "item",
"item": "3"
}
ok: [B] => (item=4) => {
"ansible_loop_var": "item",
"item": "4"
}
ok: [B] => (item=5) => {
"ansible_loop_var": "item",
"item": "5"
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
例 3:输出 1 ~ 5 之间的数字并保留两位小数。
---
- hosts: B
gather_facts: no
tasks:
- debug:
var: item
with_sequence: count=5 format="number is %0.2f"
# format 是一个格式化参数,使用类似于 C 语言中的 printf 函数。
效果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=number is 1.00) => {
"ansible_loop_var": "item",
"item": "number is 1.00"
}
ok: [B] => (item=number is 2.00) => {
"ansible_loop_var": "item",
"item": "number is 2.00"
}
ok: [B] => (item=number is 3.00) => {
"ansible_loop_var": "item",
"item": "number is 3.00"
}
ok: [B] => (item=number is 4.00) => {
"ansible_loop_var": "item",
"item": "number is 4.00"
}
ok: [B] => (item=number is 5.00) => {
"ansible_loop_var": "item",
"item": "number is 5.00"
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_random_choice
使用 with_random_choice
可以从列表的多个值中随机返回一个值。
看如下示例:
---
- hosts: B
gather_facts: no
tasks:
- debug:
var: item
with_random_choice:
- 1
- 2
- 3
- 4
- 5
效果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=5) => {
"ansible_loop_var": "item",
"item": 5
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=2) => {
"ansible_loop_var": "item",
"item": 2
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_dict
with_dict
用来以字典的形式遍历对象,遍历对象的属性名将保存在 key
变量中,属性值将保存在 value
变量中。
看如下示例:
---
- hosts: B
gather_facts: no
vars:
users:
alice: female
bob: male
tasks:
- debug:
var: item
with_dict: "{{users}}"
结果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item={'value': u'male', 'key': u'bob'}) => {
"ansible_loop_var": "item",
"item": {
"key": "bob",
"value": "male"
}
}
ok: [B] => (item={'value': u'female', 'key': u'alice'}) => {
"ansible_loop_var": "item",
"item": {
"key": "alice",
"value": "female"
}
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_subelements
with_subelements
能够遍历对象中指定序列的每一项,并把对象的其它部分作为一个整体,用每一项与对象的其它部分做组合。
看下面示例:
---
- hosts: B
gather_facts: no
vars:
users:
- name: bob
hobby:
- Skateboard
- VideoGame
- name: alice
hobby:
- Music
tasks:
- debug:
var: item
with_subelements:
- "{{users}}"
- hobby
结果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=[{u'name': u'bob'}, u'Skateboard']) => {
"ansible_loop_var": "item",
"item": [
{
"name": "bob"
},
"Skateboard"
]
}
ok: [B] => (item=[{u'name': u'bob'}, u'VideoGame']) => {
"ansible_loop_var": "item",
"item": [
{
"name": "bob"
},
"VideoGame"
]
}
ok: [B] => (item=[{u'name': u'alice'}, u'Music']) => {
"ansible_loop_var": "item",
"item": [
{
"name": "alice"
},
"Music"
]
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_file
with_file
可以用来遍历指定文件路径列表中每一个文件的内容,这个文件列表路径是 ansible 管理机本地的文件路径,文件路径不支持 glob 通配符。
看下面示例:
---
- hosts: B
remote_user: root
gather_facts: no
tasks:
- debug:
var: item
with_file:
- file_a
- file_b
结果如下:
$ cat file_a
in file a
$ cat file_b
in file b
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=in file a) => {
"ansible_loop_var": "item",
"item": "in file a"
}
ok: [B] => (item=in file b) => {
"ansible_loop_var": "item",
"item": "in file b"
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
with_fileglob
with_fileglob
可以用来遍历指定文件路径列表中每一个文件的内容,这个文件列表路径是 ansible 管理机本地的文件路径,文件路径支持 glob 通配符。
看下面示例:
---
- hosts: B
remote_user: root
gather_facts: no
tasks:
- debug:
var: item
with_fileglob:
- /opt/file_*
结果如下:
$ cat /opt/file_a
in /opt/file a
$ cat /opt/file_b
in /opt/file b
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [B] => (item=/opt/file_a) => {
"ansible_loop_var": "item",
"item": "/opt/file_a"
}
ok: [B] => (item=/opt/file_b) => {
"ansible_loop_var": "item",
"item": "/opt/file_b"
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
评论区