一、 Ad-Hoc 的问题
通过对 AD-HOC 的学习,我们发现 AD-HOC 每次只能在被管理节点上执⾏简单的命令。
⽽⽇常⼯作中,我们往往⾯临的是⼀系列的复杂操作,例如我们有
可能需要安装软件、更新配置、启动服务等等⼀系列操作的结合。此时
再通过 AD-HOC 去完成任务就有些⼒不从⼼了。
在这种场景下,Ansible引进了 PLAYBOOK 来帮忙我们解决这样复杂问题。
二、 PlayBook是什么
Playbook 也通常被⼤家翻译成剧本。
可以认为它是Ansible ⾃定义的⼀⻔语⾔
(可以将 Playbook ⽐作Linux 中的 shell,⽽ Ansible 中的 Module 可以⽐作为 Linux 中的各种命令。)
通过这样的类⽐,我们对PlayBook就有了⼀个更形象的认识了。
既然 Playbook 是⼀⻔语⾔,那么它遵循什么样的语法格式?
有哪些语⾔呢性? 我们将通过下⾯的学习逐步了解。
三、 YAML 学习
PlayBook遵循YAML 的语法格式。因此在学习PlayBook之前,我们必须要先弄明⽩YAML 相关知识点。
1、YAML特点
YAML ⽂件
-
以 # 为注释符
-
以 .yml 或者.yaml 结尾
-
以 --- 开始 , 以 ... 结束, 但开始和结束标志都是可选的
2、基本语法
- ⼤⼩写敏感
- 使⽤缩进表示层级关系
- 缩进时是使⽤Tab键还是使⽤空格⼀定要达到统⼀,建议使⽤
空格。 - 相同层级的元素必须左侧对⻬即可
YAML ⽀持的数据结构有三种
- 字符串
- 列表
- 字典
接下来分别介绍它们。
1. 字符串
---
# YAML 中的字符串可以不使⽤引号,即使⾥⾯存在空格的时候,当然
了使⽤单引号和双引号也没有错。
this is a string
'this is a string'
"this is a string"
# YAML 中若⼀⾏写不完你要表述的内容的时候,可以进⾏折⾏。写法
如下:
long_line: |
Example 1
Example 2
Example 3
# 或者
long_line: >
Example 1
Example 2
Example 3
...
2. 列表
---
# 若熟悉 Python 的话, 可以认为它就是Python中的List ,若熟悉 C 语⾔的话, 可以认为它是 C 中的数组。
# 如何定义: 以短横线开头 + 空格 + 具体的值
- red
- green
- blue
# 以上的值假如转换成 python 的 List 会是这样:
# ['red', 'green', 'blue']
...
3. 字典
---
# 若熟悉 Python 的话, 可以认为它就是 Python 中的 Dict
# 如何定义: key + 冒号(:) + 空格 + 值(value), 即 key:value
name: Using Ansible
code: D1234
# 转换为 python 的 Dict
# {'name': 'Using Ansibel', 'code': 'D1234'}
...
4. 混合结构
以上,针对YAML 的所有基础知识点就介绍完了。但在⽇常⽣活
中,往往需要的数据结构会特别复杂,有可能会是字符串、列表、字典
的组合形式。 这⾥举⼀个⼩例⼦: 所有⼈都上过学,都知道到学校⾥是
以班级为单位。我们去使⽤列表和字典的形式去描述⼀个班级的组成。
---
class:
- name: stu1
num: 001
- name: stu2
num: 002
- name: stu3
num: 003
# {'class': [{'name': 'stu1', 'num': 1},{'name':
'stu2', 'num': 2},...]}
...
5. 验证YAML 语法
# 将YAML⽂件,通过 Python 的YAML 模块验证, 若不正确则报错。若正确则会输出 YAML ⾥的内容。
# 注意使⽤时,⼀定确保安装了yaml 软件包。
pip3 install pyyaml
# yaml.load(sys.stdin) 从标准输入中load, < myyaml.yml 就是标准输入
python -c 'import yaml,sys; print yaml.load(sys.stdin)' < myyaml.yml # yaml.safe_load 安全的
python3 -c 'import yaml,sys; print(yaml.load(sys.stdin))' < myyaml.yml
Example
# 正确的情况
# cat myyaml.yml
---
- red
- green
- blue
...
# 验证YAML 语法
python -c 'import yaml,sys; print yaml.safe_load(sys.stdin)' < myyaml.yml
python3 -c 'import yaml,sys; print(yaml.load(sys.stdin))' < myyaml.yml
['red', 'green', 'blue']
#==============================================================
# 错误的情况, 将YAML⽂件写错
# cat myyaml.yml
---
- red
- green
-blue
...
python -c 'import yaml,sys; print yaml.load(sys.stdin)' < myyaml.yml
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/lib/python2.7/sitepackages/yaml/__init__.py", line 71, in load
return loader.get_single_data()
File "/usr/local/lib/python2.7/sitepackages/yaml/constructor.py", line 37, in
get_single_data
node = self.get_single_node()
...
...
四、Playbook 的编写
1、Play 的定义
由于Playbook 是由⼀个或者多个Play组成,那么如果我们熟悉Play的写法,就⾃然掌握了我们这章的PlayBook。
那如何定义⼀个Play呢?
1、每⼀个Play 都是以短横杠开始的
2、每⼀个Play 都是⼀个YAML 字典格式
根据上⾯两条Play 的规则,⼀个假想的 Play 应该是如下的样⼦
---
- key1: value1
key2: value2
key3: value3
...
由于⼀个Playbook 是由⼀个或者多个Play构成,
那么⼀个含有多个Play的Playbook 结构上应该是如下的样⼦
---
# ⼀个含有3个Play 的伪PlayBook构成
- key1: value1
key2: value2
key3: value3
- key4: value1
key5: value2
key6: value3
- key1: value1
key2: value2
key3: value3
...
2、Play 属性
以上⼀⼩节中的Play为基础, Play中的每⼀个key,
⽐如 key1, key2等;这些key在PlayBook中被定义为Play的属性。
这些属性都具有特殊的意义,我们不能随意的⾃定义Play 的属性。
接下来就来看看 Ansible 本身都⽀持哪些Play属性。
常用属性
- name 属性, 每个play的名字
- hosts 属性, 每个play 涉及的被管理服务器,同ad-hoc 中的资产选择器
- tasks 属性, 每个play 中具体要完成的任务,以列表的形式表达
- become 属性,如果需要提权,则加上become 相关属性,su提权或者sudo提权
- become_user 属性, 若提权的话,提权到哪个⽤户上
- remote_user属性,指定连接到远程节点的⽤户,就是在远程
- 服务器上执⾏具体操作的⽤户。若不指定,则默认使⽤当前执⾏ ansible Playbook 的⽤户
3、一个完整剧本
根据上⼀⼩节中介绍的真实的属性,⼀个含有⼀个Play 的Playbook 应该是如下的样⼦
---
- name: the first play example
hosts: webservers
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=present
- name: copy nginx.conf to remote server
copy: src=nginx.conf dest=/etc/nginx/nginx.conf
- name: start nginx server
service:
name: nginx
enabled: true
state: started
4、tasks 属性中任务的多种写法
# 以启动 nginx 服务,并增加开机启动为例
# ⼀⾏的形式:
service: name=nginx enabled=true state=started
# 多⾏的形式:
service: name=nginx
enabled=true
state=started
# 多⾏写成字典的形式:
service:
name: nginx
enabled: true
state: started
5、具有多个Play 的Playbook
---
- name: manage web servers
hosts: webservers
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=present
- name: copy nginx.conf to remote server
copy: src=nginx.conf dest=/etc/nginx/nginx.conf
- name: start nginx server
service:
name: nginx
enabled: true
state: started
- name: manager db servers
hosts: db_servers
tasks:
- name: update database confg
copy: src=my.cnf dest=/etc/my.cnf
6、如何对Playbook 进行语法校验
下⾯校验的⽅法,只能校验PlayBook是否正确,⽽不能校验YAML⽂件是否语法正确。
# ansible-playbook -i hosts myplaybook.yml --syntaxcheck
因为PlayBook 属于YAML 格式, 我们同样可以使⽤检查YAML的语法格式的⽅法进⾏检查PlayBook的语法正确性。
# python -c 'import yaml,sys; print yaml.safe_load(sys.stdin)' < myplaybook.yml
7、 如何运⾏PlayBook
# ansible-playbook -i hosts myplaybook.yml
8、 如何单步跟从调试PlayBook
# 执⾏Task中的任务,需要⼿动确认是否往下执⾏。
# ansible-playbook -i hosts myplaybook.yml --step
9、如何测试运行PlayBook
测试运⾏就是会执⾏完整个PlayBook ,但是所有Task中的⾏为都不
会在远程服务器上执⾏,所有执⾏都是模拟⾏为。
# ansible-playbook -i hosts myplaybook.yml -C
#-C 为⼤写的字⺟ C
1