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常用命令

  1. usage: ansible-playbook [-h] [--version] [-v] [-k]
  2. --ask-vault-pass # 要求提供密码
  3. --vault-password-file # 密码文件
  4. --flush-cache # 清除清单中每个主机的缓存
  5. --force-handlers # 即使任务失败也运行handlers程序
  6. --list-hosts # 输出匹配的主机列表,不进行其他操作
  7. --list-tags # 列出所有可用的标签
  8. --list-tasks # 列出将要执行的任务
  9. --private-key # 使用此文件验证ssh连接
  10. --scp-extra-args # 指定额外的参数传递给scp,如-l
  11. --sftp-extra-args # 指定额外的参数以传递给sftp
  12. --ssh-extra-args # 指定额外的参数传递给ssh,如-R
  13. --step # 每执行一步等待确认,一步一步执行
  14. --syntax-check # 在剧本上执行语法检测,但不执行
  15. -C # 不做任何改变,但预测可能发生的某些变化
  16. -D # 更改文件和模板时,显示文件差异
  17. -T # 覆盖连接超时时间,默认为10s
  18. -f # 指定要使用的并发进程数,默认为5
  19. -i # 指定清单主机路径,或使用逗号分隔的主机列表
  20. -k # 询问连接密码
  21. -v # 详细模式

playbook语法

playbook使用yaml语法格式,后缀可以是yaml或者yml。

  • 在单一一个playbook文件中,可以使用(—-)区分多个play,还有选择性的连续三个点好(...)用来表示play的结尾,也可省略。
  • 次行开始正常写playbook的内容,一般都会写上描述该playbook的功能。
  • 使用#号注释代码。
  • 缩进必须统一,不能空格和tab混用。
  • 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行实现的。
  • YAML文件内容和Linux系统大小写判断方式保持一致,是区分大小写的,k/v的值均需大小写敏感
  • k/v的值可同行写也可以换行写。同行使用:分隔。
  • v可以是个字符串,也可以是一个列表
  • 一个完整的代码块功能需要最少元素包括 name: task

示例

  1. # 创建playbook文件
  2. $ cat frist-playbook.yaml
  3. --- #固定格式
  4. - hosts: websrvs #定义需要执行主机
  5. remote_user: root #远程用户
  6. tasks: #定义一个任务的开始
  7. - name: create new file #定义任务的名称
  8. file: name=/tmp/playtest.txt state=touch #调用模块,具体要做的事情
  9. - name: install package
  10. yum: name=httpd
  11. $ ansible-playbook frist-playbook.yaml
  12. PLAY [all] ********************************************************************************************
  13. TASK [Gathering Facts] ********************************************************************************************
  14. ok: [192.168.10.10]
  15. TASK [create new file] ********************************************************************************************
  16. changed: [192.168.10.10]
  17. TASK [install package] ********************************************************************************************
  18. ok: [192.168.10.10]
  19. PLAY RECAP ********************************************************************************************
  20. 192.168.10.10 : ok=3 changed=1 unreachable=0 failed=0

playbook中的元素

主机和用户

一个playbook开始时,最先定义的就是要操作的目标主机和用户

  1. ---
  2. - hosts: 192.168.1.31
  3. remote_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中的变量

标签的使用