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 

    下一篇实施处理程序

  • 相关阅读:
    Linux(Centos7)yum安装最新redis
    refresh table tablename ;MSCK REPAIR TABLE table_name;
    整个shuffle的流程图
    Vim简明教程
    centos vim 7.3 升级 + vim 简单配置文件
    Python——可变类型与不可变类型(即为什么函数默认参数要用元组而非列表)
    python——修饰符
    转——《将人性置之死地而后生》刘夙
    各学科领域入门书籍推荐
    python——关于Python Profilers性能分析器
  • 原文地址:https://www.cnblogs.com/itwangqiang/p/13606614.html
Copyright © 2011-2022 走看看