Playbook介绍
playbook是与ad-hoc模式完全不同的运作模式,ad-hoc无法持久迟永,playbook可以持久使用。
playbook是由一个或多个play组成的列表文件,play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓的task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联合起来按事先编排的机制完成某一任务。
Playbook核心元素
- Hosts:执行的目标远程主机列表
- Tasks:任务集
- Varniables:内置变量或自定义变量在playbook中调用。
- Templates:jinjia2模板,即使用模板语法的文件,比如配置文件
- Handlers、Notity:结合时候,由特定条件出发的操作,满足条件方可执行,否则不执行
- tags:标签,指定某条任务执行,用于选择运行playbook中的部分代码。
ansible-playbook常用命令
usage: ansible-playbook [-h] [--version] [-v] [-k]--ask-vault-pass # 要求提供密码--vault-password-file # 密码文件--flush-cache # 清除清单中每个主机的缓存--force-handlers # 即使任务失败也运行handlers程序--list-hosts # 输出匹配的主机列表,不进行其他操作--list-tags # 列出所有可用的标签--list-tasks # 列出将要执行的任务--private-key # 使用此文件验证ssh连接--scp-extra-args # 指定额外的参数传递给scp,如-l--sftp-extra-args # 指定额外的参数以传递给sftp--ssh-extra-args # 指定额外的参数传递给ssh,如-R--step # 每执行一步等待确认,一步一步执行--syntax-check # 在剧本上执行语法检测,但不执行-C # 不做任何改变,但预测可能发生的某些变化-D # 更改文件和模板时,显示文件差异-T # 覆盖连接超时时间,默认为10s-f # 指定要使用的并发进程数,默认为5-i # 指定清单主机路径,或使用逗号分隔的主机列表-k # 询问连接密码-v # 详细模式
playbook语法
playbook使用yaml语法格式,后缀可以是yaml或者yml。
- 在单一一个playbook文件中,可以使用(—-)区分多个play,还有选择性的连续三个点好(
...)用来表示play的结尾,也可省略。 - 次行开始正常写
playbook的内容,一般都会写上描述该playbook的功能。 - 使用#号注释代码。
- 缩进必须统一,不能空格和
tab混用。 - 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行实现的。
YAML文件内容和Linux系统大小写判断方式保持一致,是区分大小写的,k/v的值均需大小写敏感k/v的值可同行写也可以换行写。同行使用:分隔。v可以是个字符串,也可以是一个列表- 一个完整的代码块功能需要最少元素包括
name: task
示例:
# 创建playbook文件$ cat frist-playbook.yaml--- #固定格式- hosts: websrvs #定义需要执行主机remote_user: root #远程用户tasks: #定义一个任务的开始- name: create new file #定义任务的名称file: name=/tmp/playtest.txt state=touch #调用模块,具体要做的事情- name: install packageyum: name=httpd$ ansible-playbook frist-playbook.yamlPLAY [all] ********************************************************************************************TASK [Gathering Facts] ********************************************************************************************ok: [192.168.10.10]TASK [create new file] ********************************************************************************************changed: [192.168.10.10]TASK [install package] ********************************************************************************************ok: [192.168.10.10]PLAY RECAP ********************************************************************************************192.168.10.10 : ok=3 changed=1 unreachable=0 failed=0
playbook中的元素
主机和用户
一个playbook开始时,最先定义的就是要操作的目标主机和用户
---- hosts: 192.168.1.31remote_user: root
上面的是全局定义的执行用户,还可以在某一个task中定义要执行该任务的远程用户。
tasks:
- name: run df -h
remote_user: test # 除此任务外,其他任务还是用root用户
shell: name=df -h
还可以定义使用sudo授权用户执行该任务
tasks:
- name: run df -h
sudo_user: test # 授权test使用sudo
sudo: yes
shell: name=df -h
tasks任务列表
每一个tasks必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以清楚的辨别是属于哪一个task的,如果name值为空,则模块名action的值将作为输出信息中标记特定的task。
每一个playbook中可以包含一个或者多个tasks任务列表,每一个tasks完成具体的某一件事。
tasks:
- name: create new file
file: path=/tmp/test01.txt state=touch
- name: create new user
user: name=test001 state=present
handlers和Notify
很多时候我们的某一个配置发生了改变,需要重启服务(比如nginx配置文件发生改变)这时候就可以用到handlers和notify
每当发生改动时,notify会在playbook的每一个task结束时被触发,而且即使有多个不同task通知改动的发生,notify只会被触发一次。
---
- hosts: all
remote_user: nginx
tasks:
- name: install nginx package
yum: name=nginx state=installed
- name: copy config file
template: src=./config/nginx.conf dest=/etc/nginx/nginx.conf
notify:
- restart service
- name: start service
service: name=nginx state=started
handlers:
- name: restart service
service: name=nginx state=restarted
# 这里只要nginx.conf做了改动,就会触发notify定义的handlers动作
# template模块中src可以为相对路径,但dest必须为绝对路径
变量的使用
playbook支持以下变量
- 命令行指定变量
hosts文件中定义变量
- 针对单个主机定义变量
- 针对组定义变量
- playbook文件中定义变量
- 调用setup模块获取变量
- 独立yaml文件中定义的变量
环境说明:这里配置了两个组,一个apache组和一个nginx组
[root@ansible PlayBook]# cat /etc/ansible/hosts
[apache]
192.168.1.36
192.168.1.33
[nginx]
192.168.1.3[1:2]
命令行指定变量
执行playbook时通过参数-e传入变量,这样传入的变量在整个playbook中都可以被调用,属于全局变量
[root@ansible PlayBook]# cat variables.yml
---
- hosts: all
remote_user: root
tasks:
- name: install pkg
yum: name={{ pkg }}
#执行playbook 指定pkg
[root@ansible PlayBook]# ansible-playbook -e "pkg=httpd" variables.yml
hosts文件中定义变量
在/etc/ansible/hosts中定义变量,可以针对每个主机定义不同的变量,也可以定义一个组的变量,然后直接在playbook中直接调用。
注意,组中定义的变量没有单个主机中的优先级高。
# 编辑hosts文件定义变量
[root@ansible PlayBook]# vim /etc/ansible/hosts
[apache]
192.168.1.36 webdir=/opt/test #定义单个主机的变量
192.168.1.33
[apache:vars] #定义整个组的统一变量
webdir=/web/test
[nginx]
192.168.1.3[1:2]
[nginx:vars]
webdir=/opt/web
# 编辑playbook文件
[root@ansible PlayBook]# cat variables.yml
---
- hosts: all
remote_user: root
tasks:
- name: create webdir
file: name={{ webdir }} state=directory #引用变量
# 执行playbook
[root@ansible PlayBook]# ansible-playbook variables.yml
playbook文件中定义变量
编写playbook时,直接定义变量,然后引用,可以定义多个变量
注意:如果在执行playbook时,又通过-e参数指定变量的值,则会以-e为准
# 编辑playbook
[root@ansible PlayBook]# cat variables.yml
---
- hosts: all
remote_user: root
vars: #定义变量
pkg: nginx #变量1
dir: /tmp/test1 #变量2
tasks:
- name: install pkg
yum: name={{ pkg }} state=installed #引用变量
- name: create new dir
file: name={{ dir }} state=directory #引用变量
# 执行playbook
[root@ansible PlayBook]# ansible-playbook variables.yml
# 如果执行时候又重新指定了变量的值,那么会已重新指定的为准
[root@ansible PlayBook]# ansible-playbook -e "dir=/tmp/test2" variables.yml
调用setup模块获取变量
setup模块是默认的获取主机信息的,在playbook中可以直接使用,可使用ansible all -m setup来获取
# 编辑playbook文件
[root@ansible PlayBook]# cat variables.yml
---
- hosts: all
remote_user: root
tasks:
- name: create file
file: name={{ ansible_fqdn }}.log state=touch #引用setup中的ansible_fqdn
# 执行playbook
[root@ansible PlayBook]# ansible-playbook variables.yml
独立yaml文件中定义的变量
为了方便管理将所有的变量统一放在一个独立的变量YAML文件中,playbook文件直接引用文件调用变量即可。
# 定义存放变量的文件
[root@ansible PlayBook]# cat var.yml
var1: vsftpd
var2: httpd
# 编写playbook
[root@ansible PlayBook]# cat variables.yml
---
- hosts: all
remote_user: root
vars_files: #引用变量文件
- ./var.yml #指定变量文件的path(这里可以是绝对路径,也可以是相对路径)
tasks:
- name: install package
yum: name={{ var1 }} #引用变量
- name: create file
file: name=/tmp/{{ var2 }}.log state=touch #引用变量
# 执行playbook
[root@ansible PlayBook]# ansible-playbook variables.yml
变量优先级
命令行指定变量—>hosts文件中针对单个主机的变量—>hosts文件中针对组的变量—>yaml中的变量
