zoukankan      html  css  js  c++  java
  • Ansible_编写循环和条件任务

    一、利用循环迭代任务

    1️⃣:Ansible支持使用loop关键字对一组项目迭代任务,可以配置循环以利用列表中的各个项目、列表中各个文件的内容、生成的数字序列或更为复杂的结构来重复任务

    1、简单循环

    1️⃣:简单循环对一组项目迭代任务。loop关键字添加到任务中,将应对其迭代任务的项目列表取为值。循环变量item保存每个迭代过程中使用的值

    • 演示实例:
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        tasks:
          - name: create user
            user:
              name: "{{ item }}"
              state: present
            loop:
              - zhangsan
              - lisi
      
       //测试执行play
      [root@localhost project]# ansible-playbook playbook.yaml -C
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [create user] ********************************************************************************************************************************************************
      changed: [client.example.com] => (item=zhangsan)
      changed: [client.example.com] => (item=lisi)
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

    2️⃣:此外、还可以通过变量给loop提供所使用的的列表

    • 演示实例:
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        vars:
          users:
            - zhangsan
            - lisi
            - wangwu
        tasks:
          - name: create user
            user:
              name: "{{ item }}"
              state: present
            loop: "{{ users }}"
      
       //执行play
      [root@localhost project]# ansible-playbook playbook.yaml -C
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [create user] ********************************************************************************************************************************************************
      changed: [client.example.com] => (item=zhangsan)
      changed: [client.example.com] => (item=lisi)
      changed: [client.example.com] => (item=wangwu)
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

    2、循环散列或字典列表

    1️⃣: loop列表不需要是简单值列表

    • 演示实例:item标识一个循环的项目(任务),item.name和item.group表示item的两个键值(键值可自定义,但必须与loop中的项目匹配)
       //查看playbook文件
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        tasks:
          - name: create user
            user:
              name: "{{ item.name }}"
              group: "{{ item.group}}"
              state: present
            loop:
              - name: zhangsan
                group: zhangsan
              - name: lisi
                group: lisi
      
       //测试是否可play
      [root@localhost project]# ansible-playbook playbook.yaml -C
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [create user] ********************************************************************************************************************************************************
      changed: [client.example.com] => (item={'name': 'zhangsan', 'group': 'zhangsan'})
      changed: [client.example.com] => (item={'name': 'lisi', 'group': 'lisi'})
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

    3、将Register变量于Loop一起使用

    • 演示实例:
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        tasks:
          - name: show some user
            shell: 'echo this user is {{ item }}'
            loop:
              - zhangsan
              - lisi
              - wangwu
            register: result
      
          - name: show these user
            debug:
              var: result
      
       //测试是否执行play
      [root@localhost project]# ansible-playbook playbook.yaml -C
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [show some user] *****************************************************************************************************************************************************
      skipping: [client.example.com] => (item=zhangsan) 
      skipping: [client.example.com] => (item=lisi) 
      skipping: [client.example.com] => (item=wangwu) 
      
      TASK [show these user] 
      ............
      "item": "zhangsan",
                      "msg": "skipped, running in check mode",
                      "skipped": true
      ............
      "item": "lisi",
                      "msg": "skipped, running in check mode",
                      "skipped": true
      .............
      "item": "wangwu",
                      "msg": "skipped, running in check mode",
                      "skipped": true
      .............

    1️⃣: 在上面的例子中,results键包含一个列表。在下面,修改了playbook,使第二个任务迭代此列表

    • 演示实例:
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        tasks:
          - name: show some user
            shell: 'echo this user is {{ item }}'
            loop:
              - zhangsan
              - lisi
              - wangwu
            register: magic
      
          - name: show these user
            debug:
              msg: "{{ item.stdout }}"
            loop: "{{ magic['results'] }}"
      
       //执行play
      [root@localhost project]# ansible-playbook playbook.yaml
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [show some user] *****************************************************************************************************************************************************
      changed: [client.example.com] => (item=zhangsan)
      changed: [client.example.com] => (item=lisi)
      changed: [client.example.com] => (item=wangwu)
      
      TASK [show these user] ****************************************************************************************************************************************************
      ok: [client.example.com] => (item={'cmd': 'echo this user is zhangsan', 'stdout': 'this user is zhangsan', 'stderr': '', 'rc': 0, 'start': '2020-09-03 15:28:50.767109', 'end': '2020-09-03 15:28:50.774188', 'delta': '0:00:00.007079', 'changed': True, 'invocation': {'module_args': {'_raw_params': 'echo this user is zhangsan', '_uses_shell': True, 'warn': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['this user is zhangsan'], 'stderr_lines': [], 'failed': False, 'item': 'zhangsan', 'ansible_loop_var': 'item'}) => {
          "msg": "this user is zhangsan"
      }
      ok: [client.example.com] => (item={'cmd': 'echo this user is lisi', 'stdout': 'this user is lisi', 'stderr': '', 'rc': 0, 'start': '2020-09-03 15:28:51.542241', 'end': '2020-09-03 15:28:51.547953', 'delta': '0:00:00.005712', 'changed': True, 'invocation': {'module_args': {'_raw_params': 'echo this user is lisi', '_uses_shell': True, 'warn': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['this user is lisi'], 'stderr_lines': [], 'failed': False, 'item': 'lisi', 'ansible_loop_var': 'item'}) => {
          "msg": "this user is lisi"
      }
      ok: [client.example.com] => (item={'cmd': 'echo this user is wangwu', 'stdout': 'this user is wangwu', 'stderr': '', 'rc': 0, 'start': '2020-09-03 15:28:52.292883', 'end': '2020-09-03 15:28:52.298768', 'delta': '0:00:00.005885', 'changed': True, 'invocation': {'module_args': {'_raw_params': 'echo this user is wangwu', '_uses_shell': True, 'warn': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['this user is wangwu'], 'stderr_lines': [], 'failed': False, 'item': 'wangwu', 'ansible_loop_var': 'item'}) => {
          "msg": "this user is wangwu"
      }
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

    二、有条件的运行任务

    Ansible可使用conditionals在符合特定条件时执行任务或play。例如,可以利用一个条件在Ansible安装或配置服务前确定受管主机上的可用内存

     1、条件任务语法

    1️⃣:when语句用于有条件地运行任务;它取要测试的条件为值。如果条件满足,则运行任务。如果条件不满足,则跳过任务

    • 演示实例:
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        vars:
          package: True
        tasks:
          - name: install httpd
            yum:
              name: httpd
              state: installed
            when: package
      
       //测试执行play
      [root@localhost project]# ansible-playbook playbook.yaml 
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [install httpd] ******************************************************************************************************************************************************
      changed: [client.example.com]
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

    2️⃣:处理条件时可使用的一些运算示例

    操作示例
    等于(值为字符串) ansible_machine == "x86_64"
    等于(值为数字) max_memory == 512
    小于 min_memory < 128
    大于 min_memory > 256
    小于等于 min_memory <= 256
    大于等于 min_memory >= 512
    不等于 min_memory != 512
    变量存在 min_memory is defined
    变量不存在 min_memory is not defined
    布尔变量是True。1、True或yes的求值为True memory_available
    布尔变量是False。0、False或no的求值为False not memory_available
    第一个变量的值存在,作为第二个变量的列表中的值 ansible_distribution in supported_distros
    • 演示实例一:
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        vars:
          package: httpd
        tasks:
          - name: install {{ package }}
            yum:
              name: "{{ package }}"
              state: present
            when: package is defined
      
       //执行play
      [root@localhost project]# ansible-playbook playbook.yaml 
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [install httpd] ******************************************************************************************************************************************************
      changed: [client.example.com]
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    • 演示实例二:第一个变量的值存在(一般是事实),且作为第二个变量列表中的值
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        vars:
          version:
            - RedHat
            - CentOS
        tasks:
          - name: install httpd
            yum:
              name: httpd
              state: present
            when: ansible_facts['distribution'] in version     //ansible_facts['distribution']该变量的值与versionversion中的值匹配
      
       //执行play
      [root@localhost project]# ansible-playbook playbook.yaml 
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [install httpd] ******************************************************************************************************************************************************
      changed: [client.example.com]
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    • 演示实例三:(判断大小)
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        vars:
          number: 800
        tasks:
          - name: install httpd
            yum:
              name: httpd
              state: present
            when: number >= 800
      
       //执行play
      [root@localhost project]# ansible-playbook playbook.yaml 
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [install httpd] ******************************************************************************************************************************************************
      changed: [client.example.com]
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

    2、测试多个条件

    1️⃣:一个when语句可用于评估多个条件:使用andor关键字组合条件,并使用括号分组条件

    2️⃣:使用and语句运算时,两个条件必须为真,才能满足整个条件语句

    • 演示实例一:and 语句第一种写法
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        tasks:
          - name: install httpd
            yum:
              name: httpd
              state: present
            when: ansible_facts['distribution_version'] == "8.1" and ansible_facts['distribution'] == "RedHat"
      
       //执行play
      [root@localhost project]# ansible-playbook playbook.yaml 
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [install httpd] ******************************************************************************************************************************************************
      changed: [client.example.com]
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    • 演示实例二:and 语句第二种写法
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        tasks:
          - name: install httpd
            yum:
              name: httpd
              state: present
            when:
              - ansible_facts['distribution_version'] == "8.1" 
              - ansible_facts['distribution'] == "RedHat"
      
       //执行play
      [root@localhost project]# ansible-playbook playbook.yaml 
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [install httpd] ******************************************************************************************************************************************************
      changed: [client.example.com]
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
    • 演示实例三:and 语句第三中写法
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        tasks:
          - name: install httpd
            yum:
              name: httpd
              state: present
            when:
              ( ansible_facts['distribution_version'] == "8.1" )
              and
              ( ansible_facts['distribution'] == "RedHat" )
      
       //执行play
      [root@localhost project]# ansible-playbook playbook.yaml
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [install httpd] ******************************************************************************************************************************************************
      changed: [client.example.com]
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

    3️⃣:使用or语句时,其中任一条件为真时,就能满足条件语句

    • 演示实例一:or 语句第一种写法
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        tasks:
          - name: install httpd
            yum:
              name: httpd
              state: present
            when: ansible_facts['distribution'] == "RedHat" or ansible_facts['distribution_version'] == "7.9"
      
       //执行play
      [root@localhost project]# ansible-playbook playbook.yaml 
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [install httpd] ******************************************************************************************************************************************************
      changed: [client.example.com]
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
       //我当前使用的是RHEL8.1版本
    • 演示实例二:or 语句第二种写法
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        tasks:
          - name: install httpd
            yum:
              name: httpd
              state: present
            when: >               //这里可以加,也可以不加;>:是允许下面的变量可以换行写
              ( ansible_facts['distribution'] == "RedHat" )
              or 
              ( ansible_facts['distribution_version'] == "7.9 )"
      
       //执行play
      [root@localhost project]# ansible-playbook playbook.yaml 
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [install httpd] ******************************************************************************************************************************************************
      changed: [client.example.com]
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    • 演示实例三:or 语句的第三种写法(与and语句嵌套使用)
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        tasks:
          - name: install httpd
            yum:
              name: httpd
              state: present
            when:
              ( ansible_facts['distribution'] == "RedHat" and ansible_facts['kernel'] == "4.18.0-147.el8.x86_64"  )
              or 
              ( ansible_facts['distribution_version'] == "7.9" and ansible_facts['distribution_major_version'] == "7" )
      
       //执行play
      [root@localhost project]# ansible-playbook playbook.yaml 
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [install httpd] ******************************************************************************************************************************************************
      changed: [client.example.com]
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

    三、组合循环和有条件任务

     1、使用Loop和When组合使用

    • 演示实例:
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        tasks:
          - name: install httpd
            yum:
              name: httpd
              state: present
            loop: "{{ ansible_facts['mounts'] }}"
            when:
              - item.mount == "/"
              - item.size_available > 50000000000
      
       //执行paly
      [root@localhost project]# ansible-playbook playbook.yaml 
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [install httpd] ******************************************************************************************************************************************************
      changed: [client.example.com] => (item={'mount': '/', 'device': '/dev/mapper/rhel-root', 'fstype': 'xfs', 'options': 'rw,seclabel,relatime,attr2,inode64,noquota', 'size_total': 53660876800, 'size_available': 51805659136, 'block_size': 4096, 'block_total': 13100800, 'block_available': 12647866, 'block_used': 452934, 'inode_total': 26214400, 'inode_available': 26178405, 'inode_used': 35995, 'uuid': '6a525cf5-3f23-4639-81cb-04fcdb764eb6'})
      skipping: [client.example.com] => (item={'mount': '/home', 'device': '/dev/mapper/rhel-home', 'fstype': 'xfs', 'options': 'rw,seclabel,relatime,attr2,inode64,noquota', 'size_total': 28922376192, 'size_available': 28686655488, 'block_size': 4096, 'block_total': 7061127, 'block_available': 7003578, 'block_used': 57549, 'inode_total': 14129152, 'inode_available': 14129137, 'inode_used': 15, 'uuid': '2840f839-89b2-4717-b1d0-c74c46d05019'}) 
      skipping: [client.example.com] => (item={'mount': '/boot', 'device': '/dev/nvme0n1p1', 'fstype': 'xfs', 'options': 'rw,seclabel,relatime,attr2,inode64,noquota', 'size_total': 1063256064, 'size_available': 882565120, 'block_size': 4096, 'block_total': 259584, 'block_available': 215470, 'block_used': 44114, 'inode_total': 524288, 'inode_available': 523987, 'inode_used': 301, 'uuid': '234365dc-2262-452e-9cbb-a6acfde04385'}) 
      skipping: [client.example.com] => (item={'mount': '/mnt', 'device': '/dev/sr0', 'fstype': 'iso9660', 'options': 'ro,relatime,nojoliet,check=s,map=n,blocksize=2048', 'size_total': 7851202560, 'size_available': 0, 'block_size': 2048, 'block_total': 3833595, 'block_available': 0, 'block_used': 3833595, 'inode_total': 0, 'inode_available': 0, 'inode_used': 0, 'uuid': '2019-10-15-13-34-03-00'}) 
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

    2、使用Register和When组合使用

    • 演示实例:
       //查看playbook
      [root@localhost project]# cat playbook.yaml 
      ---
      - hosts: all
        tasks:
          - name: install httpd
            yum:
              name: httpd
              state: present
            ignore_errors: yes       //在运行时,如果出现错误且命令失败,将不会停止,继续执行其他的命令
            register: result       //将安装成功后的结果注册到result变量中
      
          - name: start httpd
            service:
              name: httpd
              state: started
            when: result.rc == 0    //在该变量中匹配到返回值rc=0执行该命令
      
       //执行play
      [root@localhost project]# ansible-playbook playbook.yaml 
      
      PLAY [all] ****************************************************************************************************************************************************************
      
      TASK [Gathering Facts] ****************************************************************************************************************************************************
      ok: [client.example.com]
      
      TASK [install httpd] ******************************************************************************************************************************************************
      changed: [client.example.com]
      
      TASK [start httpd] ********************************************************************************************************************************************************
      changed: [client.example.com]
      
      PLAY RECAP ****************************************************************************************************************************************************************
      client.example.com         : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

    下一篇实施处理程序

  • 相关阅读:
    06 is和==的区别 encode()编码 decode()解码
    05 dic的增删改查 字典的嵌套 考试题dic.get()的相关使用
    03 编码 int ,bool,str的常用操作 主要讲str
    01 基本数据类型 变量 if语句
    04 列表的增删改查 常用方法 元祖 range
    02 while循环 格式化输出 运算符
    多校2 Harmonious Army hdu6598 网络流
    P3159 [CQOI2012]交换棋子 网络流
    P2172 [国家集训队]部落战争 最大流
    P2402 奶牛隐藏 网络流
  • 原文地址:https://www.cnblogs.com/itwangqiang/p/13606614.html
Copyright © 2011-2022 走看看