目录
上一章我对playbooks做了简单的介绍、包括它的语法、组成、编写等。只是一些简单的基础类的东西。
现在本章继续对ansible剧本playbooks进行介绍,本章讲的是条件选择
一、关于条件选择
条件选择可以看ansible官方文档的Conditionals,也可以看ansible权威指南的 条件选择。
如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件判断。
如上面的剧本中,如果hua有两个主机vm821和76,从实验列表中知道vm821和vm76分别cenos8和centos7,要是同时用官方nginx yum安装nginx,那就是先判断系统版本了。8和7的yum的rpm包是不一样的,centos8使用的是el8,cento7使用的是el7。
二、条件选择
2.1 when语句
2.1.1 when语句介绍
有时候用户有可能需要某一个主机越过某一个特定的步骤.这个过程就可以简单的像在某一个特定版本的系统上 少装了一个包一样或者像在一个满了的文件系统上执行清理操作一样. 这些操作在Ansible上,若使用`when`语句都异常简单.When语句包含Jinja2表达式(参见:doc:playbooks_variables).
在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法。例如:
tasks:
- name: "shutdown Debian flavored systems"
command: /sbin/shutdown -h now
when: ansible_os_family == "Debian"
when语句中还可以使用Jinja2的大多“filter”,例如要忽略此前某语句的错误并基于其结果(failed或者sucess)运行后面指定的语句,可使用类似如下形式:
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
此外,when语句中还可以使用facts或playbook中定义的变量。
2.1.2 常见的判断符号
条件判断语句,一般都会支持一些判断符号,ansible when也不例外,常用的如下:
符号 | 说明 |
---|---|
== | 比较两个对象是否相等,相等为真 |
=! | 比较两个对象是否不等,不等为真 |
> | 比较两个值的大小,如果左边的值大于右边的值,则为真 |
< | 比较两个值的大小,如果左边的值小于右边的值,则为真 |
>= | 比较两个值的大小,如果左边的值大于右边的值或左右相等,则为真 |
<= | 比较两个值的大小,如果左边的值小于右边的值或左右相等,则为真 |
and | 逻辑与,当左边与右边同时为真,则返回真 |
or | 逻辑或,当左边与右边有任意一个为真,则返回真 |
not | 取反 |
is defined | 变量被定义且存在 |
is not defined | 变量不存在 |
2.2 条件导入
基于某个特定标准,又是你也许在一个playbook中你想以不同的方式做同一件事. 在不同平台或操作系统上使用痛一个playbook就是一个很好的例子.
举个例子,名字叫做Apache的包,在CentOS 和 Debian系统中也许不同, 但是这个问题可以一些简单的语法就可以被Ansible 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 running
service: name={{ apache }} state=running
2.3 基于变量选择文件和模版
有时候,你想要复制一个配置文件,或者一个基于参数的模版. 下面的结构选载选第一个宿主给予的变量文件,这些可以比把很多if选择放在模版里要简单的多. 下面的例子展示怎样根据不同的系统,例如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/
2.4 注册变量
经常在playbook中,存储某个命令的结果在变量中,以备日后访问是很有用的。这样使用命令模块可以在许多方面除去写站(site)特异事件,根据例子 你可以检测某一个特定程序是否存在。
这个 ‘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’是可以访问. 这个注册了以后的结果,如果像上面展示的,可以转化为一个list(或者已经是一个list),就可以在任务中的”with_items”中使用. “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()