ansible(19)--ansible的playbook
1. playbook简介
playbook
的主要功能在于将事先归并为一组的主机装扮成事先通过ansible
中的task
定义好的角色。从根本上来讲,所谓task
无非是调用ansible
的一个个模块。将多个play
组织在一个playbook
中,即可以让它们联同起来按事先编排的机制同唱一台大戏。
playbook
是一个 由 yaml
语法编写的文本文件,它由 play
和task
两部分组成。
play
: 主要定义要操作主机或者主机组task
:主要定义对主机或主机组具体执行的任务,可以是一个任务,也可以是多个任务(模块)
playbook
和ad-hoc
的主要区别如下:
-
playbook
是对AD-Hoc
的一种编排方式。
-
playbook
可以持久运行,而Ad-Hoc
只能临时运行。
-
playbook
适合复杂的任务,而Ad-Hoc
适合做快速简单的任务。
-
playbook
能控制任务执行的先后顺序。
2. playbook编写规范
2.1 YAML语法规范
yaml
的语法规范如下:
-
在单一档案中,可用连续三个连字号
"-"
区分多个档案,也就是说在一个文件里可以写多个playbook
。另外,还有选择性的连续三个点号“…”
用来表示档案结尾,当文件只有一个playbook
时,写上比较规范,不写也不会报错。 -
次行开始正常写
Playbook
的内容,一般建议写明该Playbook
的功能,使用#
号注释代码。 -
短横线
“-”
表示列表项,使用一个短横杠加一个空格。 -
缩进必须是统一的,不能空格和
tab
混用。缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的。
-
YAML
文件内容和Linux
系统大小写判断方式保持一致,是区别大小写的,k/v
的值均需大小写敏感。 -
k/v
的值可同行写也可换行写。同行使用:
分隔。v
可是个字符串,也可是另一个列表。 -
以冒号结尾的除外,其他所有冒号后面所有必须有空格。
-
YAML
文件扩展名通常为yml
或yaml
。
2.2 YAML语法要素
YAML
的语法要素:
-
列表
其所有元素均使用
“-”
打头,表示平级关系,示例:# A list of tasty fruits - Apple - Orange - Strawberry - Mango
-
字典
Dictionary
,通常由多个key
与value
构成,类似于变量赋值,key
相当于变量,value
为值,只不过连接用冒号,示例:# An employee record name: Example Developer job: Developer skill: Elite
也可以将
key:value
放置于{}
中进行表示多个key:value
,多个key:value
使用逗号“,”
隔开:示例:# An employee record {name: Example Developer,job: Developer,skill: Elite}
-
列表和字典的结合使用:
name: John Smith age: 41 gender: Male spouse: <==字典嵌套,spouse:表示key name: Jane Smith <==name/age/gender三个字典为值 age: 37 gender: Female children: <==字典与列表嵌套 - name: Jimmy Smith <==被嵌套的列表 age: 17 <==列表内的字典 gender: Male - name: Jenny Smith age: 13 gender: Female
2.3 Playbook核心元素
-
Hosts
执行的远程主机列表,
Hosts
为key
,其值为将来要执行的主机列表。 -
Tasks
任务集。
-
Varniables
内置变量或自定义变量在
playbook
中调用。 -
Templates (模板)
可替换模板文件中的变量并实现一些简单逻辑的文件。
-
Handlers 和notity结合使用
由特定条件触发的操作,满足条件方才执行,否则不执行。
-
tags (标签)
指定某条任务执行,用于选择运行
playbook
中的部分代码。ansible
具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags
跳过此些代码片断。
2.4 Playbook的基础组件
-
Hosts
playbook
中的每一个play
的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。hosts
用于指定要执行指定任务的主机,须事先定义在主机清单中。 -
remote_user
可用于
Host
和task
中。表示在远程的主机上以谁的身份去进行后面的任务。也可以指定其通过sudo
的方式在远程主机上执行任务,其可用于play
全局或某任务;甚至可以在sudo
时使用sudo_user
指定sudo
时切换的用户。- hosts: websrvs remote_user: root <==指定全局为root身份 tasks: - name: test connection ping: remote_user: xu <==表示针对name这个模块使用xu sudo: yes <==默认sudo为root sudo_user:wang <==指定sudo切换时,使用wang
-
task列表
play
的主体部分是task list
。task list
中的各任务按次序逐个在hosts
中指定的所有主机上执行,即在所有主机上完成第一个任务后,再开始第二个任务。task
的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。每个
task
都应该有其name
,用于playbook
的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。 -
tasks:任务列表
格式:
action: module arguments action: command /sbin/setenforce 0 module: arguments 建议使用 command: /sbin/setenforce 0
注意:
-
shell
和command
模块后面跟命令,而非key=value
; -
某任务的状态在运行后为
changed
时,可通过“notify”
通知给相应的handlers
(触发任务); -
任务可以通过
"tags“
打标签,而后可在ansible-playbook
命令上使用-t
指定进行调用;
-
3 Playbook编写示例
3.1 ansible部署NFS示例
-
编写
NFS
的playbook
文件:--- - hosts: 192.168.20.23 remote_user: root tasks: - name: Install NFS Server yum: name: nfs-utils state: present - name: Configure NFS Server copy: src: conf/exports.j2 dest: /etc/exports notify: Restrat NFS Service - name: Init NFS Server file: path: /data/nfs state: directory owner: “nginx” group: ”nginx“ mode: "0644" - name: Start NFS service service: name: nfs state: started enabled: yes handlers: - name: Restrat NFS Service service: name: nfs state: restarted #NFS配置文件: [root@xuzhichao playbook]# cat conf/exports.j2 /data/nfs 192.168.20.0/24(rw,all_squash,anonuid=887,anongid=887)
-
检查文件语法:
[root@xuzhichao playbook]# ansible-playbook install_nfs.yml --syntax-check playbook: install_nfs.yml
-
运行
playbook
文件:#测试运行: [root@xuzhichao playbook]# ansible-playbook install_nfs.yml -C [root@xuzhichao playbook]# ansible-playbook install_nfs.yml PLAY [192.168.20.23] ***************************************************************************************************************************************** TASK [Gathering Facts] *************************************************************************************************************************************** ok: [192.168.20.23] TASK [Install NFS Server] ************************************************************************************************************************************ ok: [192.168.20.23] TASK [Configure NFS Server] ********************************************************************************************************************************** changed: [192.168.20.23] TASK [Init NFS Server] *************************************************************************************************************************************** changed: [192.168.20.23] TASK [Start NFS service] ************************************************************************************************************************************* changed: [192.168.20.23] RUNNING HANDLER [Restrat NFS Service] ************************************************************************************************************************ changed: [192.168.20.23] PLAY RECAP *************************************************************************************************************************************************** 192.168.20.23 : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
-
检查
NFS
服务情况:[root@xuzhichao playbook]# showmount -e 192.168.20.23 Export list for 192.168.20.23: /data/nfs 192.168.20.0/24
3.2 ansible部署httpd示例
-
编写
httpd
的playbook
文件:[root@xuzhichao playbook]# cat install_httpd.yml --- - hosts: 192.168.20.23 remote_user: root tasks: - name: Install Htttpd Server yum: name: httpd state: present - name: Configure Httpd Server copy: src: conf/httpd.conf.j2 dest: /etc/httpd/conf/httpd.conf owner: "root" group: "root" mode: "0644" notify: Restart Httpd Server - name: Init Httpd Server copy: src: file/test.html.j2 dest: /var/www/html/test.html owner: "apache" group: "apache" mode: "0644" - name: Start Httpd Server service: name: httpd state: started enabled: yes handlers: - name: Restart Httpd Server service: name: httpd state: restarted
-
编写
httpd
的配置文件和主页文件:#httpd的主页文件: [root@xuzhichao playbook]# cat file/test.html.j2 ansible autodev web site #httpd的主配置文件: [root@xuzhichao playbook]# cat conf/httpd.conf.j2 Listen 8000
-
运行
playbook
:[root@xuzhichao playbook]# ansible-playbook install_httpd.yml PLAY [192.168.20.23] ***************************************************************************************************************************************** TASK [Gathering Facts] *************************************************************************************************************************************** ok: [192.168.20.23] TASK [Install Htttpd Server] ********************************************************************************************************************************* ok: [192.168.20.23] TASK [Configure Httpd Server] ******************************************************************************************************************************** changed: [192.168.20.23] TASK [Init Httpd Server] ************************************************************************************************************************************* ok: [192.168.20.23] TASK [Start Httpd Server] ************************************************************************************************************************************ changed: [192.168.20.23] RUNNING HANDLER [Restart Httpd Server] *********************************************************************************************************************** changed: [192.168.20.23] PLAY RECAP *************************************************************************************************************************************************** 192.168.20.23 : ok=6 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
-
测试
httpd
的运行情况:[root@xuzhichao playbook]# curl http://192.168.20.23:8000/test.html ansible autodev web site