ansible的条件判断、迭代执行、tags

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介:

在ansible中支持条件判断,这使我们操作更加灵活

使用when进行条件测试

示例1:

将 testservers 组中的其中一台主机上的 httpd 服务卸载掉,另外主机不卸载

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
37
38
39
[root@node1 ansible] # ansible testservers -m shell -a 'rpm -q httpd'
192.168.100.131 | success | rc=0 >>
httpd-2.2.15-29.el6.centos.x86_64
 
192.168.100.132 | success | rc=0 >>
httpd-2.2.15-47.el6.centos.3.x86_64
 
[root@node1 ansible] # cat http.yml 
- hosts: testservers
   remote_user: root
   tasks:
   - name: uninstall httpd service
     yum: name=httpd state=absent
     when: ansible_nodename ==  "v2.lansgg.com"
     
[root@node1 ansible] # ansible-playbook http.yml 
 
PLAY [testservers] ************************************************************ 
 
GATHERING FACTS *************************************************************** 
ok: [192.168.100.131]
ok: [192.168.100.132]
 
TASK: [uninstall httpd service] *********************************************** 
skipping: [192.168.100.132]
changed: [192.168.100.131]
 
PLAY RECAP ******************************************************************** 
192.168.100.131            : ok=2    changed=1    unreachable=0    failed=0   
192.168.100.132            : ok=1    changed=0    unreachable=0    failed=0   
 
[root@node1 ansible] # ansible testservers -m shell -a 'rpm -q httpd'
192.168.100.132 | success | rc=0 >>
httpd-2.2.15-47.el6.centos.3.x86_64
 
192.168.100.131 | FAILED | rc=1 >>
package httpd is not installed
 
[root@node1 ansible] #

示例2:

也可以使用 or 进行 或 判断,这里将组内的两台主机的 httpd 服务都卸载,

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
37
38
39
[root@node1 ansible] # ansible testservers -m shell -a 'rpm -q httpd'
192.168.100.132 | success | rc=0 >>
httpd-2.2.15-47.el6.centos.3.x86_64
 
192.168.100.131 | success | rc=0 >>
httpd-2.2.15-29.el6.centos.x86_64
 
[root@node1 ansible] # cat http.yml 
- hosts: testservers
   remote_user: root
   tasks:
   - name: uninstall httpd service
     yum: name=httpd state=absent
     when: (ansible_nodename ==  "v2.lansgg.com" ) or ( ansible_all_ipv4_addresses[0] ==  '192.168.100.132' )
     
[root@node1 ansible] # ansible-playbook http.yml 
 
PLAY [testservers] ************************************************************ 
 
GATHERING FACTS *************************************************************** 
ok: [192.168.100.131]
ok: [192.168.100.132]
 
TASK: [uninstall httpd service] *********************************************** 
changed: [192.168.100.131]
changed: [192.168.100.132]
 
PLAY RECAP ******************************************************************** 
192.168.100.131            : ok=2    changed=1    unreachable=0    failed=0   
192.168.100.132            : ok=2    changed=1    unreachable=0    failed=0   
 
[root@node1 ansible] # ansible testservers -m shell -a 'rpm -q httpd'
192.168.100.131 | FAILED | rc=1 >>
package httpd is not installed
 
192.168.100.132 | FAILED | rc=1 >>
package httpd is not installed
 
[root@node1 ansible] #

保存结果

几乎所有的模块都是会outputs一些东西,甚至debug模块也会.大多数我们会使用的结果变量是changed.这个changed变量决定 了是否要直接handlers和输出的颜色是什么.然而,结果变量还有其他的用途,譬如我需要保存我的结果变量,然后在我们的playbook的其他地方使用.

示例:

分别在一台主机上创建一个目录,另外主机不存在此目录,根据此目录的存在情况,做出不同操作

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
[root@node1 ansible] # ansible testservers -m shell -a 'ls -l /nono'
192.168.100.131 | success | rc=0 >>
total 0
 
192.168.100.132 | FAILED | rc=2 >>
ls : cannot access  /nono : No such  file  or directory
 
[root@node1 ansible] # cat re.yml 
- hosts: testservers
   remote_user: root
   tasks:
    - name:  ls  /nono
      shell:  /bin/ls  /nono
      register: result
      ignore_errors: True
    - name:  test  result
      copy: content= "ok"  dest= /tmp/test
      when: result.rc == 0
    - name:  test  no result
      copy: content= "no ok"  dest= /tmp/test
      when: result.rc != 0
      
[root@node1 ansible] # ansible-playbook re.yml 
 
PLAY [testservers] ************************************************************ 
 
GATHERING FACTS *************************************************************** 
ok: [192.168.100.131]
ok: [192.168.100.132]
 
TASK: [ ls  /nono ] ************************************************************** 
changed: [192.168.100.131]
failed: [192.168.100.132] => { "changed" true "cmd" "/bin/ls /nono" "delta" "0:00:00.004437" "end" "2016-03-02 12:56:55.409736" "rc" : 2,  "start" "2016-03-02 12:56:55.405299" "warnings" : []}
stderr:  /bin/ls : cannot access  /nono : No such  file  or directory
...ignoring
 
TASK: [ test  result] *********************************************************** 
skipping: [192.168.100.132]
ok: [192.168.100.131]
 
TASK: [ test  no result] ******************************************************** 
skipping: [192.168.100.131]
ok: [192.168.100.132]
 
PLAY RECAP ******************************************************************** 
192.168.100.131            : ok=3    changed=1    unreachable=0    failed=0   
192.168.100.132            : ok=3    changed=1    unreachable=0    failed=0   
 
[root@node1 ansible] # ansible testservers -m shell -a 'ls -l /tmp/test'
192.168.100.131 | success | rc=0 >>
-rw-r--r-- 1 root root 2 Mar  2 12:55  /tmp/test
 
192.168.100.132 | success | rc=0 >>
-rw-r--r-- 1 root root 5 Mar  2 12:55  /tmp/test
 
[root@node1 ansible] # ansible testservers -m shell -a 'cat /tmp/test'
192.168.100.131 | success | rc=0 >>
ok
 
192.168.100.132 | success | rc=0 >>
no ok
 
[root@node1 ansible] #

ansible 中的循环操作:

当有需要重复性执行的任务时,可以使用迭代机制,格式为:将需要迭代的内容定义为Item变量引用,并通过with_items 语句来指明迭代的元素列表即可

示例1、

在 testservers 组中一台主机上安装lamp

1
2
3
4
5
6
7
8
9
10
11
12
[root@node1 ansible] # cat item.yml 
- hosts: testservers
   remote_user: root
   tasks:
    - name: yum  install  lamp
      yum: name=`item` state=present
      with_items:
          - httpd
          - mysql-server
          - php
      when: (ansible_nodename ==  "v2.lansgg.com" )
[root@node1 ansible] #

上面的语句等同于:

1
2
3
4
5
6
7
8
9
10
11
12
- hosts: testservers
   remote_user: root
   tasks:
   - name:  install  httpd
     yum: name=httpd state=present
     when: (ansible_nodename ==  "v2.lansgg.com" )
   - name:  install  mysql-server
     yum: name=mysql-server state=present
     when: (ansible_nodename ==  "v2.lansgg.com" )
   - name:  install  php
     yum: name=php state=present
     when: (ansible_nodename ==  "v2.lansgg.com" )

上面的语句 hash 方式编写也可以,等同于如下:

1
2
3
4
5
6
7
8
9
10
- hosts: testservers
   remote_user: root
   tasks:
    - name:  install  httpd
      yum: name=`item`.`name` state=`item`.`state`
      when: (ansible_nodename ==  "v2.lansgg.com" )
      with_items:
       - {name:  'httpd' , state:  'present' }
       - {name:  'mysql-server' , state:  'present' }
       - {name:  'php' , state:  'present' }

开始执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@node1 ansible] # ansible-playbook item.yml 
 
PLAY [testservers] ************************************************************ 
 
GATHERING FACTS *************************************************************** 
ok: [192.168.100.131]
ok: [192.168.100.132]
 
TASK: [yum  install  lamp] ****************************************************** 
skipping: [192.168.100.132]
changed: [192.168.100.131] => (item=httpd,mysql-server,php)
 
PLAY RECAP ******************************************************************** 
192.168.100.131            : ok=2    changed=1    unreachable=0    failed=0   
192.168.100.132            : ok=1    changed=0    unreachable=0    failed=0

ansible 的 tags 功能

ansible的playbool中有一个关键字,叫做tags。tags是什么?就是打标签。tags可以和一个play(就是很多个task)或者一 个task进行捆绑。然后,ansible-playbook提供了“--skip-tags”和“--tags” 来指明是跳过特定的tags还是执行特定的tags。

示例 1、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@node1 ansible] # cat tag.yml
- hosts: testservers
   remote_user: root
   tasks:
    - name:  echo  A1
      command echo  A1
      tags:
       - A1
    - name:  echo  A2
      command echo  A2
      tags:
       - A2
    - name:  echo  A3
      command echo  A3
      tags:
       - A3

当执行  ansible-playbook tag.yml --tags="A1,A3  ,则只会执行A1和A3的echo命令。

如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@node1 ansible] # ansible-playbook tag.yml --tags="A1,A3"
 
PLAY [testservers] ************************************************************ 
 
GATHERING FACTS *************************************************************** 
ok: [192.168.100.131]
ok: [192.168.100.132]
 
TASK: [ echo  A1] *************************************************************** 
changed: [192.168.100.131]
changed: [192.168.100.132]
 
TASK: [ echo  A3] *************************************************************** 
changed: [192.168.100.131]
changed: [192.168.100.132]
 
PLAY RECAP ******************************************************************** 
192.168.100.131            : ok=3    changed=2    unreachable=0    failed=0   
192.168.100.132            : ok=3    changed=2    unreachable=0    failed=0

当执行  ansible-playbook tag.yml --skip-tags="A2" ,同样只会执行 A1和A3的echo命令。

如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@node1 ansible] # ansible-playbook tag.yml --skip-tags="A2"
 
PLAY [testservers] ************************************************************ 
 
GATHERING FACTS *************************************************************** 
ok: [192.168.100.131]
ok: [192.168.100.132]
 
TASK: [ echo  A1] *************************************************************** 
changed: [192.168.100.132]
changed: [192.168.100.131]
 
TASK: [ echo  A3] *************************************************************** 
changed: [192.168.100.131]
changed: [192.168.100.132]
 
PLAY RECAP ******************************************************************** 
192.168.100.131            : ok=3    changed=2    unreachable=0    failed=0   
192.168.100.132            : ok=3    changed=2    unreachable=0    failed=0

示例 2 、

我们安装 httpd 服务的流程为 安装服务、copy文件、启动服务、如果配置有变化就重启服务,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@node1 ansible] # cat http.yml 
- hosts: testservers
   remote_user: root
   tasks:
   - name:  install  httpd package
     yum: name=httpd state=present
   - name: start httpd service
     service: name=httpd enabled= true  state=started
   - name: copy config  file
     copy: src=httpd.conf dest= /etc/httpd/conf/httpd .conf
     notify:
        restart httpd service
     tags:
      - modify
   handlers:
    - name: restart httpd service
      service: name=httpd state=restarted
[root@node1 ansible] #

当我们的配置文件有修改的时候,可以指定tags,这样就会只执行copy config file 任务,前面就不会再执行

结果如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@node1 ansible] # ansible-playbook http.yml --tags=modify
 
PLAY [testservers] ************************************************************ 
 
GATHERING FACTS *************************************************************** 
ok: [192.168.100.131]
ok: [192.168.100.132]
 
TASK: [copy config  file ] ****************************************************** 
changed: [192.168.100.131]
changed: [192.168.100.132]
 
NOTIFIED: [restart httpd service] ********************************************* 
changed: [192.168.100.131]
changed: [192.168.100.132]
 
PLAY RECAP ******************************************************************** 
192.168.100.131            : ok=3    changed=2    unreachable=0    failed=0   
192.168.100.132            : ok=3    changed=2    unreachable=0    failed=0

特殊 tags

系统中内置的特殊tags:

  always、tagged、untagged、all 是四个系统内置的tag,有自己的特殊意义

  always: 指定这个tag 后,task任务将永远被执行,而不用去考虑是否使用了--skip-tags标记

  tagged: 当 --tags 指定为它时,则只要有tags标记的task都将被执行,--skip-tags效果相反

  untagged: 当 --tags 指定为它时,则所有没有tag标记的task 将被执行,--skip-tags效果相反

  all: 这个标记无需指定,ansible-playbook 默认执行的时候就是这个标记.所有task都被执行


本文转自 西索oO 51CTO博客,原文链接:http://blog.51cto.com/lansgg/1746825


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
移动开发 前端开发 JavaScript
一文讲透支付宝沙箱的基本应用
沙箱环境是支付宝开放平台为开发者提供的与生产环境完全隔离的联调测试环境,开发者在沙箱环境中完成的接口调用不会对生产环境中的数据造成任何影响。沙箱为开放的产品提供有限功能范围的支持,可以覆盖产品的绝大部分核心链路和对接逻辑,便于开发者快速学习/尝试/开发/调试。沙箱环境会自动完成或忽略一些场景的业务门槛,例如:开发者无需等待产品开通,即可直接在沙箱环境调用接口,使得开发集成工作可以与业务流程并行,从而提高项目整体的交付效率。......
2424 0
一文讲透支付宝沙箱的基本应用
|
JSON 中间件 Go
Golang高性能日志库zap + lumberjack 日志切割组件详解
Golang高性能日志库zap + lumberjack 日志切割组件详解
Golang高性能日志库zap + lumberjack 日志切割组件详解
|
6月前
简约的域名主页HTML源码带暗黑模式
简约的域名主页HTML源码带暗黑模式
162 17
|
算法 搜索推荐 Java
解析01背包问题及其在动态规划中的应用
解析01背包问题及其在动态规划中的应用
|
资源调度 JavaScript 数据处理
vue3 element组件上传图片
vue3 element组件上传图片
792 0
|
监控 小程序 开发者
【小程序质量提优解决方案】(一)页面不存在
【小程序质量提优解决方案】(一)页面不存在
456 11
|
搜索推荐 定位技术 数据安全/隐私保护
方便、免费的PDF在线处理网站汇总:PDF合并、文字编辑、页面提取与删除、格式转换…
方便、免费的PDF在线处理网站汇总:PDF合并、文字编辑、页面提取与删除、格式转换…
470 1
|
安全 网络架构
外部网关协议详解
外部网关协议详解
652 0
复现sci顶刊中的画中画(局部细节放大)
复现sci顶刊中的画中画(局部细节放大)
1273 0
|
机器学习/深度学习 数据采集 数据建模
Python机器学习数据建模与分析——Numpy和Pandas综合应用案例:空气质量监测数据的预处理和基本分析
本篇文章主要以北京市空气质量监测数据为例子,聚集数据建模中的数据预处理和基本分析环节,说明Numpy和Pandas的数据读取、数据分组、数据重编码、分类汇总等数据加工处理功能。同时在实现案例的过程中对用到的Numpy和Pandas相关函数进行讲解。
903 0
Python机器学习数据建模与分析——Numpy和Pandas综合应用案例:空气质量监测数据的预处理和基本分析