Ansible Playbook Conditionals
通常,play的结果可能取决于变量的值,facts(有关远程系统的知识)或先前的任务结果。 在某些情况下,变量的值可能取决于其他变量。 此外,可以创建其他组,以根据主机是否与其他条件匹配来管理主机。 在Ansible中有许多控制执行流程的选项。 支持条件的更多示例可以在这里找到: http : //jinja.pocoo.org/docs/dev/templates/#comparisons
When 语句
有时您会想要跳过特定主机上的特定步骤。 如果操作系统是特定版本,这可能是一个简单的方法,如果没有安装某个包,或者如果文件系统正在充满,可能会执行一些清理步骤。
这在使用when子句时很容易做到,它包含一个没有双大括号的原始Jinja2表达式(见变量 )。 其实很简单:
tasks:
- name: "shut down Debian flavored systems"
command: /sbin/shutdown -t now
when: ansible_os_family == "Debian"
# note that Ansible facts and vars like ansible_os_family can be used
# directly in conditionals without double curly braces 您也可以使用括号来分组条件:
tasks:
- name: "shut down CentOS 6 and Debian 7 systems"
command: /sbin/shutdown -t now
when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or
(ansible_distribution == "Debian" and ansible_distribution_major_version == "7")
所有需要为真的多个条件(逻辑“和”)也可以指定为列表:
asks:
- name: "shut down CentOS 6 systems"
command: /sbin/shutdown -t now
when:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version == "6" 一些Jinja2“过滤器”也可以在语句中使用,其中一些是唯一的,由Ansible提供。 假设我们想忽略一个语句的错误,然后决定根据成功或失败有条件地做某些事情:
tasks:
- command: /bin/false
register: result
ignore_errors: True - command: /bin/something
when: result|failed # In older versions of ansible use |success, now both are valid but succeeded uses the correct tense.
- command: /bin/something_else
when: result|succeeded - command: /bin/still/something_else
when: result|skipped 请注意,这是“register”声明的一点点预示。 我们稍后会在本章中讨论。
提醒您,要查看特定系统上有哪些facts,您可以执行以下操作:
ansible hostname.example.com -m setup 提示:有时您会收到一个字符串的变量,您将需要对其进行数学运算比较。 你可以这样做:
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中定义的变量。 一个例子可能是基于一个变量的布尔值执行一个任务:
vars:
epic: true 那么条件执行可能如下所示:
tasks:
- shell: echo "This certainly is epic!"
when: epic
要么:
tasks:
- shell: echo "This certainly isn't epic!"
when: not epic 如果未设置必需变量,则可以使用Jinja2 定义的测试来跳过或失败。 例如:
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 这与vars文件的条件导入(见下文)相结合特别有用。 如示例所示,您不需要使用{{}}在条件中使用变量,因为这些变量已经被隐含。
Loops and Conditionals
结合with_items (请参阅循环 ),请注意,每个项目分别处理when语句。 这是设计:
tasks:
- command: echo {{ item }}
with_items: [ 0, 2, 4, 6, 8, 10 ]
when: item > 5 如果需要根据定义的循环变量跳过整个任务,则使用| default过滤器来提供一个空的迭代器:
- command: echo {{ item }}
with_items: "{{ mylist|default([]) }}"
when: item > 5 如果使用没有列表的with_dict :
- command: echo {{ item.key }}
with_dict: "{{ mydict|default({}) }}"
when: item.value > 5
Loading in Custom Facts
如果需要,提供自己的facts也很容易,这在开发模块中有所体现。 要运行它们,只需在您的任务列表顶部调用您自己的自定义facts收集模块,返回的变量将在以后的任务中访问:
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'
Applying ‘when’ to roles and includes
请注意,如果您有多个任务共享相同的条件语句,则可以将条件附加到如下的任务include语句。 所有的任务得到评估,但条件应用于每个任务:
- include: tasks/sometasks.yml
when: "'reticulating splines' in output"
- hosts: webservers
roles:
- { role: debian_stock_config, when: ansible_os_family == 'Debian' } 在不符合条件的系统上使用此方法时,默认情况下,您将会注意到很多“跳过”输出。 在“ 关于模块”文档中的“group_by”模块上阅读,以获得更加精简的方式来完成相同的操作。
Conditional Imports
有时你会根据某些标准,在一个playbook里做一些不同的事情。 有一本适用于多个平台和操作系统版本的playbook就是一个很好的例子。
例如,CentOS和Debian之间的Apache软件包的名称可能不同,但可以在一个可读的Playbook中使用最少的语法进行处理:
---
- hosts: all
remote_user: root
vars_files:
- "vars/common.yml"
- [ "vars/{{ ansible_os_family }}.yml", "vars/os_defaults.yml" ]
tasks:
- name: make sure apache is started
service: name={{ apache }} state=started 作为提醒,各种YAML文件只包含键值和值:
---
# for vars/CentOS.yml
apache: httpd
somethingelse: 42 这个怎么用? 如果操作系统是“CentOS”,则第一个可以导入的文件是“vars / CentOS.yml”,如果该文件不存在,则为“/vars/os_defaults.yml”。
如果列表中没有找到任何文件,则会出现错误。 在Debian上,它会首先查看'vars / Debian.yml'而不是'vars / CentOS.yml',然后再回到'vars / os_defaults.yml'。 很简单
要使用这个条件导入功能,您需要在运行该playbook之前安装facter或ohai,但如果您喜欢,您可以将其与Ansible一起推出:
# for facter
ansible -m yum -a "pkg=facter state=present"
ansible -m yum -a "pkg=ruby-json state=present" # for ohai
ansible -m yum -a "pkg=ohai state=present" 可配置的配置方法 - 将变量与任务分离,使您的剧本不会变成具有丑陋的嵌套ifs,条件等的任意代码,并导致更精简和可审计的配置规则,特别是因为至少有一个决策点要跟踪。
Selecting Files And Templates Based On Variables
有时您要复制的配置文件或您将使用的模板可能取决于变量。 以下构造选择适合于给定主机的变量的第一个可用文件,这通常比在模板中放入大量条件更为干净。
以下示例显示如何模板化出与CentOS和Debian之间有很大不同的配置文件:
- name: template a file
template: src={{ item }} dest=/etc/myapp/foo.conf
with_first_found:
- files:
- {{ ansible_distribution }}.conf
- default.conf
paths:
- search_location_one/somedir/
- /opt/other_location/somedir/
Register Variables
通常在playbook中,将给定命令的结果存储在变量中可能是有用的,然后再访问它。 以这种方式使用命令模块可以在很多方面消除编写站点特定事实的需要,例如,您可以测试特定程序的存在。
'register'关键字决定将结果保存到哪个变量中。生成的变量可以在模板,动作行或when语句中使用。 看起来像这样(显而易见的例子):
- 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_item”中被使用,如果它被转换成列表(或已经是列表),如下所示。
“stdout_lines”也可以在对象上使用,但是如果需要也可以调用“home_dirs.stdout.split()”,并且可以被其他字段分割:
- 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() }}" 如前所示,注册变量的字符串内容可通过'stdout'值访问。 您可以检查注册变量的字符串内容为空:
- name: check registered variable for emptiness
hosts: all tasks: - name: list contents of directory
command: ls mydir
register: contents - name: check contents for emptiness
debug: msg="Directory is empty"
when: contents.stdout == ""
Ansible Playbook Conditionals的更多相关文章
- Ansible playbook API 开发 调用测试
Ansible是Agentless的轻量级批量配置管理工具,由于出现的比较晚(13年)基于Ansible进行开发的相关文档较少,因此,这里通过一些小的实验,结合现有资料以及源码,探索一下Ansible ...
- ansible playbook实践(四)-如何调试写好的playbook文件
有时,我们写了一个长长,功能很强悍的yaml文件,但是,我们有可能会担心,写的yaml文件是否正确,是否有漏洞危机,毕竟是要修改线上的机器,那么,有可能我们可以从以下几个检查维度来进行,确保在大规模应 ...
- ansible playbook批量改ssh配置文件,远程用户Permission denied
最近手里的数百台服务器需要改/etc/ssh/sshd_config的参数,禁止root直接登陆,也就是说 [root@t0 ~]# cat /etc/ssh/sshd_config | grep R ...
- ansible笔记(11):初识ansible playbook(二)
ansible笔记():初识ansible playbook(二) 有前文作为基础,如下示例是非常容易理解的: --- - hosts: test211 remote_user: root tasks ...
- ansible笔记(10):初识ansible playbook
ansible笔记():初识ansible playbook 假设,我们想要在test70主机上安装nginx并启动,我们可以在ansible主机中执行如下3条命令 ansible test70 -m ...
- Ansible playbook 批量修改服务器密码 先普通后root用户
fsckzy Ansible playbook 批量修改服务器密码 客户的需求:修改所有服务器密码,密码规则为Rfv5%+主机名后3位 背景:服务器有CentOS6.7,SuSE9.10.11,r ...
- 写Ansible playbook添加zabbix被监控的对象
本主题达到的效果是能通过编写Ansible Playbook,创建zabbix主机组,把被监控的对象加入到zabbix监控系统中,同时链接到对象的模板. 1.准备工作 在zabbix服务器上面,我们需 ...
- Ansible playbook基础组件介绍
本节内容: ansible playbook介绍 ansible playbook基础组件 playbook中使用变量 一.ansible playbook介绍 playbook是由一个或多个“pla ...
- ansible playbook基本操作
一.ansible playbook简单使用 相当于是把模块写入到配置文件里面 vim /etc/ansible/test.yml //写入如下内容: --- - hosts: 127.0.0.1 r ...
随机推荐
- iotBaidu问题小结
1.后台程序不能正常运行: d:\>java -jar MqttService.jar Exception in thread "main" java.lang.Securi ...
- System V 消息队列 实例
前言: 消息队列是消息的链接表,存放在内核中,并由消息队列标识符标识.我们将称消息队列为 “队列”,其标识符为“队列I D”.msgget创建一个新队列或打开一个存在的队列; msgsnd向队列末端添 ...
- ios之gcd
看这里吧 http://www.jianshu.com/p/3a5a55e50e84
- java IO字节流
字节流可以读取 复制 各种类型 的文件. 写文件 第一种:读文件,每次读取1024字节的内容,读取太大文件不会导致内存溢出 第二种:读文件,更简单 思考?如果复制一个电影 或 1G 以上的文件,会出现 ...
- js和jquery判断该元素中是否有指定class
<div class="test">test</div> var t = document.getElementsByClassName('test'); ...
- 【pushlet学习】具体实战
业务需求: 1. 前端界面需要实时显示空调.照明等设备的状态, 如:空调电压.空调电流.光照强度等,这些量每一个称作一个测点: 2. 不同的用户登录系统后,用户只能看到自己设备的运行状态,而看不到其他 ...
- SimpleXML概述
要处理XML 文件,有两种传统的处理思路:SAX 和DOM.SAX 基于事件触发机制,对XML 文件进行一次扫描,完成要进行的处理:DOM 则将整个XML 文件构造为一棵DOM树,通过对DOM 树的遍 ...
- 使用javascript连接mqtt协议(自动重连问题)
因为之前是在rabbitmq的插件"RabbitMQ Web MQTT plugin "中看到使用了mqttws31.js的实例,由于对mqttws31不了解,网上下载了连接成功, ...
- 编译器错误消息: CS0016: 未能写入输出文件“c:/Windows/Microsoft.NET/Framework/v4.0.50727/Temporary ASP.NET Files/root .... 拒绝访问。
此问题困扰良久,得终极解决方案 环境:windows 2008 server r2 + iis7 + .net framework4.5 解决:1. 错误信息中包含的目录“c:/Windows/Mic ...
- 微信小程序注册身份证验证
// 校验身份证号 //校验码校验 checkCode: function (val) { var p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2])) ...