Bootstrap

Ansible中Playbook的逻辑控制语句-loop

playbook的逻辑控制语句

  • when
    • 条件判断语句,类似if
  • loop
    • 循环语句,类似loop
  • block
    • 将几个任务组成一个代码块,便于针对一组操作的异常进行处理

loop循环

  • 标准loop使用的是类似数组的方式
  • 嵌套loop使用的是类似列表套字典的方式
  • 散列loop可以直接使用字典形式,但是要遵循yaml的格式

loop的标准循环

  • loop循环可以使用with_items关键字或者loop关键字
  • 重复的任务可以用以下的方式简写
- hosts: webservers
  tasks:
  - name: ensure some services at the latest version
    yum:
      name: {{item}}
      state: latest
    with_items:
      - httpd
      - php
      - php-mysql
  • loop循环会将with_items后面的列表中的元素依次赋值给item变量,然后执行后面的任务
  • 如果在变量中已经定义了一组列表变量,也可以用{{变量名称}}的方式引用,如下:
- hosts: webservers
# 此处定义一个packages变量,其值为一个列表
  vars:
    packages:
      - httpd
      - php
      - php-mysql
  tasks:
  - name: ensure some services at the latest version
    yum:
      name: {{item}}
      state: latest
    # 使用packages变量,将其赋值给上面的item变量
    with_items: "{{packages}}"
  • with_items`的引用不止限于字符串列表,还可以是类似python中的字典列表,是一对键值对,如下:
- hosts: webservers
  tasks:
  - name: ensure some services at the latest version
    yum:
      name: "{{item.key}}"
      state: "{{item.value}}"
    with_dict:
      - [key: 'httpd',value: 'latest']
      - [key: 'php',value: 'latest']
      - [key: 'php-mysql',value: 'latest']
  • 注意:如果使用when条件判断和with_items循环,when声明会对每一个item都单独进行判断

loop的嵌套循环

  • 循环可以嵌套,用以下两种方法实现:
    • 使用[]的方式
    • 使用.的方式
  • 示例如下:
---
- hosts: localhost
  gather_facts: False
  tasks:
    - name: debug loops
      debug: msg="name->{{ item[0] }} value->{{ item.1 }}"
      with_nested:
         - ['A','B']
         - ['a','b','c']
# 以上代码会将A和a组合,A和b组合,A和c组合,B和a组合,B和b组合,B和c组合,分别输出,形成嵌套循环

loop的散列循环

  • 使用字典形式对符合散列格式的变量进行循环
---
- hosts: all
  gather_facts: Fasle
  vars:
    user:
      kebi:
        name: zhangrongkai
        addr: luotian
      maoxian: 
        name: songlixing
        addr: xiaochang

  tasks:
    - name: debug loops
      debug: msg="name--->{{ item.key }} value--->{{ item.value.name }} addr---{{ item.value.addr }}"
      with_dict: "{{ user }}"
# user=变量中的user项
# item.key=变量中的user项中的kebi和maoxian项
# item.value=变量中的user项中的kebi和maoxian项中的name和addr项
# 最后通过item.value.name和item.value.addr来输出name和addr的值

文件配置loop

  • 针对文件的操作可以使用with_fileglob关键字来实现,如下:
---
- hosts: all
  tasks:
    - name: debug loops
      debug: msg="filename--->{{ item }}"
      with_fileglob:
        - /tmp/*.py
# 该方法会返回当前目录下符合条件的文件列表
  • 实际上是调用了python中的glob模块来实现的:glob.glob("/tmp/*.py")

随机选择loop

  • 针对随机选择的操作可以使用with_random_choice关键字来实现,如下:
---
- hosts: all
  tasks:
     - name: debug loops
       debug: msg="name--->{{ item }}"
       with_random_choice:
         - "test1"
         - "test2"
         - "test3"
# 该方法会随机选择一个在关键字下面列出的元素,将 其赋值给item变量
  • 实际上是调用了python中的random模块来实现的:random.choice(["test1","test2","test3"])

文件优先匹配loop

  • 使用with_first_found关键字可以实现文件优先匹配的操作,如下:
---
- hosts: all
  tasks:
    - name: debug loops
      debug: msg="file--->{{ item }}"
      with_first_found:
        - "{{ ansible_distribution }}.yaml"
        - "default.yaml
# 如果匹配到了{{ ansible_distribution }}.yaml文件,就使用该文件,如果没有匹配到,就使用default.yaml文件

在loop循环中使用变量获取结果

  • 在loop循环中使用变量获取结果可以使用register关键字来实现,如下:
---
- hosts: all
  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 %}"
# 使用ret变量来保存结果,然后通过ret.results来获取结果,最后通过for循环来输出结果
# ret获取到的是两个yaml格式的数据,分别是hostname和uname的结果
;