ansible常用模块学习之循环模块学习

1.通过with_items实现简单的循环

---
- hosts: test
  remote_user: root
  gather_facts: no
  tasks:
     - name: test loop
       debug: msg="{{item}}"
       with_items:
            - "{{groups.test}}" 

[root@ansible ansible]# ansible-playbook loops.yaml 

PLAY [test] **************************************************************************************************************************************************************************************************

TASK [test loop] *********************************************************************************************************************************************************************************************
ok: [192.168.10.21] => (item=192.168.10.21) => {
    "msg": "192.168.10.21"
}
ok: [192.168.10.21] => (item=192.168.10.20) => {
    "msg": "192.168.10.20"
}
ok: [192.168.10.20] => (item=192.168.10.21) => {
    "msg": "192.168.10.21"
}
ok: [192.168.10.20] => (item=192.168.10.20) => {
    "msg": "192.168.10.20"
}

如上例,可以看出test里的每条信息都单独输出了一次。实现了循环的功能。

2.with_together多列表合并

---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  tasks: 
    - debug: msg="{{item}}"
      with_together:
          - [a,b,c]
          - [1,2,3] 

[root@ansible ansible]# ansible-playbook loops_together.yaml 

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => (item=[u'a', 1]) => {
    "msg": [
        "a", 
        1
    ]
}
ok: [192.168.10.20] => (item=[u'b', 2]) => {
    "msg": [
        "b", 
        2
    ]
}
ok: [192.168.10.20] => (item=[u'c', 3]) => {
    "msg": [
        "c", 
        3
    ]
}

3 with_cartesian 可实现多层循环

业务场景如
需要建test1 test2 test3 test4 目录 然后下面都再建a b c 三个目录
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  tasks:
     - name: create dir
       file: 
         state: directory
         path: "/test/{{item.0}}/{{item.1}}"
       with_cartesian:
             - [test1,test2,test3,test4]
             - [a,b,c] 

[root@ansible ansible]# ansible-playbook loops_cartesian.yaml 

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK [create dir] ********************************************************************************************************************************************************************************************
changed: [192.168.10.20] => (item=[u'test1', u'a'])
changed: [192.168.10.20] => (item=[u'test1', u'b'])
changed: [192.168.10.20] => (item=[u'test1', u'c'])
changed: [192.168.10.20] => (item=[u'test2', u'a'])
changed: [192.168.10.20] => (item=[u'test2', u'b'])
changed: [192.168.10.20] => (item=[u'test2', u'c'])
changed: [192.168.10.20] => (item=[u'test3', u'a'])
changed: [192.168.10.20] => (item=[u'test3', u'b'])
changed: [192.168.10.20] => (item=[u'test3', u'c'])
changed: [192.168.10.20] => (item=[u'test4', u'a'])
changed: [192.168.10.20] => (item=[u'test4', u'b'])
changed: [192.168.10.20] => (item=[u'test4', u'c'])

查看结果
[root@gitlab ~]# tree /test
/test
├── test1
│   ├── a
│   ├── b
│   └── c
├── test2
│   ├── a
│   ├── b
│   └── c
├── test3
│   ├── a
│   ├── b
│   └── c
└── test4
    ├── a
    ├── b
    └── c

4 with_indexed_items为列表加索引


[root@ansible ansible]# cat loops_indexed.yaml --- - hosts: test remote_user: root gather_facts: no tasks: - debug: msg: "{{item}}" with_indexed_items: - test1 - test2 - test3 结果: [root@ansible ansible]# ansible-playbook loops_indexed.yaml PLAY [test] ************************************************************************************************************************************************************************************************** TASK [debug] ************************************************************************************************************************************************************************************************* ok: [192.168.10.20] => (item=[0, u'test1']) => { "msg": [ 0, "test1" ] } ok: [192.168.10.20] => (item=[1, u'test2']) => { "msg": [ 1, "test2" ] } ok: [192.168.10.20] => (item=[2, u'test3']) => { "msg": [ 2, "test3" ] } 多重嵌套,深层嵌套为一个整体 [root@ansible ansible]# cat loops_indexed.yaml --- - hosts: test remote_user: root gather_facts: no tasks: - debug: msg: "{{item}}" with_indexed_items: - test1 - [test2,[test4,test5]] - test3 [root@ansible ansible]# ansible-playbook loops_indexed.yaml PLAY [test] ************************************************************************************************************************************************************************************************** TASK [debug] ************************************************************************************************************************************************************************************************* ok: [192.168.10.20] => (item=[0, u'test1']) => { "msg": [ 0, "test1" ] } ok: [192.168.10.20] => (item=[1, u'test2']) => { "msg": [ 1, "test2" ] } ok: [192.168.10.20] => (item=[2, [u'test4', u'test5']]) => { "msg": [ 2, [ "test4", "test5" ] ] }

5 with_sequence按照规定递增递减


--- - hosts: 192.168.10.20 remote_user: root gather_facts: no tasks: - debug: msg: "{{item}}" with_sequence: start=6 end=12 stride=2 [root@ansible ansible]# ansible-playbook loops_sequence.yaml PLAY [192.168.10.20] ***************************************************************************************************************************************************************************************** TASK [debug] ************************************************************************************************************************************************************************************************* ok: [192.168.10.20] => (item=6) => { "msg": "6" } ok: [192.168.10.20] => (item=8) => { "msg": "8" } ok: [192.168.10.20] => (item=10) => { "msg": "10" } ok: [192.168.10.20] => (item=12) => { "msg": "12" }

6 with_random_choice随机返回

[root@ansible ansible]# cat loops_random_choice.yaml
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  tasks:
     - debug:
         msg: "{{item}}"
       with_random_choice:
             - 1
             - 2
             - 3
             - 4

结果如下
[root@ansible ansible]# ansible-playbook loops_random_choice.yaml 

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => (item=1) => {
    "msg": 1
}

PLAY RECAP ***************************************************************************************************************************************************************************************************
192.168.10.20              : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@ansible ansible]# ansible-playbook loops_random_choice.yaml 

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => (item=3) => {
    "msg": 3
}

7 with_dict字典格式变量

[root@ansible ansible]# cat loops_dict.yaml
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  vars:
    users:
      alice: 
         name: alice app
         gender: female
         telephone: 12345656
      bob: 
        name: bob app
        gender: male
        telephone: 9876655 
  tasks: 
    - debug: 
        msg: "User {{item.key}} is {{item.value.name}}, gender is {{ item.value.gender}} tel is {{item.value.telephone}} "
      with_dict: "{{users}}"   

[root@ansible ansible]# ansible-playbook loops_dict.yaml 

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => (item={u'key': u'bob', u'value': {u'gender': u'male', u'name': u'bob app', u'telephone': 9876655}}) => {
    "msg": "User bob is bob app, gender is male tel is 9876655 "
}
ok: [192.168.10.20] => (item={u'key': u'alice', u'value': {u'gender': u'female', u'name': u'alice app', u'telephone': 12345656}}) => {
    "msg": "User alice is alice app, gender is female tel is 12345656 "
}

PLAY RECAP ***************************************************************************************************************************************************************************************************
192.168.10.20              : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

8 with_subelements多层

[root@ansible ansible]# cat loops_subelements.yaml
--- 
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no 
  vars:
    users: 
    - name: bob
      gender: male
      hobby:
        - test1
        - test2
    - name: alice
      gender: female
      hobby:
        - test3
  tasks:
  - debug:
     msg: "{{item.0.name}} 's hobby is {{item.1}}"
    with_subelements:
        - "{{users}}" 
        - hobby

结果
[root@ansible ansible]# ansible-playbook loops_subelements.yaml 

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => (item=[{u'gender': u'male', u'name': u'bob'}, u'test1']) => {
    "msg": "bob 's hobby is test1"
}
ok: [192.168.10.20] => (item=[{u'gender': u'male', u'name': u'bob'}, u'test2']) => {
    "msg": "bob 's hobby is test2"
}
ok: [192.168.10.20] => (item=[{u'gender': u'female', u'name': u'alice'}, u'test3']) => {
    "msg": "alice 's hobby is test3"
}

9 with_file获取ansible主机文件内容


--- - hosts: 192.168.10.20 remote_user: root gather_facts: no tasks: - debug: msg: "{{item}}" with_file: - "/etc/ansible/var_file" 结果: [root@ansible ansible]# ansible-playbook loops_file.yaml PLAY [192.168.10.20] ***************************************************************************************************************************************************************************************** TASK [debug] ************************************************************************************************************************************************************************************************* ok: [192.168.10.20] => (item=testvar:testvarinfile countlist - one - two - three) => { "msg": "testvar:testvarinfile\ncountlist\n- one\n- two\n- three" }

10 with_fileglob 匹配ansible主机上指定目录的文件名

[root@ansible ansible]# cat loops_fileglob.yaml
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  tasks:
    - debug: 
       msg: "{{item}}"
      with_fileglob:
          - "/tmp/*"

结果
[root@ansible ansible]# ansible-playbook loops_fileglob.yaml 

PLAY [192.168.10.20] *****************************************************************************************************************************************************************************************

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => (item=/tmp/te2.devopstack.com) => {
    "msg": "/tmp/te2.devopstack.com"
}
ok: [192.168.10.20] => (item=/tmp/te1.devopstack.com) => {
    "msg": "/tmp/te1.devopstack.com"
}

11 新的循环方式

可以用lookup和dict代替with_dict实现相同的功能
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  vars:
    users:
      alice: female
      bob: male
  tasks:
    - debug: 
       msg: "{{item.key}} is {{item.value}}"
      loop: "{{lookup('dict',users)}}"

结果:
TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => (item={u'key': u'bob', u'value': u'male'}) => {
    "msg": "bob is male"
}
ok: [192.168.10.20] => (item={u'key': u'alice', u'value': u'female'}) => {
    "msg": "alice is female"
}

在2.6版本的官网手册中,官方开始推荐使用"loop加filter"的方式来替代"loop加lookup"的方式,过滤器使用dict2items实现相同的功能。
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  vars:
   users:
     alice: female
     bob: male
  tasks:
    - debug:
        msg: "{{item.key}} is {{item.value}}"
      loop: "{{users|dict2items}}"
loop可以替代with_list,当处理嵌套的列表时,列表不会被拉平
---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  vars: 
    testlist:
    - a
    - [b,c]
    - d
  tasks:
    - debug: 
       msg: "{{item}}"
      loop: "{{testlist}}" 

ok: [192.168.10.20] => (item=a) => {
    "msg": "a"
}
ok: [192.168.10.20] => (item=[u'b', u'c']) => {
    "msg": [
        "b", 
        "c"
    ]
}
ok: [192.168.10.20] => (item=d) => {
    "msg": "d"
}

flatten过滤器可以替代with_flattened,当处理多层嵌套的列表时,列表中所有的嵌套层级都会被拉平

---
- hosts: 192.168.10.20
  remote_user: root
  gather_facts: no
  vars: 
    testlist:
    - a
    - [b,c]
    - d
  tasks:
    - debug: 
       msg: "{{item}}"
      loop: "{{testlist|flatten}}" 

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [192.168.10.20] => (item=a) => {
    "msg": "a"
}
ok: [192.168.10.20] => (item=b) => {
    "msg": "b"
}
ok: [192.168.10.20] => (item=c) => {
    "msg": "c"
}
ok: [192.168.10.20] => (item=d) => {
    "msg": "d"
}

flatten过滤器(加参数),再配合loop_control关键字,可以替代with_indexed_items

#flatten过滤器(加参数),再配合loop_control关键字,可以替代with_indexed_items
#当处理多层嵌套的列表时,只有列表中的第一层会被拉平,flatten过滤器的bug暂且忽略
示例如下,之后会对示例进行解释
---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    testlist:
    - a
    - [b,c]
    - d
  tasks:
  - debug:
      msg: "{{index}}--{{item}}"
    loop: "{{testlist | flatten(levels=1)}}"
    loop_control:
      index_var: index

"loop_control"关键字可以用于控制循环的行为,比如在循环时获取到元素的索引。

"index_var"是"loop_control"的一个设置选项,"index_var"的作用是让我们指定一个变量,"loop_control"会将列表元素的索引值存放到这个指定的变量中,比如如下配置

Shell
  loop_control:
    index_var: my_idx
1
2
  loop_control:
    index_var: my_idx
上述设置表示,在遍历列表时,当前被遍历元素的索引会被放置到"my_idx"变量中,也就是说,当进行循环操作时,只要获取到"my_idx"变量的值,就能获取到当前元素的索引值,当然,除了"index_var"选项,"loop_control"还有一些其他的选项可以使用,我们之后再进行总结。

with_nested/with_cartesian #product过滤器配合list过滤器,可以替代with_nested和with_cartesian
---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    testlist1: [ a, b, c ]
    testlist2: [ 1, 2, 3, 4 ]
  tasks:
  - debug:
      msg: "{{ item.0 }}--{{ item.1 }}"
    loop: "{{ testlist1 | product(testlist2) | list }}"
with_sequence #range过滤器配合list过滤器可以代替with_sequence
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "{{item}}"
    loop: "{{ range(0, 6, 2) | list }}"
with_random_choice #使用random函数可以替代with_random_choice,由于random函数是随机取出列表中的一个值,并不涉及循环操作,所以并不用使用loop关键字。
---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    testlist: [ a, b, c ]
  tasks:
  - debug:
      msg: "{{ testlist | random }}"
with_dict 除了上文总结的dict2items过滤器,dictsort过滤器也可以替代with_dict
---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    users:
      d: daisy
      c: carol
      a: alice
      b: bob
      e: ella
  tasks:
  - debug:
      msg: "{{item.key}} -- {{item.value}}"
    loop: "{{ users | dict2items }}"
  - debug:
      msg: "{{item.0}} -- {{item.1}}"
    loop: "{{ users | dictsort }}"
with_subelements #subelements过滤器可以替代with_subelements

--- - hosts: test70   remote_user: root   gather_facts: no   vars:     users:     - name: bob       gender: male       hobby:         - Skateboard         - VideoGame     - name: alice       gender: female       hobby:         - Music   tasks:   - debug:       msg: "{{item.0.name}}'s hobby is {{item.1}}"     with_subelements:     - "{{users}}"     - hobby   - debug:       msg: "{{item.0.name}}'s hobby is {{item.1}}"     loop: "{{users | subelements('hobby')}}"

12     loop_control label简化输出结果

---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    users:
      alice:
        name: Alice Appleworth
        gender: female
        telephone: 123-456-7890
      bob:
        name: Bob Bananarama
        gender: male
        telephone: 987-654-3210
  tasks:
  - debug:
      msg: "{{item.key}}"
    loop: "{{users | dict2items}}"
    loop_control:
      label: "{{item.key}}"

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin
avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: