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: [  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
[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可以更好的按照运维人员的意愿来对远程节点执行特定的操作。

转载于:https://www.cnblogs.com/gzxbkk/p/7608055.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值