• 第6章 ansible循环和条件判断


    第6章 ansible循环和条件判断

    • 6.1. 循环

    6.1.1. with_items迭代列表
    6.1.2. with_dict迭代字典项
    6.1.3. with_fileglob迭代文件
    6.1.4. with_lines迭代行
    6.1.5. with_nested嵌套迭代

    • 6.2. 条件判断

    第6章 ansible循环和条件判断

    6.1. 循环

    ansible中的循环都是借助迭代来实现的。基本都是以"with_"开头,一下是常见的几种循环。

    6.1.1. with_items迭代列表

    ansible支持迭代功能。例如:有一大堆要输出的命令,一大堆要安装的软件包,一大堆要copy的文件等等。

    例如:要安装一堆软件包

    ---
        - hosts: localhost
          tasks:
            - yum: name="{{item}}" state=installed
              with_items:
                - pkg1
                - pkg2
                - pkg3
    

    它会一个一个迭代到特殊变量"{{item}}"处。

    再例如,指定一堆文件列表,然后使用grep搜索出给定文件列表中包含"www.example.com"字符串的文件:

    ---
        - hosts: localhost
          tasks:
            - shell: grep -R1 "www.example.com" "{{item}}"
              with_items:
                - file1
                - file2
                - file3
              register: match_file
            - debug: msg="{% for i in match_file.results %} {{i.stdout}} {% end %}"
    

    注意:将with_items迭代后的结果注册为变量时,其注册结果也是列表式的,且其key为"results"。具体的结果比较长,可以使用debug模块的var或msg参数观察match_file变量的结果。

    在上面,是使用for循环进行引用的。如果不使用for循环,那么就需要使用数组格式。例如:引用match_file中的第一和第二个结果。

    - debug: var=match_file.result[0].stdout
    - debug: var=match_file.result[1].stdout
    

    显然,不如循环引用更好,因为不知道match_file中到底有几个匹配文件,也就不能确定match_file中的列表数量。

    每个列表项中可能都包含一个或多个字典,既然with_items迭代的是列表项,那么肯定也能迭代列表中的各字典。

    例如:

    tasks:
      - command: echo {{ item }}
        with_items: [ 0,2,4,6,8,10 ]
        register: num
      - debug: msg="{% for i in num.results %} {{i.stdout}} {% endfor %}"
      
    # 再例如:
    ---
        - hosts: localhost
          tasks:
            - shell: echo "name={{item.name}},age={{item.age}}"
              with_items:
                - {name: zhangsan,age: 32}
                - {name: lisi,age: 33}
                - {name: wangwu,age: 35}
              register: who
            - debug: msg="{% for i in who.results %} {{i.stdout}} {% endfor %}"
    

    6.1.2. with_dict迭代字典项

    使用"with_dict"可以迭代字典项。迭代时,使用"item.key"表示字典的key,"item.value"表示字典的值。

    例如:

    ---
        - hosts: localhost
          tasks:
            - debug: msg="{{item.key}} & {{item.value}}"
              with_dict: { address: 1,netmask: 2,gateway: 3}
    
    # 另一种情况,字典已经是存储好的。例如ansible facts中的ansible_eth0.ipv4,内容如下:
    "ipv4": {
        "address": "192.168.1.61",
        "netmask": "255.255.255.0",
        "gateway": "192.168.1.1"
    }
    
    # 这种情况下,with_dict处可以直接指定该字典的key。即:
    ---
        - hosts: localhost
          tasks:
            - debug: msg="{{item.key}} & {{item.value}}"
              with_dict: "{{ansible_ens32.ipv4}}"
    }
    
    # 再例如,直接引用playbook中定义的vars
    ---
        - hosts: localhost
          gather_facts: False
          vars:
            user:
              zh_key:
                name: zh
                gender: Male
              lmz_key:
                name: lmz
                gender: Female
          tasks:
            - name: print hash loop var
              debug: msg="{{item.key}} & {{item.value.name}} & {{item.value.gender}}"
              with_dict: "{{user}}"
    
    # 执行结果部分截取:
    TASK [print hash loop var] *****************************************************
    ok: [localhost] => (item={'value': {u'gender': u'Male', u'name': u'zh'}, 'key': u'zh_key'}) => {
        "msg": "zh_key & zh & Male"
    }
    ok: [localhost] => (item={'value': {u'gender': u'Female', u'name': u'lmz'}, 'key': u'lmz_key'}) => {
        "msg": "lmz_key & lmz & Female"
    }
    

    6.1.3. with_fileglob迭代文件

    例如:拷贝一堆用通配符匹配出来的文件到各远程主机上。

    ---
        - hosts: localhost
          tasks:
            - copy: src="{{item}}" dest=/tmp/
              with_fileglob:
                - /tmp/*.sh
                - /tmp/*.py
    # 注意:通配符无法匹配"/",因此无法递归到子目录中,也就无法迭代子目录中的文件。
    
    

    6.1.4. with_lines迭代行

    with_lines很好用,可以将命令行的输出结果按行迭代。

    例如:find一堆文件出来,copy走

    ---
        - hosts: localhost
          tasks:
            - copy: src="{{item}}" dest=/tmp/yaml
              with_lines:
                - find /tmp -type f -name "*.yml"
    

    6.1.5. with_nested嵌套迭代

    嵌套迭代是指多次迭代列表项,例如:

    ---
        - hosts: localhost
          tasks:
            - debug: msg="{{item[0]}} & {{item[1]}}"
              with_nested:
                - [a,b]
                - [1,2,3]
    
    # 执行结果部分截取:
    TASK [debug] *******************************************************************
    ok: [localhost] => (item=[u'a', 1]) => {
        "msg": "a & 1"
    }
    ok: [localhost] => (item=[u'a', 2]) => {
        "msg": "a & 2"
    }
    ok: [localhost] => (item=[u'a', 3]) => {
        "msg": "a & 3"
    }
    ok: [localhost] => (item=[u'b', 1]) => {
        "msg": "b & 1"
    }
    ok: [localhost] => (item=[u'b', 2]) => {
        "msg": "b & 2"
    }
    ok: [localhost] => (item=[u'b', 3]) => {
        "msg": "b & 3"
    }
    

    6.2. 条件判断

    在ansible中,只有when可以实现条件判断

    tasks:
      - name: config the yum repo for centos 6
        yum_repository:
          name: epel
          description: epel
          baseurl: http://mirrors.aliyun.com/epel/6/$basearch/
          gpgcheck: no
        when: ansible_distribution_major_version == "6"
    

    注意两点:

    • when判断的对象是task,所以和task在同一列表层次。它的判断结果决定它所在task是否执行,而不是它下面的task是否执行。
    • when中引用变量的时候不需要加{{}}符号。
    • 此外,还支持各种逻辑组合。
    tasks:
     
    # 逻辑或
      - command: /sbin/shutdown -h now
        when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or
              (ansible_distribution == "Debian" and ansible_distribution_major_version == "7")
     
    # 逻辑与
      - command: /sbin/shutdown -t now
        when:
          - ansible_distribution == "CentOS"
          - ansible_distribution_major_version == "6"
     
    # 取反
      - command: /sbin/shutdown -t now
        when: not ansible_distribution == "CentOS"
    

    还可以直接引用布尔值的变量

    ---
        - hosts: localhost
          vars:
            epic: False
          tasks:
            - debug: msg="This certainly is epic!"
              when: not epic
    

    此外,可以使用jinja2的defined来测试变量是否已定义,使用undefined可以取反表示未定义。例如:

    tasks:
        - shell: echo "I've got '{{ foo }}' and am not afraid to use it!"
          when: foo is defined
     
        - fail: msg="Bailing out. this play requires 'bar'"
          when: bar is undefined
    
  • 相关阅读:
    xmlHttp.js.rar 没啥说的。。各浏览器都支持的纯ajax!
    实用正则表达式(实用篇) [转]
    Jquery的好书[pdf,新书]
    xml 中的冒号 读取问题的解决
    给一个DataTable 添加一列,来保存计算出来的结果。。
    悟透JavaScript(转) 超级精华
    当前标识符读写权限
    ie浏览器开机自动启动且全屏
    SQL Server ErrorLog 错误日志(如果数据库所占空间变大)
    利用Git hub创建博客
  • 原文地址:https://www.cnblogs.com/HsLM/p/12367580.html
Copyright © 2020-2023  润新知