• Ansible之Playbooks的when语句


    在使用ansible做自动化运维的时候,大多数情况下都执行某些任务的时候都需要依赖某个变量的值或者是上一个任务的执行结果。如,根据facts信息中的系统版本相关的信息来确定使用哪种包管理器安装软件。Ansible提供when语句,可以控制任务的执行流程。

    一个很简单的when语句的例子:

    1

    2

    3

    4

        tasks:

          - name: "shutdown Debian flavored systems"

            command: /sbin/shutdown -t now

            when: ansible_os_family == "Debian

    表示当节点主机系统为Debian的时候,执行关机操作。

    在符合语句中也可以使用小括号:

    1

    2

    3

    4

    5

        tasks:

          - name: "shutdown CentOS 6 and 7 systems"

            command: /sbin/shutdown -t now

            when: ansible_distribution == "CentOS" and

                  (ansible_distribution_major_version == "6" or ansible_distribution_major_version == "7")

     在`when`语句中也可以使用过滤器。如,我们想跳过一个语句执行中的错误,但是后续的任务的执行需要由该任务是否成功执行决定:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

        tasks:

          - command: /bin/false

            register: result

            ignore_errors: True

          - command: /bin/something

            when: result|failed

          - command: /bin/something_else

            when: result|success

          - command: /bin/still/something_else

            when: result|skipped

    有时候需要将一个字符串的变量转换为整数来进行数字比较:

    1

    2

    3

        tasks:

          - shell: echo "only on Red Hat 6, derivatives, and later"

            when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6

    在playbooks和inventory中定义的变量都可以使用,如,需要根据一个变量的bool值决定是否执行该任务:

    1

    2

        vars:

          epic: true

     条件语句:
     

    1

    2

    3

        tasks:

            - shell: echo "This certainly is epic!"

              when: epic



    或:
     

    1

    2

    3

        tasks:

            - shell: echo "This certainly isn't epic!"

              when: not epic

     如果引用的变量没有被定义,使用Jinja2的`defined`测试,可以跳过或者是抛出错误:

    1

    2

    3

    4

    5

    6

        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 not defined

     当`when`和`with_items`一起使用的时候,每个项都会单独被`when`语句处理:

    1

    2

    3

    4

        tasks:

            - command: echo {{ item }}

              with_items: [ 0246810 ]

              when: item > 5

    示例:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    [root@web1 ~]# cat /etc/ansible/when.yml

        ---

        - hosts: webservers

          remote_user: root

          tasks:

           - command: echo {{ item }}

             with_items: [ 1,2,3,4,5,6,8,10]

             when: item > 5

        [root@web1 ~]# ansible-playbook /etc/ansible/when.yml

         

        PLAY [webservers] ************************************************************* 

         

        GATHERING FACTS *************************************************************** 

        ok: [192.168.1.65]

         

        TASK: [command echo {{ item }}] *********************************************** 

        skipping: [192.168.1.65=> (item=1)

        skipping: [192.168.1.65=> (item=2)

        skipping: [192.168.1.65=> (item=3)

        skipping: [192.168.1.65=> (item=4)

        skipping: [192.168.1.65=> (item=5)

        changed: [192.168.1.65=> (item=6)

        changed: [192.168.1.65=> (item=8)

        changed: [192.168.1.65=> (item=10)

         

        PLAY RECAP ******************************************************************** 

        192.168.1.65               : ok=2    changed=1    unreachable=0    failed=0

    如果需要的话,也可以返回自定义的facts给控制节点。返回的自定义的facts变量也可以用作下个任务的执行条件:

    1

    2

    3

    4

    5

        tasks:

            - name: gather site specific fact data

              action: site_facts

            - command: /usr/bin/thingy

              when: my_custom_fact_just_retrieved_from_the_remote_system == '1234'

    在角色和包含中使用when

    如果有多个任务都需要使用同一个条件语句控制。可以将这些任务打包到一个单独的任务文件中,然后使用`include`包含和`when`条件语句。条件语句只对包含任务文件起作用,对包含playbook文件不起作用。指定的条件语句会作用到所包含的每个任务上:

    1

    2

     - include: tasks/sometasks.yml

          when: "'reticulating splines' in output"

    角色中使用when

    1

    2

    3

      - hosts: webservers

          roles:

             - { role: debian_stock_config, when: ansible_os_family == 'Debian' }

    注册变量

    在playbook中将某个命令运行的结果保存起来,提供给后续任务使用。如,通过command模块来判断远程节点上某个文件是否存在或者通过执行某个命令的获取其返回结果,并保存起来,下个任务根据获取的变量值来决定执行的具体操作。

    register关键字可以将任务执行结果保存到一个变量中,该变量可以在模板或者playbooks文件中使用:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

     - name: test play

          hosts: all

         

          tasks:

         

              - shell: cat /etc/motd

                register: motd_contents

         

              - shell: echo "motd contains the word hi"

                when: motd_contents.stdout.find('hi') != -1

     上边中的例子中,通过注册变量访问返回的内容,`stdout`里面保存了命令的标准输出内容。注册变量还可以使用在`with_items`中,如果其保存的内容可以转换为列表,或者内容本身就是个列表。如果命令的输出本身就是列表,可以通过`stdout_lines`访问:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

     - name: registered variable usage as a with_items list

          hosts: all

         

          tasks:

         

              - name: retrieve the list of home directories

                command: ls /home

                register: home_dirs

         

              - name: add home dirs to the backup spooler

                file: path=/mnt/bkspool/{{ item }} src=/home/{{ item }} state=link

                with_items: home_dirs.stdout_lines

                # same as with_items: home_dirs.stdout.split()

    示例:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    [root@web1 ~]# cat /etc/ansible/rewith.yml

        ---

        - hosts: webservers

          remote_user: root

          tasks:

           - name: list of home dir

             command: ls /home

             register: home_dirs

           - name: add home dirs to the backup

             file: path=/tmp/back/{{ item }} src=/home/{{ item }} state=link

             with_items: home_dirs.stdout_lines

        [root@web1 ~]# ansible-playbook /etc/ansible/rewith.yml

         

        PLAY [webservers] ************************************************************* 

         

        GATHERING FACTS *************************************************************** 

        ok: [192.168.1.65]

         

        TASK: [list of home dir****************************************************** 

        changed: [192.168.1.65]

         

        TASK: [add home dirs to the backup] ******************************************* 

        changed: [192.168.1.65=> (item=1.sql)

        changed: [192.168.1.65=> (item=1youku.sql)

        changed: [192.168.1.65=> (item=liuzhenwei)

        changed: [192.168.1.65=> (item=tom)

         

        PLAY RECAP ******************************************************************** 

        192.168.1.65               : ok=3    changed=2    unreachable=0    failed=0 

        ###远程节点

        [root@db2 ~]# ll /tmp/back

        total 0

        lrwxrwxrwx. 1 root root 11 Aug  4 14:37 1.sql -/home/1.sql

        lrwxrwxrwx. 1 root root 16 Aug  4 14:37 1youku.sql -/home/1youku.sql

        lrwxrwxrwx. 1 root root 16 Aug  4 14:37 liuzhenwei -/home/liuzhenwei

        lrwxrwxrwx. 1 root root  9 Aug  4 14:37 tom -/home/tom

    在ansible中when语句的使用还是比较多的,它可以用来控制playbooks中任务的执行流程。类似于程序中的条件语句一样,使得ansible可以更好的按照运维人员的意愿来对远程节点执行特定的操作。

  • 相关阅读:
    重生奇迹MU游戏上格斗家挂机小技巧
    【Terraform】Terraform自动创建云服务器脚本
    Halcon · 曲线宽度检测算法总结
    ios-mfi_蓝牙部分翻译
    Python3 JSON 数据解析
    MIT 6.5840 Raft Implementation(2A, Leader Election)
    四川水泥杂志四川水泥杂志社四川水泥编辑部2022年第11期目录
    Hugging “Hugging Face“
    苏州科技大学、和数联合获得国家知识产权局颁发的3项发明专利证书
    RK3588 rtc-hym8563设备开发
  • 原文地址:https://blog.csdn.net/rqaz123/article/details/126380253