Playbook介绍

根本上说playbook和shell脚本没有任何的区别,playbook就像shell一样,也是把一堆的命令组合起来,然后加入对应条件判断等等,在shell脚本中是一条一条的命令,而在playbook中是一个一个的task任务构成,每个task任务可以看做shell中的一条命令;shell脚本一般只是在当前服务器上执行,而playbook则是在不止一个服务器上执行,因此playbook需要在其中指定运行该playbook的服务器名。

playbook的语法结构

playbook使用yml标记语言,这是一种标记语言,这种标记语言在文件的最开始需要使用三个“-”来说明文件开始,然后使用缩进来说明代码块的范围。下面通过一个简易的实例,来说明playbook的语法。

1.大小写敏感
2.使用缩进表示层级关系
3.缩进时不允许使用Tab键,只允许使用空格。
4.缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
基本语法案例

---                             #标记文件的开始
- hosts: webservers             #指定该playbook在哪个服务器上执行
  vars:                         #表示下面是定义的变量,
    http_port: 80               #变量的形式,key: value,这里http_port是变量名,80是值
    max_clients: 200
  remote_user: root             #指定远程的用户名,这里缩进和vars保持了一致,说明变量的代码块已经结束。

tasks:              #下面构成playbook的tasks,每个task都有 - name: 开始,name指定该任务的名称。
- name: ensure apache is at the latest version  #指定该任务的名称。
    yum: pkg=httpd state=latest                   #yum说明要是用的模板名称,后面指定对应的参数,这两行结合起来就相当于一个shell命令。
- name: write the apache config file            #每个task之间可以使用空行来做区分。
    template: src=/srv/httpd.j2 dest=/etc/httpd.conf

实例

检查mysql状态

[root@test2 playbook]# cat test.yml
---
 - hosts: all
   remote_user: root
   gather_facts: no             #不收集对应主机的信息,这样运行会快点。
   tasks:
     - name: check the mysql stauts
       service: name=mysqld state=running

通过ansible-playbook --syntax-check检测语法

[root@master playbook]# ansible-playbook --syntax-check test.yml 
[WARNING]: Unable to parse /etc/ansible/inventory as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: test

playbook: test.yml ## 出现这个没报错即可使用

空运行:-C参数 会报告改操作对主机的更改内容,但不会实际操作主机。

运行结果如下:[root@master~ playbook]# ansible-playbook test.yml


PLAY [all] ********************************************************************


TASK: [check the mysql stauts] ************************************************
ok: [192.168.143.30]




PLAY RECAP ********************************************************************
192.168.143.30        : ok=1    changed=0    unreachable=0    failed=0

限定主机范围执行

虽然playbook中定义了执行的主机,但是有时候我们可能仅想在定义的主机中的部分机器上执行,这时候怎么办?修改playbook中的hosts的范围,但是每次改变主机就修改一次,比较麻烦,我们可以使用–limit参数,指定该playbook在指定的主机上执行。有以下inventory文件,我们想在dbservers上执行上面测试用的playbook内容。

[all]
192.168.143.30
192.168.143.50

[mysql]
192.168.143.40

运行结果如下:

[root@test2 playbook]# ansible-playbook test.yml --limit mysql


PLAY [all] ********************************************************************


TASK: [check the mysql stauts] ************************************************
ok: [192.168.143.40]


PLAY RECAP ********************************************************************
192.168.143.40              : ok=1    changed=0    unreachable=0    failed=0


[root@test2 playbook]#

查看当前playbook在哪些主机上执行

[root@test2 playbook]# ansible-playbook test.yml --list-hosts


playbook: test.yml


  play #1 (all): host count=3
192.168.143.30
192.168.143.40
192.168.143.50

ansible-playbook的一些其他技巧

–inventory=path,指定inventory文件,默认是在/etc/ansible/hosts下面。

–verbose,显示详细的输出,使用-vvvv显示精确到每分钟的输出。

–extra-vars=vars:定义在playbook使用的变量。

–forks:指定并发的线程数,默认是5.

–connection=type:指定远程连接主机的方式,默认是ssh,设置为local时,则只在本地执行playbook、

–check:检测模式,playbook中定义的所有任务将在每台主机上检测,但是并不执行。

ansibleplaybook中的handlers
在系统中,我们修改了服务器的配置文件,这时候就需要重启操作服务,就可以使用到handlers.

handlers:                               #下面定义了两个handlers
    - name: restart mysql
      service:  name=mysql state=restarted
    - name: restart httpd
      service: name=httpd state=restarted


- name: template configuration file
  template: src=template.j2 dest=/etc/httpd/conf/httpd.conf  #修改了配置文件然后依次启动mysql和httpd服务。
  notify:                               #使用notify来声明引用handlers。
     - restart mysql
     - restart htttpd

在使用handlers时需要注意以下几点:

Handlers只有在其所在的任务被执行时,才会被运行;如果一个任务中定义了notify调用Handlers,但是由于条件判断等原因,该任务未被执行,那么Handlers同样不会被执行。

Handlers只会在每一个play的末尾运行一次;如果想在一个playbook中间运行Handlers,则需要使用meta模块来实现。例如:-meta: flush_handlers.

如果一个play在运行到调用Handlers的语句之前失败了,那么这个Handlers将不会被执行。我们可以使用meta模块的–force-handlers选项来强制执行Handlers,即使Handlers所在的play中途运行失败也能执行。