ansible基础-task控制
1. 前言
很多情况下,一个play是否执行会依赖于某个(些)变量的值,这个变量可以来自自定义变量、facts,甚至是另一个task的执行结果。
ansible通过变量判定task是否执行,我们称之为task控制。
在我看来,ansible的控制语句带来的最大的好处就是使部署代码更加健壮,举几个例子:
- 利用「ansible_os_family」变量使部署代码支持更多版本的操作系统
- 避免很多冗余无用的代码执行,提高代码执行效率
- 避免很多task意外的执行失败
- 使playbook满足幂等性
2. when语句
ansible使用最频繁的task控制语句就是「when」语句。
when语句可以在task中直接使用,也可以与include*、import*、roles、vars_files、incloud_vars等引入语句搭配使用。执行结果也比较通俗易懂,前者用来判断task是否执行,后者用来判断task是否引用。
when语句引用变量时不用加「{{}}」。在when语句中,ansible将不带引号的字符串认定为变量,所以如果使用字符串记得加单(双)引号。
对不同数据类型的判断可以使用不同的条件语句:
使用「==」:
tasks:
- name: "shut down Debian flavored systems"
command: /sbin/shutdown -t now
when: ansible_facts['os_family'] == "Debian"
使用「is」:
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 undefined - command: /bin/something
when: result is failed # In older versions of ansible use ``success``, now both are valid but succeeded uses the correct tense.
- command: /bin/something_else
when: result is succeeded - command: /bin/still/something_else
when: result is skipped
使用「in」:
when: "'reticulating splines' in output"
使用运算符(记得使用「int」将参数转为整数类型):
tasks:
- shell: echo "only on Red Hat 6, derivatives, and later"
when: ansible_facts['lsb']['major_release']|int >=
直接判断变量的True/False:
tasks:
- shell: echo "This certainly is epic!"
when: epic
- shell: echo "This certainly isn't epic!"
when: not epic
多个条件判断语句结合:
tasks:
- name: "shut down CentOS 6 and Debian 7 systems"
command: /sbin/shutdown -t now
when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "") or
(ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "")
when语句的参数也支持列表,等价于「and」:
tasks:
- name: "shut down CentOS 6 systems"
command: /sbin/shutdown -t now
when:
- ansible_facts['distribution'] == "CentOS"
- ansible_facts['distribution_major_version'] == ""
3 与引用相关的控制语句
3.1 条件导入play
上面说到when语句可以控制task是否被引用,例如当变量「output」包含字符串「reticulating splines」时再导入playbook「sometasks.yml」:
- import_tasks: tasks/sometasks.yml
when: "'reticulating splines' in output"
其他的导入语句import_playbook;include_tasks;import_role;include_role;roles等语句使用方法也类似上面的示例。
3.2 条件导入变量文件
同样,当task中使用「include_vars」语句导入变量文件时,也可以控制其导入,格式与导入play类似,这里就不举例了。
4 与register相关的控制语句
比较特殊的,我们可以基于一个task的执行结果来判断某个task是否执行,此时就用到了「register」语句。这里列举一个我在部署openshift时的例子:
遇到的问题:
部署harbor时,我想用「docker network connect」命令将harbor_harbor和ldapserver这两个容器网络打通,但是发现如果这两个容器是已经关联的状态,再次执行playbook时抛报错「Error response from daemon: service endpoint with name ldapserver already exists」这样就不满足ansible的幂等性。
解决办法:
第一个task是查询harbor_harbor的网络连接信息,并将其注册为一个变量「harbor_conn_info」:
- name: Get network harbor_harbor connection information
shell: >
/usr/bin/docker network inspect harbor_harbor
register: harbor_conn_info
上面示例中,变量「harbor_conn_info」是「/usr/bin/docker network inspect harbor_harbor」命令的执行结果,ansible从执行结果中查找「ldapserver」字符串,如果未查到(即find函数结果返回值为-1)则执行「docker network connect」命令。
通过这个例子,说明ansible的控制语句能够使部署代码满足最基本幂等性要求,也能使代码更加健壮。
5 基于变量的控制语句
基于变量的控制语句是另外一种task控制方式,不需要「when」语句,例如:
---
- hosts: all
remote_user: root
vars_files:
- "vars/common.yml"
- [ "vars/{{ ansible_facts['os_family'] }}.yml", "vars/os_defaults.yml" ]
tasks:
- name: make sure apache is started
service: name={{ apache }} state=started
6 本节应该掌握的技能
- 掌握task控制的作用以及带来的好处
- 会在 playbook中使用when语句
- 掌握register+when的配合使用
7 参考链接
- https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html
欢迎大家关注我的公众号:

ansible基础-task控制的更多相关文章
- ansible基础-理解篇
1. 介绍 要说现在的部署工具,ansible可以说家喻户晓了. ansible是一个开源软件,用于软件供应.配置管理.应用部署.ansible可以通过SSH.remote PowerShell.其他 ...
- 4.Ansible Task控制
1.tag标签(调试) --skip-tags install_nfs 跳过此标签 -t 指定标签名 [root@manager tasks]# cat task_nfs.yml - hosts: w ...
- ansible基础-优化
简介 当管理集群达到一定规模时,ansible达到性能瓶颈是难以避免的,此时我们可以通过一定手段提高ansible的执行效率和性能. 笔者虽未管理过超大规模服务器,但也通过查找资料和咨询大神了解了一些 ...
- ansible基础-playbook剧本的使用
ansible基础-playbook剧本的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.YAML概述 1>.YAML的诞生 YAML是一个可读性高,用来表达数据序 ...
- ansible基础-安装与配置
一 安装 1.1 ansible架构 ansible是一个非常简单的自动化部署项目,由python编写并且开源.用于提供自动化云配置.配置文件管理.应用部署.服务编排和很多其他的IT自动化需求. an ...
- ansible基础-Jinja2模版 | 过滤器
Jinja2模版介绍 注:本文demo使用ansible2.7稳定版 在ansible基础-变量的「8.2 模版使用变量」章节中关于模版与变量也有所提及,有兴趣的同学可以去回顾一下. ansible通 ...
- ansible基础-roles
一 简介 注:本文demo使用ansible2.7稳定版 在我看来,role是task文件.变量文件.handlers文件的集合体,这个集合体的显著特点是:可移植性和可重复执行性. 实践中,通常我们以 ...
- ansible基础-playbooks
1. playbooks介绍 如果说ansible的modules是工具,inventory配置文件是原材料,那么playbook就是一封说明书,这里会记录任务是如何如何执行的,当然如果你愿意,这里也 ...
- ansible基础-ansible角色的使用
ansible基础-ansible角色的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们建议把多个节点都会用到的功能将其定义模块,然后谁要用到该模块就直接调用即可!而在a ...
随机推荐
- JavaScript设计模式 Item 5 --链式调用
1.什么是链式调用 这个很容易理解,例如: $(this).setStyle('color', 'red').show(); 一般的函数调用和链式调用的区别:调用完方法后,return this返回当 ...
- MyBatis 中@param 的用法
示例: 接口方法 public List<Teacher> selectTeacher(@Param(value="id") String id,@Param(valu ...
- bzoj5249 [2018多省省队联测]IIIDX
转化一下问题变成给定一棵树,一个序列,求父亲的权值小于子树的最大方案. 直接贪心会在有重复权值时出现错误,我们考虑用线段树优化贪心. 将序列从小到大排序,线段树上每个点记录他和他右边当前还可用的权值, ...
- BZOJ3252: 攻略 可并堆
网上有很多人说用dfs序+线段树做...其实stl的堆可以...可并堆可以...很多奇奇怪怪的东西都能做... 可并堆比较好想...也比较好写... 分析: 首先,这是一个网络流做不了的题...数据太 ...
- Linux 下配置Nginx,MySql,php-fpm开机启动
一. Nginx 开机启动 1.在/etc/init.d/目录下创建脚本 vim /etc/init.d/nginx 2.编写脚本内容 (将以下复制进去相应改动安装路径) #!/bin/bash # ...
- i春秋——Misc之百度杯
今天心里很是不开森,想想往日何必那么努力呢?不如你的比比皆是,可是人家就是因为有关系,你又能怎样呢? 你所有应该有的都被打翻了,别灰心,至少你曾经努力过! 愿我未来的学弟学妹们都能一直开开心心的过好每 ...
- JAVAEE——SpringMVC第一天:介绍、入门程序、架构讲解、SpringMVC整合MyBatis、参数绑定、SpringMVC和Struts2的区别
1. 学习计划 第一天 1.SpringMVC介绍 2.入门程序 3.SpringMVC架构讲解 a) 框架结构 b) 组件说明 4.SpringMVC整合MyBatis 5.参数绑定 a) Sp ...
- 《HelloGitHub》第 26 期
公告 五月初 hellogithub.com 网站做了优化和试错.因为我个人能力原因,导致这段时间网站出现了间断性不能访问,现在问题已经修复.多谢大家的支持.理解和反馈. 本期新增了"星图& ...
- ASP.NET Core的实时库: SignalR简介及使用
大纲 本系列会分为2-3篇文章. 第一篇介绍了SignalR的预备知识和原理 本文介绍SignalR以及ASP.NET Core里使用SignalR. 本文的内容: 介绍SignalR 在ASP.NE ...
- MySQL · 引擎特性 · 临时表那些事儿
前言 相比于普通的用户数据表,MySQL/InnoDB中的临时表,大家应该会陌生很多.再加上不同的临时表创建的时机和创建的位置都不固定,这也进一步加大神秘感.最让人捉摸不透的是,临时表很多时候会先创建 ...