之前的模块都是使用Ad-hoc方式(Ad-hoc方式是一种可以快速输入的命令,而且不需要保存起来的命令)点对点命令执行,可以管理远程主机,但如果服务器数量比较多,配置信息也比较多,可以利用Ansible PlayBook编写剧本
剧本主要作用是实现任务处理的自动化和流程化
PlayBook 是由一个或多个 "play" 组成列表,在play 中的内容被我们称之为 tasks,也叫任务
多个tasks组成了一个play,task调用 ansible的各种模块(module),将多个play组织在一个 playbook 剧本中组成一个完整的流程控制集合
下面就是一个只包含了2个play的playbook:
说明:
playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务
hosts 用于指定要执行任务的主机,其可以是一个或多个由冒号分隔主机组
vars 执行对应任务时,携带的到远端主机的变量信息
remote_user 则用于指定远程主机上的执行任务的用户
play的主体部分是task list。task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个,如中途剧本执行发生错误,所有已经执行任务都将回滚。
task的目的是使用使用指定模块,在模块参数中可以使用变量。模块执行时幂等性的,多次执行是安全的,因为其结果均一致。
每个task都应该有其name,是我们对当前任务的说明,用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供name,则执行的模块名将用于输出
定义task的action(动作)可以使用module_name:module_args”
一个name只能包括一个task
在众多模块中,只有command和shell模块仅需要给定一个列表而无需使用“key=value”格式
注:
如果命令或脚本的退出码不为零, 可以使用如下方式替代:
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand || /bin/true
或者使用ignore_errors来忽略错误信息:
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand
ignore_errors: True
总结:简单来说playbook就是一个用yaml语法把多个模块堆起来的一个文件而已,把不同的模块按照顺序编排在剧本中,ansible就会按照剧本一步一步的执行,最终达到我们的目的。
更多playbook官方说明参考:
Intro to playbooks — Ansible Documentation
Ansible 中文学习手册
Playbooks — 国内最专业的Ansible中文官方学习手册
Playbook采用YAML语言编写,每一个Ansible的Playbook都是一个YAML格式的文件
1. yaml 文件以 --- 开头 ,表明是一个 yaml 文件
2. yaml中使用"#"作为注释符
3. 区分大小写
4.使用缩进表示层级关系:YAML使用一个固定的缩进风格表示层级结构,可以理解为同一层代表一个级别,缩进时不允许使用Tab键,只允许使用空格
注:缩进的空格数目没有限制,但要求同一层级左对齐。判断是否是同一级别是通过缩进结合换行来实现的
5.冒号,以冒号结尾的除外,其他所有冒号后面必须有空格
6.短横线,表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为同一列表
7.关于布尔值的书写格式,即true/false的表达方式。其实playbook中的布尔值类型非常灵活,可分为两种情况:
1)模块的参数:这时布尔值作为字符串被ansible解析。接受yes/on/1/true /no/off/0/false。例如上面示例中的update_cache=yes
2)非模块的参数:这时布尔值被yaml解释器解析,完全遵循yaml语法。接受不区分大小写的true/yes/on/y/false/no/off/n。例如gather_facts: True
建议遵循ansible的官方规范,模块的布尔参数采用yes/no,非模块的布尔参数采用True/False
8.YAML文件扩展名通常为yml或yaml
对于Ansible, 每一个YAML文件都是从一个列表(列表list,又称为序列 sequence)开始。
列表中的每一项都是一个键值对,通常它们被称为一个 “哈希” 或 “字典”或映射
列表中的所有成员都开始于相同的缩进级别, 并且使用一个 "- " 作为开头(一个减号和一个空格)
具体在ansible playbook中,列表所描述的是局部环境,它不一定要有名称,只要使用"- ",它就表示圈定一个范围,范围内的项都属于该列表。例如:
一个字典是由一个简单的 键: 值 的形式组成(这个冒号后面必须是一个空格),它一般当作列表项的属性
k/v的值可同行写也可换行写。同行使用 : 号分隔
v可是个字符串,也可是另一个列表
YAML列表与字典是可以自由组合在一起的,它们之间可以相互嵌套,通过非常灵活的组合,可以帮助我们描述更加复杂的对象属性
此外, Ansible使用“{{ var }}”来引用变量.。如果一个值以 “{” 开头, YAML 将认为它是一个字典, 所以我们必须引用它, 像这样 foo: "{{ var }}"
编写一个剧本,使用playbook执行
vim a1.yml
---
- hosts: web_server
remote_user: root
tasks:
- name: ping the host
ping:
- name: make directorytest
file:
path: /data/testfile
state: directory
执行编写 a1.yml 的剧本
ansible-playbook /root/a1.yml
如上图所示,playbook执行后返回了一些信息,这些信息是这次剧本运行的概况.
'PLAY [web_servers]'表示这次运行的playbook中有一个'play',是针对web_servers这个主机组运行的,一个'playbook'是由一个或多个'play'组成的
这个play一共包含三个任务,第一个任务的名字叫做'Gathering Facts',第二个任务的名字叫做'Ping the host',第三个任务的名字叫做'make directory test'
但我们只写了两个任务,是因为,每个play在执行时,都会先执行一个默认任务,这个默认任务就是'Gathering Facts','Gathering Facts'任务会收集当前play对应的目标主机的相关信息,收集完这些基础信息后,才会执行我们指定的任务
/data/testfile目录已经存在于远程主机中,'make directory test'任务返回的信息是绿色的,不存在则应是黄色,这是因为幂等性的原因
当playbook中的所有play执行完毕后,在返回信息的'PLAY RECAP'中可以对所有目标主机的执行情况进行概要描述。
1.palyboo核心元素包括:
target:定义 playbook的远程主机组
variables:定义playbook使用的变量
tasks:定义远程主机上执行的任务列表
handlers:处理器,当某条件满足时,触发执行的操作
roles:角色,用于层次性、结构化的组织playbook,roles能根据层次型结构,自动装载变量文件、tasks以及handlers等
2.target 常用参数详解
hosts:运行指定任务的目标主机,可以是主机组、主机、多个主机,中间冒号分隔,all代表所有主机
remote_user:指定远程主机的执行任务的用户
gather_facks:获取远程主机的 facts基础信息
注:gather_facks: True 表示在远程主机运行的 setup 模块,获取远程主机的facts,facts就是变量,内建变量 。每个主机的各种信息cpu个数、内存大小等会在facts中的某个变量中
3. variable 常用参数详解
vars:在 yaml文件中定义变量赋值。格式: 变量名 :变量值
vars_files:指定变量文件,在文件中定义变量
4. tasks 常用参数详解
name:任务显示名称也是屏幕显示信息
module_name: module_atgs :需要使用的模块名字:模块参数
关于task 说明:
1.play的主题部分是 task列表,task 列表中的任务是按顺序逐个在 hosts 指定的主机执行
2.在运行playbook时(从上到下执行),如果一个 host 执行 task 失败,整tasks 都会回滚。
3.每一个task 必须有一个名称 name ,这样运行 playbook时从其输出任务的执行信息中,便于分辨出属于那个 task 列表,没有定义name,‘action’的值将会用作输出信息中标记特定的task
4.定义一个task,常见的格式:” module_name: module_args” 例如:yum: name=httpd state=absent update_cache=yes
5.ansible的自带模块中,command模块和shell模块无需使用key=value格式
5. handler 常用参数详解
notify:“notify”这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性地执行指定操作。
handler: 也是task列表,在notify 中列出的操作称为 handler,notify中调用handler中定义的操作
ansible-playbook --check playbook.yaml #只检测可能会发生的改变,但不真执行操作,--check简写是 -C (大写)
ansible-playbook --list-hosts playbook.yaml #列出运行任务的主机
ansible-playbook --syntax-check playbook.yaml #检查yaml文件语法是否正确
ansible-playbook -t TAGS_NAME playbook.yaml #表示跳过标签前的步骤,直接从标签位置开始, -t选项执行特定的 tag标签任务
注:通过tage参数给指定的任务定义一个调用标识
格式:
- name: NAME
module: arguments
tags: TAG_ID
ansible-playbook playbook.yaml #运行某个剧本文件