概念
Playbooks are automation blueprints, in YAML format, that Ansible uses to deploy and configure nodes in an inventory.
playbook 是自动化的蓝图,使用YAML 格式,用来配置和部署清单中的节点。
- Executing tasks with elevated privileges or as a different user.
- Using loops to repeat tasks for items in a list.
- Delegating playbooks to execute tasks on different machines.
- Running conditional tasks and evaluating conditions with playbook tests.
- Using blocks to group sets of tasks.
playbook 、play、task 的关系
简单总结一下playbook、play和task的关系:
1.playbook中可以定义一个或多个play
2.每个play中可以定义一个或多个task
- 其中还可以定义两类特殊的task:pre_tasks和post_tasks
- pre_tasks表示执行执行普通任务之前执行的任务列表
- post_tasks表示普通任务执行完之后执行的任务列表
3.每个play都需要通过hosts指令指定要执行该play的目标主机
4.每个play都可以设置一些该play的环境控制行为,比如定义play级别的变量

Yaml 语法
YAML的基本语法规则如下:
(1).使用缩进表示层级关系
(2).缩进时不允许使用Tab键,只允许使用空格
(3).缩进的空格数目不重要,只要相同层级的元素左对齐即可
(4).yaml文件以”—“作为文档的开始,以表明这是一个yaml文件
- 即使没有使用`---`开头,也不会有什么影响
(5).# 表示注释,从这个字符一直到行尾,都会被解析器忽略
(6).字符串不用加引号,但在可能产生歧义时,需加引号(单双引号皆可),比如引用变量时
(7).布尔值非常灵活,不分区大小写的true/false、yes/no、on/off、y/n、0和1都允许
YAML支持三种数据结构:
(1).对象:key/value格式,也称为哈希结构、字典结构或关联数组
(2).数组:也称为列表
(3).标量(scalars):单个值
可以去找一些在线YAML转换JSON网站,比如 http://yaml-online-parser.appspot.com 通过在线转换可以验证或查看自己所写的YAML是否出错以及哪里出错。
对象
一组键值对,使用冒号隔开key和value。注意,冒号后必须至少一个空格。
name: task1
等价于json:{
"name": "task1"
}
数组
---
- Shell
- Perl
- Python
等价于json:
["Shell","Perl","Python"]
对象与数组结合
---
languages:
- Shell
- Perl
- Python
字典
---
person1:
name: task1
age: 18
gender: male
person2:
name: task2
age: 19
gender: female
复合结构
---
- person1:
name: task1
age: 18
langs:
- Perl
- Ruby
- Shell
- person2:
name: task2
age: 19
langs:
- Python
- Javascript
字符串续行
字符串可以写成多行,从第二行开始,必须至少有一个单空格缩进。换行符会被转为空格。
str: hello
world
hello world
等价于json:
{
"str": "hello world hello world"
}
也可以使用 > 换行,它类似于上面的多层缩进写法。此外,还可以使用|在换行时保留换行符。
this: |
Foo
Bar
that: >
Foo
Bar
等价于json:
{‘that’: ‘Foo Bar’, ‘this’: ‘Foo\nBar\n’}
playbook 的组成
再来解释一下这个playbook文件的含义。
playbook中,每个play都需要放在数组中,所以在playbook的顶层使用列表的方式- xxx:来表示这是一个play(此处是- hosts:)。
每个play都必须包含hosts和tasks指令。
hosts指令用来指定要执行该play的目标主机,可以是主机名,也可以是主机组,还支持其它方式来更灵活的指定目标主机。具体的规则后文再做介绍。
tasks指令用来指定这个play中包含的任务,可以是一个或多个任务,任务也需要放在play的数组中,所以tasks指令内使用- xxx:的方式来表示每一个任务(此处是- copy:)。
gather_facts是一个play级别的指令设置,它是一个负责收集目标主机信息的任务,由setup模块提供。默认情况下,每个play都会先执行这个特殊的任务,收集完信息之后才开始执行其它任务。但是,收集目标主机信息的效率很低,如果能够确保playbook中不会使用到所收集的信息,可以显式指定gather_facts: no来禁止这个默认执行的收集任务,这对效率的提升是非常可观的。
此外每个play和每个task都可以使用name指令来命名,也建议尽量为每个play和每个task都命名,且名称具有唯一性。
playbook 模块参数传递方式
在刚才的示例中,copy模块的参数传递方式如下:
tasks:
- name: copy /etc/passwd to /tmp
copy: src=/etc/passwd dest=/tmp
这是标准的yaml语法,参数部分src=/etc/passwd dest=/tmp是一个字符串,当作copy对应的值。
根据前面介绍的yaml语法,还可以换行书写。有以下几种方式:
---
- name: first play
hosts: nginx
gather_facts: false
tasks:
- copy:
src=/etc/passwd dest=/tmp
- copy:
src=/etc/passwd
dest=/tmp
- copy: >
src=/etc/passwd
dest=/tmp
- copy: |
src=/etc/passwd
dest=/tmp
除此之外,Ansible还提供了另外两种传递参数的方式:
(1).将参数和参数值写成key: value的方式
(2).使用args参数声明接下来的是参数
---
- name: first play
hosts: nginx
gather_facts: false
tasks:
- name: copy1
copy:
src: /etc/passwd
dest: /tmp
- name: copy2
copy:
args:
src: /etc/passwd
dest: /tmp
指定执行的主机
每一个play都包含hosts指令,它用来指示在解析inventory之后选择哪些主机执行该play中的tasks。
hosts指令通过pattern的方式来筛选节点,pattern的指定方式有以下几种规则:
1.直接指定inventory中定义的主机名
- hosts: localhost
2.直接指定inventory中的主机组名
- hosts: nginx、hosts: all
3.使用组名时,可以使用数值索引的方式表示组中的第几个主机
- hosts: nginx[1]:mysql[0]
4.可使用冒号隔开多个pattern
- hosts: nginx:localhost
5.可以使用范围表示法
- hosts: 192.168.200.3[0:3]
- hosts: web[A:D]
6.可以使用通配符*
- hosts: *.example.com
- hosts: *
7.可以使用正则表达式,需使用~开头
- hosts: ~(web|db)\.example\.com
此外:
1.所有pattern选中的主机都是包含性的,第一个pattern选中的主机会添加到下一个pattern的范围内,直到最后一个pattern筛选完,于是取得了所有pattern匹配的主机
2.pattern前面加一个&符号表示取交集
- pattern1:&pattern2 要求同时存在于pattern1和pattern2中的主机
3.pattern前面加一个!符号表示排除
- pattern1:!pattern2 要求出现在pattern1中但未出现在pattern2中

