使用Ansible loops编写循环

来源:互联网 发布:流程图描述算法 编辑:程序博客网 时间:2024/06/05 15:44

在ansible的playbook中如果发现需要有很多task重复的引用某一个相同的模块时这个时候需要使用loops去编写playbook减少使用某个模块。

标准循环

标准循环关键字:”with_items:”
编写standerloop.yaml的playbook文件分别对远程主机打印one,two这两个值:

---  - gather_facts: Flase    hosts: all    tasks:    -      debug: "msg= \"name -----> {{ item }}\""      name: "debug loops"      with_items:       - one       - two

执行的结果如下:
这里写图片描述

with_items的值是python list数据结构,可以理解为每个task会循环读取list里面的值,然后key的名称是item,当然list里面也支持python字典形式:

---  - gather_facts: Flase    hosts: all    tasks:    -      debug: "msg=\"name -----> {{ item.key }}    vaule -----> {{ item.vaule }}\""      name: "debug loops"      with_items:       - { key: "one", vaule: "VAULE1"}       - { key: "two", vaule: "VAULE2"}

执行结果如下:
这里写图片描述

嵌套循环

嵌套循环主要实现一对多,多对多的合并

----  hosts: all  gather_facts: False  tasks:  - name: debug loops    debug: "msg=\"name -----> {{ item[0] }} vaule -----> {{ item[1] }}\""    with_nested:    - ['Ansible']    - ['test1','test2','test3']

得到的结果如下:
这里写图片描述

散列loops(对哈希表进行循环)

标准的loop最外层必须是Python的list数据类型,而散列loops直接支持YAML格式的数据变量。散列的loops直接支持YAML格式的数据变量。使用with_dict来循环哈希表中的元素,with_dict是接收一个Python字典(经过yaml.load后)的格式变量:

----  hosts: all  gather_facts: False  vars:   user:    Bob_hou:     name: Bob_Hou     shell: bash    Jmilk:     name: Jmilk     shell: zsh  tasks:  -    name: debug loops    debug: "msg=\"name -----> {{item.key }} value -----> {{item.value.name }} shell -----> {{ item.value.shell }}\""    with_dict: "{{ user }}"

输出的结果为:
这里写图片描述

文件匹配loop

在编写playbook的时候需要针对文件进行操作中最常使用到的循环,例如我们需要对一个目录下指定格式的文件进行处理,这个时候我们直接使用with_fileglob循环去匹配我们需要处理的文件。例如我要寻找playbook中所有的yaml格式的剧本文件,于是编写一个如下的文件匹配循环:

----  hosts: all  gather_facts: False  tasks:  -    name: debug loops    debug: "msg=\"files -----> {{ item }}\""    with_fileglob:    -      /root/playbook/*.yaml

with_fileglob这个时候会匹配root/playbook目录下所有以yaml结尾的文件,当作{{ item }} 变量,运行的结果如下:

这里写图片描述

实际上文件循环是使用python glob模块去做文件模糊匹配:

>>> import glob>>> print glob.glob('/root/playbook/*.yaml')['/root/playbook/nginx-116.yaml', '/root/playbook/fileloop.yaml', '/root/playbook/var.yaml', '/root/playbook/standerloop.yaml', '/root/playbook/nestedloop.yaml', '/root/playbook/variable.yaml', '/root/playbook/nginx.yaml', '/root/playbook/hashloop.yaml']

随机选择loop

利用with_random_choice在传入的list中随机选择一个,与使用python random实现原理一样。它有时可以用作一个简化版的负载均衡器,比如作为条件判断。提供的字符串中的其中一个会被随机选中。

----  hosts: all  gather_facts: False  tasks:  -    name: debug loops    debug: "msg=\"name -----> {{ item }}\""    with_random_choice:    - "web"    - "devstack"    - "nginx"

执行的结果如下:
这里写图片描述

条件判断Loops

如我们执行一个task之后,我们想要检测这个task结果是否达到了预想状态,如果没有没有达到预想状态,我们就需要退出整个playbook执行,这个时候可以使用循环检测判断了。

----  hosts: all  gather_facts: False  tasks:  -    name: debug loops    shell: cat /root/ansible    register: host    until: host.stdout.startswith("cat")    retries: 5    delay: 5

每5秒执行一次cat /root/ansible结果,然后将结果交给register的host参数,然后判断host.stdout.startswith的内容是否是cat字符串开头,如果条件成立,此task运行完成,如果条件不成立5s后重试,5次还不成立,此task运行失败。这里我选用的目录就是一个假目录,所以最后执行结果会是失败的。
这里写图片描述

文件优先匹配

如果你想引用一个文件,而该文件是从一组文件中根据给定条件匹配出来的,你可以使用这种模式:

----  hosts: all  gather_facts: True  tasks:  -    name: debug loops    debug: "msg=\"files -----> {{item }}\""    with_first_found:    -      "{{ ansible_distribution }}.yaml"    -      "nginx.yaml"

with_first_found会从list里面定义的文件从上往下一个一个的匹配,如果匹配到了item就是该文件。输出结果如下:
这里写图片描述

register loops循环

register适用于task直接互相传递数据的,一般我们会把register用在单一的task中进行变量临时存储,其实register还可以同时接受多个task的结果当做变量临时存储:

----  hosts: all  gather_facts: True  tasks:  -    name: debug loops    shell: "{{ item }}"    with_items:    -      hostname    -      uname    register: ret  - name: display loops    debug: "msg=\"{% for i in ret.results %} {{ i.stdout }} {% endfor %}\""

输出结果如下:
这里写图片描述

关于循环这一块如果对阅读英语文档有困难的朋友,可以推荐一个网址:
http://www.ansible.com.cn/docs/playbooks_loops.html
这里翻译了英文文档,然后也给了详细的示例,可以参考。

0 0