一、 playbook简介

本质上playbook就是ansible命令的合集,是个采用YAML语言编写的脚本文件。

图解playbook:

playbook由多条play组成,每条play都有一个task对应的操作,然后调用modules,应用在主机清单host上,通过ssh远程连接,从而控制远程主机或者网络设备

ansible权威指南笔记(二)—— playbook基础_Apache

Playbook核心元素

  • Hosts:待执行的远程主机列表
  • Tasks:要做的任务集
  • Variables:内置变量或自定义变量
  • Templates:可替换模板文件中的变量并实现一些简单逻辑的文件
  • Handlers和notify:特定条件触发的操作,满足条件方才执行,否则不执行
  • tags:指定某条任务执行,用于选择运行playbook中的部分代码。

补充一句,当你把上面这些分别放在不同目录,并在总的playbook文件里调用它们,这就是后面要讨论的ansible的roles。

二、 yaml语言简介

1. 名称来源

YAML Ain't Markup Language,即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)

2. 语法简介

  • 以三个连字号 --- 作为yaml文件开头
  • 以三个点号 ... 作为yaml文件结尾(非必须)
  • 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
  • 使用#号注释代码
  • 缩进符号必须是统一的,不能空格和tab混用
  • 缩进级别也必须是一致的,程序判别配置的级别是通过缩进结合换行来实现的
  • 文件内容区分大小写,k/v的值均大小写敏感
  • 多个k/v可同行写也可换行写,同行使用:分隔
  • v可是个字符串,也可是另一个列表[]
  • 一个完整的代码块功能最少元素需包括 name 和 task
  • 一个name只能包括一个task
  • name只用于输出其中内容,task真正干活
  • YAML文件扩展名通常为yml或yaml

3. 简单示例

  • List:列表,其所有元素均使用 - 打头,列表代表同一类型的元素
# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango
  • Dictionary:字典,通常由多个key与value构成 键值对
# An employee record
name: Example Developer
job: Developer
skill: Elite

# 也可以将key:value放置于{}中进行表示,用,分隔多个key:value
# 注意逗号后面有空格
{name: Example Developer, job: Developer, skill: Elite}

三、 playbook基础用法

1. 简单例子

---
# 安装并启动http service
- hosts: websrvs
  remote_user: root

  tasks:
    - name: Install httpd
      yum: name=httpd state=present
    - name: Install configure file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/
    - name: start service
      service: name=httpd state=started enabled=yes
  • hosts:待操作主机集,可以不写,执行时通过 -i 调用host文件
  • remote_user:在远端使用哪个用户执行
  • tasks:任务集(核心)
  • name:只是一个文本提示,执行时会输出其中内容(例如输出Install httpd)
  • yum: name=httpd state=present:真正干活的部分,其实就是前篇文章中的ansible命令

2. 运行yml文件

运行playbook的方式

ansible-playbook <filename.yml> ... [options]

常见选项
    --check -C:语法检查,不真正执行操作
    --list-hosts:列出运行任务的主机
    --list-tags:列出tags
    --list-tasks:列出tasks
    --limit 主机列表:只针对主机列表中的主机执行
    -v -vv -vvv:显示过程,v越多越详细

示例

# 只检查语法
ansible-playbook hello.yml --check
# 显示运行任务的主机
ansible-playbook hello.yml --list-hosts
# 只在websrvs主机运行命令
ansible-playbook hello.yml --limit websrvs

3. shell脚本转playbook

比如以下shell脚本

#!/bin/bash
# 安装Apache
yum install --quiet -y httpd
# 复制配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp/tmp/vhosts.conf /etc/httpd/conf.d/
# 启动Apache,并设置开机启动
service httpd start
chkconfig httpd on

最简单的转法 —— 全部用shell模块实现

---
- hosts: all
  remote_user: root
  
  tasks:
    - name: "安装Apache"
      shell: yum install --quiet -y httpd
    - name: "复制配置文件"
      shell: cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
    - name: "复制配置文件"
      shell: cp/tmp/vhosts.conf /etc/httpd/conf.d/
    - name: "启动Apache"
      shell: service httpd start
    - name: "设置开机启动"
      shell: chkconfig httpd on

将各命令转为使用对应模块

---
- hosts: all
  remote_user: root
  
  tasks:
    - name: "安装Apache"
      yum: name=httpd
    - name: "复制配置文件"
      copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
    - name: "复制配置文件"
      copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/  
    - name: "启动Apache,并设置开机启动"
      service: name=httpd state=started enabled=yes

四、 handlers和notify

先看一个例子

---
- hosts: websrvs
  remote_user: root

  tasks:
    - name: Install httpd
      yum: name=httpd state=present
    - name: Install configure file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/
      notify: restart httpd    #  注意这里
    - name: ensure apache is running
      service: name=httpd state=started enabled=yes
  
  handlers:                    #  注意这里
    - name: restart httpd      # 这个名字跟notify后一定是对应的
      service: name=httpd state=restarted

实际上它们就是一个触发器,当notify的前一行(copy: src=files/httpd.conf dest=/etc/httpd/conf/)被执行,notify就会被触发,进而调用其后的restart httpd部分。而restart httpd部分内容是什么,就在下面的handlers中定义。

所以上面代码想实现的功能其实是:当ansible主机上的httpd.conf配置文件有改动,执行了copy操作时(如果没有改动则copy语句不会被执行到),触发重启httpd服务的操作,使配置自动生效。

handlers和notify可以有多个,例如:

---
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: add group nginx
      tags: user
      user: name=nginx state=present
    - name: add user nginx
      user: name=nginx state=present group=nginx
    - name: Install Nginx
      yum: name=nginx state=present
    - name: config
      copy: src=/root/config.txt dest=/etc/nginx/nginx.conf
      notify:
        - Restart Nginx
        - Check Nginx Process
  
  handlers:
    - name: Restart Nginx
      service: name=nginx state=restarted enabled=yes
    - name: Check Nginx process
      shell: killall -0 nginx > /tmp/nginx.log

---
- hosts: hbhosts
  remote_user: root
  
  tasks:
    - name: ensure heartbeat latest version
      yum: name=heartbeat state=present
    - name: authkeys configure file
      copy: src=/root/hb_conf/authkeys dest=/etc/ha.d/authkeys
    - name: authkeys mode 600
      file: path=/etc/ha.d/authkeys mode=600
      notify:
        - restart heartbeat
    - name: ha.cf configure file
      copy: src=/root/hb_conf/ha.cf dest=/etc/ha.d/ha.cf
      notify:
        - restart heartbeat
  handlers:
    - name: restart heartbeat
      service: name=heartbeat state=restarted

五、 tags

tags 可以为某个或多个命令添加一个标签,添加标签后,可以指定只执行该标签相关命令。

示例:httpd.yml

---
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: Install httpd
      yum: name=httpd state=present
      tage: install 
    - name: Install configure file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/
      tags: conf
    - name: start httpd service
      service: name=httpd state=started enabled=yes
      tags: service

# 指定执行install,conf 两个标签对应命令
ansible-playbook –t install,conf httpd.yml

综合例子

---
- hosts: testsrv
  remote_user: root
  tags: inshttpd
  tasks:
    - name: Install httpd
      yum: name=httpd state=present
    - name: Install configure file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/
      tags: rshttpd
      notify: restart httpd
  handlers:
    - name: restart httpd
      service: name=httpd status=restarted

ansible-playbook -t rshttpd httpd2.yml

六、 变量

1. 命名规则

变量名仅能由字母、数字和下划线组成,且只能以字母开头。

2. 变量定义与调用

  • 系统自带变量

ansible setup facts 远程主机的所有变量都可直接调用

# 查询主机名
ansible all -m setup -a 'filter="ansible_nodename"'
# 查询主机内存大小
ansible all -m setup -a 'filter="ansible_memtotal_mb"'
# 查询系统版本
ansible all -m setup -a 'filter="ansible_distribution_major_version"'
# 查询主机cpu个数
ansible all -m setup -a 'filter="ansible_processor_vcpus"'

通过{{ var_name }} 调用变量,变量名前后可以加空格,有时用"{{ var_name }}"才生效

# 示例:使用setup变量 var.yml
---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: create log file
      file: name=/var/log/ {{ ansible_fqdn }} state=touch

# 执行playbook 
ansible-playbook var.yml
  • host文件中定义变量

主机变量

vim /etc/ansible/hosts
[appsrvs]
192.168.38.17 http_port=817 name=www
192.168.38.27 http_port=827 name=web

# 调用变量
# 更改主机名为各自被定义的变量 
ansible appsrvs -m hostname -a'name={{ name }}'

组变量

vim /etc/ansible/hosts

[appsrvs]
192.168.38.17 http_port=817 name=www
192.168.38.27 http_port=827 name=web

[appsrvs:vars]
make="-"

# ansible调用变量
ansible appsrvs -m hostname -a 'name={{name}}{{mark}}{{http_port}}'
  • 通过命令行指定变量
### vi var.yml
---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: install package
      yum: name={{ pkname }} state=present

# 执行playbook
ansible-playbook –e pkname=httpd var.yml
  • playbook中定义
### 示例:playbook定义变量 var.yml
---
- hosts: websrvs
  remote_user: root
vars:
  - username: oracle
  - groupname: oinstall
tasks:
  - name: create group
    group: name={{ groupname }} state=present
  - name: create user
    user: name={{ username }} state=present

# 调用playbook
ansible-playbook var.yml
ansible-playbook -e "username=user2 groupname=group2" var.yml
  • 在独立的变量yml文件中定义
vim vars.yml

pack: vsftpd
service: vsftpd

# 引用变量文件
vars_files:
  - vars.yml
  • 在role中定义:后面介绍,其实也是在yml文件中定义

参考:

《ansible权威指南》

https://www.bilibili.com/video/BV1HZ4y1p7Bf?from=search&seid=13215158654353304589&spm_id_from=333.337.0.0

有道云笔记