设为首页 收藏本站
查看: 1891|回复: 0

[经验分享] 自动化运维工具Ansible之Playbooks的when语句

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-8-6 10:55:32 | 显示全部楼层 |阅读模式
在使用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: [ 0, 2, 4, 6, 8, 10 ]
          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
[iyunv@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
    [iyunv@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
[iyunv@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
    [iyunv@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
    ###远程节点
    [iyunv@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可以更好的按照运维人员的意愿来对远程节点执行特定的操作。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-94716-1-1.html 上篇帖子: 自动化运维工具Ansible之Playbooks循环语句 下篇帖子: 自动化运维工具ansible
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表