• ansible playbooks loop循环


    在一个task中循环某个操作

    1、标准循环

    1. - name: add several users
    2. user:
    3. name: "{{ item }}"
    4. state: present
    5. groups: "wheel"
    6. loop:
    7. - testuser1
    8. - testuser2
    9. #如果已经在变量文件中,定义了yaml列表,可以这么写
    10. loop: "{{ somelist }}"
    note:在2.5 Ansible之前主要使用with_ <lookup>关键字来创建循环,循环关键字基本上类似于with_list,with_items。
    我现在也在用,啊哈!
    一些ansible插件,类似yum和apt模块可以直接列出引用的选项,比使用loop更好,如下:
    1. - name: optimal yum
    2. yum:
    3. name: "{{list_of_packages}}"
    4. state: present
    5. - name: non optimal yum, not only slower but might cause issues with interdependencies
    6. yum:
    7. name: "{{item}}"
    8. state: present
    9. loop: "{{list_of_packages}}"
    迭代的items类型也可以是hash列表,例如:
    1. - name: add several users
    2. user:
    3. name: "{{ item.name }}"
    4. state: present
    5. groups: "{{ item.groups }}"
    6. loop:
    7. - { name: 'testuser1', groups: 'wheel' }
    8. - { name: 'testuser2', groups: 'root' }

    2、复杂的循环

    有时候你不只是需要一个简单列表,你可以用jinja2表达式创建复杂的列表,例如使用 “netsed" lookup
    1. - name: give users access to multiple databases
    2. mysql_user:
    3. name: "{{ item[0] }}"
    4. priv: "{{ item[1] }}.*:ALL"
    5. append_privs: yes
    6. password: "foo"
    7. loop: "{{ query('nested', [ 'alice', 'bob' ], [ 'clientdb', 'employeedb', 'providerdb' ]) }}"
    note: with_ 循环实际上是组合了 with_ + lookup(),甚至是with_items。 loop也可以这么搞,类似上边例子。

    3、使用lookup 与 用loop查询

    ansible2.5加入了新的函数 query,为lookup插件增加一些益处,当使用新的关键字loop时候。query提供一个更简单的借口和可预测性更好的输出,确保兼容loop。
    一些情况中,lookup函数不会返回 loop需要的list,下列的调用是相等的:
    1. loop: "{{ query('nested', ['alice', 'bob'], ['clientdb', 'employeedb', 'providerdb']) }}"
    2. loop: "{{ lookup('nested', ['alice', 'bob'], ['clientdb', 'employeedb', 'providerdb'], wantlist=True) }}"

    4、Do-Until循环

    1. - shell: /usr/bin/foo
    2. register: result
    3. until: result.stdout.find("all systems go") != -1
    4. retries: 5
    5. delay: 10
    上例 递归执行shell模块,直到“all systems go”在标准输出出现,或者每个10s执行1次,执行5次之后无结果。 retries默认值是3,delay默认值是5。
    note:如果until参数没有定义, retries值被强制设置为1。

    5、使用loop中的register

    1. - shell: "echo {{ item }}"
    2. loop:
    3. - "one"
    4. - "two"
    5. register: echo
    与使用loop和register不同的例子
    1. {
    2. "changed": true,
    3. "msg": "All items completed",
    4. "results": [
    5. {
    6. "changed": true,
    7. "cmd": "echo "one" ",
    8. "delta": "0:00:00.003110",
    9. "end": "2013-12-19 12:00:05.187153",
    10. "invocation": {
    11. "module_args": "echo "one"",
    12. "module_name": "shell"
    13. },
    14. "item": "one",
    15. "rc": 0,
    16. "start": "2013-12-19 12:00:05.184043",
    17. "stderr": "",
    18. "stdout": "one"
    19. },
    20. {
    21. "changed": true,
    22. "cmd": "echo "two" ",
    23. "delta": "0:00:00.002920",
    24. "end": "2013-12-19 12:00:05.245502",
    25. "invocation": {
    26. "module_args": "echo "two"",
    27. "module_name": "shell"
    28. },
    29. "item": "two",
    30. "rc": 0,
    31. "start": "2013-12-19 12:00:05.242582",
    32. "stderr": "",
    33. "stdout": "two"
    34. }
    35. ]
    36. }
    循环遍历注册的变量来检查结果:
    1. - name: Fail if return code is not 0
    2. fail:
    3. msg: "The command ({{ item.cmd }}) did not have a 0 return code"
    4. when: item.rc != 0
    5. loop: "{{ echo.results }}"
    在迭代期间,当前item的结果将被放置在变量中
    1. - shell: echo "{{ item }}"
    2. loop:
    3. - one
    4. - two
    5. register: echo
    6. changed_when: echo.stdout != "one"

    6、循环inventory

    如果想循环inventory中的hosts或者部分hosts,你可以用loop的ansible_play_batch或者groups变量:
    1. # show all the hosts in the inventory
    2. - debug:
    3. msg: "{{ item }}"
    4. loop: "{{ groups['all'] }}"
    5. #show all the hosts in the current play
    6. - debug:
    7. msg: "{{ item }}"
    8. loop: "{{ ansible_play_batch }}"
    使用lookup 插件 inventory_hostname 实现:
    1. # show all the hosts in the inventory
    2. - debug:
    3. msg: "{{ item }}"
    4. loop: "{{ query('inventory_hostnames', 'all') }}"
    5. # show all the hosts matching the pattern, ie all but the group www
    6. - debug:
    7. msg: "{{ item }}"
    8. loop: "{{ query('inventory_hostnames', 'all!www') }}"
     

    7、循环控制

    2.0版本你可以使用loops和task includes(不能用playbook includes)。这增加了一次循环一组任务的能力。每次循环,Ansible默认设置循环变量item,这会导致这些嵌套loop覆盖来自“外部”循环的项目的值。从Ansible 2.1开始,loop_control选项可用于指定要用于循环的变量名。
    1. # main.yml
    2. - include: inner.yml
    3. - include_tasks: inner.yml
    4. loop:
    5. - 1
    6. - 2
    7. - 3
    8. loop_control:
    9. loop_var: outer_item
    10. # inner.yml
    11. - debug:
    12. msg: "outer item={{ outer_item }} inner item={{ item }}"
    13. loop:
    14. - a
    15. - b
    16. - c
    note:如果Ansible检测到当前循环正在使用已定义的变量,则会引发错误以使任务失败。
    当使用复杂的数据结构来循环显示时,可能会出现busy情况,这就是label指令提供帮助的地方
    1. - name: create servers
    2. digital_ocean:
    3. name: "{{ item.name }}"
    4. state: present
    5. loop:
    6. - name: server1
    7. disks: 3gb
    8. ram: 15Gb
    9. network:
    10. nic01: 100Gb
    11. nic02: 10Gb
    12. ...
    13. loop_control:
    14. label: "{{ item.name }}"
    现在,它将只显示标签字段,而不是每个项目的整个结构,它默认为{{item}}来照常显示内容。
     
    循环控制的另一个选项是暂停,它允许您控制执行任务循环中的项目之间的时间(以秒为单位)。
    1. # main.yml
    2. - name: create servers, pause 3s before creating next
    3. digital_ocean:
    4. name: "{{ item }}"
    5. state: present
    6. loop:
    7. - server1
    8. - server2
    9. loop_control:
    10. pause: 3
    如果您需要跟踪您在循环中的位置,可以使用index_var选项来循环控制以指定变量名称以包含当前循环索引。
    1. - name: count our fruit
    2. debug:
    3. msg: "{{ item }} with index {{ my_idx }}"
    4. loop:
    5. - apple
    6. - banana
    7. - pear
    8. loop_control:
    9. index_var: my_idx

    8、loops和 includes (2.0版本)

    由于loop_control在Ansible 2.0中不可用,因此当使用带有循环的include时,应该使用set_fact保存item的“outer”循环值:
    1. # main.yml
    2. - include_tasks: inner.yml
    3. loop:
    4. - 1
    5. - 2
    6. - 3
    7. # inner.yml
    8. - set_fact:
    9. outer_item: "{{ item }}"
    10. - debug:
    11. msg: "outer item={{ outer_item }} inner item={{ item }}"
    12. loop:
    13. - a
    14. - b
    15. - c
    16. Note
  • 相关阅读:
    mongodb的常用操作(二)
    mongodb的常用操作
    OpenBSD内核之引导PBR
    OpenBSD内核之引导MBR
    OpenBSD之开篇
    “索引”、大数据的思考
    flume坑之channel.transactionCapacity和HdfsSink.batchSize
    cocos2d-x的CCAffineTransform相关变换实现原理
    MySQL JDBC/MyBatis Stream方式读取SELECT超大结果集
    “全服单世界”的终极目标即“虚拟世界”
  • 原文地址:https://www.cnblogs.com/nineep/p/9084995.html
Copyright © 2020-2023  润新知