一、PlayBook 介绍

Ad-Hoc无法完成多条复杂命令的操作;
Ansible引进了 PlayBook 来解决复杂命令的操作;
Playbook 是⼀门语言,遵循YAML 的语法格式;

1. YAML 的特点

YAML 文件

  • 以 # 号为注释符
  • 以 .yml 或者 .yaml 为文件后缀
  • 以 —- 开始,以 … 结束,但开始和结束标志都是可选的

    2. 基本语法

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进时使用空格
  • 相同层级的元素必须左侧对齐

YAML 支持的三种数据结构:

  • 字符串
  • 列表
  • 字典

    1)字符串

    ```yaml

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 …

  1. <a name="i8jUy"></a>
  2. #### 2)列表
  3. ```yaml
  4. ---
  5. # 若熟悉Python的话,可以认为它就是Python中的List ,若熟悉C语言的话,可以认为它是C中的数组
  6. # 如何定义: 以短横线开头 + 空格 + 具体的值
  7. - red
  8. - green
  9. - blue
  10. # 以上的值假如转换成 python 的 List 会是这样:
  11. # ['red', 'green', 'blue']
  12. ...

3)字典

---
# 若熟悉 Python 的话, 可以认为它就是 Python 中的 Dict
# 如何定义: key + 冒号(:) + 空格 + 值(value), 即 key: value
name: Using Ansible
code: D1234
# 转换为 python 的 Dict
# {'name': 'Using Ansibel', 'code': 'D1234'}
...

4)混合结构

---
class:
    - name: stu1
        num: 001
    - name: stu2
        num: 002
    - name: stu3
        num: 003
# {'class': [{'name': 'stu1', 'num': 1},{'name':'stu2', 'num': 2},...]}
...

3. 验证YAML 语法

将YAML文件,通过 Python的YAML 模块验证,若不正确则报错。若正确则会输出YAML 里的内容
注意:使用时,一定确保安装了yaml 软件包

安装pip:
[root@localhost ~]# yum install python2-pip -y
安装yaml 软件包:
[root@localhost ~]# pip install pyyaml(如果pip安装需手动下载包安装)
下载地址:https://pyyaml.org/
安装文档:https://pyyaml.org/wiki/PyYAMLDocumentation
[root@localhost ~]# wget http://pyyaml.org/download/pyyaml/PyYAML-5.3.1.tar.gz
[root@localhost ~]# tar -zxvf PyYAML-5.3.1.tar.gz
[root@localhost ~]# cd PyYAML-5.3.1
[root@localhost PyYAML-5.3.1]# python setup.py install

语法验证:
[root@localhost ~]# cat myyaml.yml
image.png
[root@localhost ~]# python -c ‘import yaml,sys; print yaml.safe_load(sys.stdin)’ < myyaml.yml
image.png

二、 Playbook 的编写

1. Play 的定义

Playbook 是由⼀个或者多个Play组成

如何定义一个Play:

  • 每一个Play都是以短横线开始
  • 每一个Play都是一个YAML字典格式

    一个假想的 Play 应该是如下的样字: ```yaml


  • key1: value1 key2: value2 key3: value3 … 由于⼀个Playbook 是由⼀个或多个Play构成, ⼀个含有多个Play的Playbook 结构上如下:<br />yaml

⼀个含有3个Play 的伪PlayBook构成

  • key1: value1 key2: value2 key3: value3
  • key4: value1 key5: value2 key6: value3
  • key1: value1 key2: value2 key3: value3 … ```

    2. Play 属性

    Play中的每⼀个key,比如 key1, key2 等;这些key在PlayBook中被定义为Play的属性

    Ansible ⽀持常用Play属性 :

  • name 属性, 每个play的名字

  • hosts 属性, 每个play 涉及的被管理服务器,同ad-hoc 中的资产选择器
  • tasks 属性, 每个play 中具体要完成的任务,以列表的形式表达
  • become 属性,如果需要提权,则加上become 相关属性
  • become_user 属性, 若提权的话,提权到哪个用户上
  • remote_user属性,指定连接到远程节点的用户,就是在远程 服务器上执行具体操作的用户。若不指定,则默认使⽤当前执行 ansible Playbook 的用户

    3. 一个完整的 Playbook

    ```yaml

  • 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,并增加开机启动为例: ```yaml

    ⼀⾏的形式:

    service: name=nginx enabled=true state=started

多⾏的形式:

service: name=nginx enabled=true state=started

多⾏写成字典的形式:

service: name: nginx enabled: true state: started

<a name="j6N32"></a>
###  5. 具有多个Play 的Playbook  
```yaml

---
- 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 语法校验

[root@localhost ~]# cat hosts
image.png
[root@localhost ~]# ll nginx.conf
image.png

[root@localhost ~]# vim myplaybook.yml


---
- 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
...
[root@localhost ~]# ansible-playbook -i hosts myplaybook.yml --syntax-check    (校验)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/667991/1645964686545-02bd0d48-0c05-415a-9a01-a86427a9ca3c.png#clientId=u40ecf07d-9d47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=72&id=uf88dd220&margin=%5Bobject%20Object%5D&name=image.png&originHeight=127&originWidth=975&originalType=binary&ratio=1&rotation=0&showTitle=false&size=12665&status=done&style=none&taskId=u65015a91-4441-4de1-89c1-8c50a5dcf61&title=&width=555)

注意: 以上校验的方法,只能校验PlayBook是否正确,而不能校验YAML 文件是否语法正确

因为PlayBook 属于YAML 格式, 可同样使用检查YAML的语法方法检查PlayBook的语法正确性:
[root@localhost ~]# python -c ‘import yaml,sys; print yaml.safe_load(sys.stdin)’ < myplaybook.yml
image.png

三、PlayBook 的运行

[root@localhost ~]# ansible-playbook -i hosts myplaybook.yml
image.png
[root@localhost ~]# ps -ef | grep nginx
image.png
注意:管理主机与被管理主机之间一定要做免密互通;
如果是给管理主机安装,管理主机自身也要做免密;

PS:单步调试 PlayBook
[root@localhost ~]# ansible-playbook -i hosts myplaybook.yml —step
备注: 执行Task中的任务,需要手动确认是否往下执行

PS:测试运行 PlayBook
测试运行会执行完整个PlayBook ,但所有Task中的行为不会在远程服务器上实际执行
(即:所有执行都是模拟行为)
[root@localhost ~]# ansible-playbook -i hosts myplaybook.yml -C
备注:-C 为大写