playbook:
playbook 由一个或多个 ‘plays’ 组成.它的内容是一个以 ‘plays’ 为元素的列表.
在 play 之中,一组机器被映射为定义好的角色.在 ansible 中,play 的内容,被称为 tasks,即任务.在基本层次的应用中,一个任务是一个对 ansible 模块的调用
Playbooks 的格式是YAML,语法做到最小化. 首先来介绍下YAML语法
YAML:
每一个 YAML 文件都是从一个列表开始. 列表中的每一项都是一个键值对, 通常它们被称为一个 “哈希” 或 “字典”. 所以, 我们需要知道如何在 YAML 中编写列表和字典. YAML 还有一个比较奇怪的地方. 所有的 YAML 文件(无论和 Ansible 有没有关系)开始行都应该是 ---. 这是 YAML 格式的一部分, 表明一个文件的开始.
列表中的所有成员都开始于相同的缩进级别, 并且使用一个 "- " 作为开头(一个横杠和一个空格):
---
#一个关于变成语言的列表
- python
- c++
- java
对应的Python 结果为:[‘python’,’c++’,’java’]
再来看一个块结构的表示方法
-
- python
- c++
- java
-
- mysql
- mongodb
对应的python结果:
[[‘python’,’c++’,’java’],[‘mysql’,’mongodb’]]
一个字典是由一个简单的 键: 值 的形式组成(这个冒号后面必须是一个空格):
---
# 一个出版书籍的记录
publish:
 name: Publisher
 city: chengdu
 province: sichuan
author:
 name: zhf
 age: 32
对应的python结果:
{‘publish’:{‘name’: ’Publisher’,’city’: ’chengdu’,’province’: ’sichuan’},’author’:{‘name’: ‘zhf’,’age’: 32}}
字典也可以使用缩进形式来表示, 如果你喜欢这样的话:
{name: Publisher,city: chengdu,province: sichuan}
从上面这些可以看出,YAML其实和JSON的格式很接近

回到playbook我们来看下tasks列表

每一个 play 包含了一个 task 列表(任务列表).一个 task 在其所对应的所有主机上(通过 host pattern 匹配的所有主机)执行完毕之后,下一个 task 才会执行.有一点需要明白的是(很重要),在一个 play 之中,所有 hosts 会获取相同的任务指令,这是 play 的一个目的所在,也就是将一组选出的 hosts 映射到 task

在运行 playbook 时(从上到下执行),如果一个 host 执行 task 失败,这个 host 将会从整个 playbook 的 rotation 中移除. 如果发生执行失败的情况,请修正 playbook 中的错误,然后重新执行即可.

下面我们来看一个task的具体例子:

---

- hosts: webservers

remote_user: root

tasks:

- name: for playbook test

apt: name=curl state=latest

在这个例子中,host的地址为webservers中定义的主机IP。remote_user: root代表已root用户执行

tasks:就是具体的任务 其中name为任务的名称, apt 就是ansible的远程命令模块 其中包含2个参数。name=curl代表要下载的软件名称,state=latest表示下载最新的

运行结果如下:任务成功执行并且在192.168.0.9上安装了curl软件包。其中TASK[for playbook test]就是我们这个任务的名称

root@zhf-linux:/home/zhf/zhf/python_prj/auto_manintance# ansible-playbook test.yml -f 10

PLAY
***************************************************************************

TASK
[setup]
*******************************************************************

ok:
[192.168.0.9]

TASK
[for playbook test]
*******************************************************

changed:
[192.168.0.9]

PLAY
RECAP
*********************************************************************

192.168.0.9
: ok=2 changed=1 unreachable=0 failed=0

我们再来看另外一个例子:在这个yml文件中。task中采用了command模块。command模块和shell模块比较特殊,它们不使用key=value的格式
而是直接使用命令。但是还是带有自有的一些参数。比如chdi/home/zhf/zhf就是指定切换到的目录。后面直接跟上rm
tcpdumpresult.txt的命令删除文件

---

-
hosts: webservers

remote_user:
root

tasks:

-
name: for playbook test

command:
chdir=/home/zhf/zhf rm tcpdumpresult.txt

运行结果:

PLAY
***************************************************************************

TASK
[setup]
*******************************************************************

ok:
[192.168.0.9]

TASK
[for playbook test]
*******************************************************

changed:
[192.168.0.9]

[WARNING]:
Consider using file module with state=absent rather than running rm

PLAY
RECAP
*********************************************************************

192.168.0.9
: ok=2 changed=1 unreachable=0 failed=0

在这个提示中,有一个warning:Consider
using file module with state=absent rather than running rm

这个的意思是让我们使用file模块
然后设置state=absent就可以删除文件。如果改成file模块使用的话yaml改成如下:

file:
path=/home/zhf/zhf state=absent

我们再看一个template的模块调用方法。在做很多功能配置的时候,涉及到大量的配置文件的修改和替换。template就是用来完成这一功能的。官方翻译:template使用了Jinjia2格式作为文件模版,进行文档内变量的替换的模块。它的每次使用都会被ansible标记为”changed”状态。

例子:这个讲实现将本端的test1.yml文件内容渲染到远端主机的test1.yml文件中去

---

- hosts: webservers

remote_user: root

tasks:

- name: use template function

template: src=/home/zhf/zhf/python_prj/auto_manintance/test1.yml dst=/home/zhf/zhf/test1.yml

其实在task中都是调用ansible中的命令模块来触发操作的。ansible有很多模块。如果在主机上查询的花可以使用ansible-doc
-s file的方式进行查询。
ansible-doc是查询命令。
-s后面接的是模块命令

或者也可以到网上查询网址是:http://docs.ansible.com/ansible/latest/modules_by_category.html

这里面有所有的ansible命令介绍。

在YAML中还可以使用变量。通过vars:定义变量。在具体使用变量的过程中两个双括号包含变量。例子如下:

---

-
hosts: webservers

vars:

filename:
tcpdumpresult.txt

remote_user:
root

tasks:

-
name: for playbook test

command:
chdir=/home/zhf/zhf rm {{ filename }}

下面将介绍下handlers;

当我们再完成一些服务配置的时候往往会重启服务或者进行恢复。所以当远端系统被人改动时,可以重放 playbooks 达到恢复的目的。当发生改动时’notify’ actions 会在 playbook 的每一个 task 结束时被触发

下面的这个例子是在安装vsftpd后重启动这个服务。类似的只要执行结果中changed=1的都会触发notify操作。

---

- hosts: webservers

remote_user: root

tasks:

- name: for notify function test

apt: name=vsftpd state=latest

notify:

- restart vsftpd

include语句和角色:

首先来看下include语句,在用playbook实现一个很复杂的功能的时候,有可能会写一个很大的文件。而且这些文件的某些task在其他yml文件中也是被重用的。这样就没必要在每个yml中都去实现这些功能,这样效率也很低,我们应该想在编写软件代码的时候去组织这些文件。这里就需要用到include语句。include可以引用其他yml文件中的play。这种方式也被称为封装,将某些具体的功能给封装起来。我们来看一个例子,以前面删除文件的play来做示例。

首先来看test.yml。在task里面没有实现具体的操作。而是包含了test1.yml文件

---

-
hosts: webservers

remote_user:
root

tasks:

-
name: to verify include function

include:
test1.yml

再来看下test1.yml文件。里面没有了hosts和remote_user等配置,而只是由普通的task列表组成。

---

-
name: test1.yml to delete the file

command:
rm /home/zhf/test2.txt

来看下执行结果:

root@zhf-linux:/home/zhf/zhf/python_prj/auto_manintance#
ansible-playbook test.yml -f 10

PLAY
***************************************************************************

TASK
[setup]
*******************************************************************

ok:
[192.168.0.9]

TASK
[to verify include function]
**********************************************

included:
/home/zhf/zhf/python_prj/auto_manintance/test1.yml for 192.168.0.9

TASK
[test1.yml to delete the file]
********************************************

changed:
[192.168.0.9]

[WARNING]:
Consider using file module with state=absent rather than running rm

PLAY
RECAP
*********************************************************************

192.168.0.9
: ok=3 changed=1 unreachable=0 failed=0

从task的name来看,先执行test.yml.
然后调用test1.yml文件执行

我们在include的时候还可以往里面传递参数

tasks:

-
name: to verify include function

include:
test1.yml path=/home/zhf/

然后在test1.yml中通过{{
path }}来使用path.
同样的你也可以在handler中去引用文件

notify:

-
include: test1.yml

Role(角色):

现在已经学过 tasks
和 handlers,那怎样组织
playbook
才是最好的方式呢?简单的回答就是:使用
roles
! Roles 基于一个已知的文件结构,去自动的加载某些
vars_files,tasks
以及 handlers。基于
roles
对内容进行分组,使得我们可以容易地与其他用户分享
roles

我们来看一个例子:
在一个工程里面有2个角色。一个是dele
一个是添加。分别实现删除文件和添加文件。我们建立如下文件目录:

1
group_vars: 其中定义全局变量,所有的角色都可以使用

2
hosts定义主机的参数,否则默认使用/etc/ansible/hosts的参数。自定义参数通过ansible-playbook
-i hosts来调用

3
role: 角色文件夹。其中包含2个角色
add和dele.
在个2角色下分别有handlers,
tasks,templates和vars文件夹。里面包含了各自的yml文件。角色中的vasrs里面的变量优先级高于group_vars中的变量

4
test.yml为整个程序的入口。从test.yml中引用具体的角色

一 首先我们来定义hosts文件。在里面添加主机IP

[webservers]

192.168.0.9

二 全局配置文件 test.yml. 在里面定义了2个角色分别是add和dele. 将分别对这个2角色进行调用

---

- name: add function for role test

hosts: webservers

roles:

- add

- name: dele function for dele test

hosts: webservers

roles:

- dele

三 角色add的定义:

[handers/main.yml]

- name: restart ftp

service: name=vsftpd state=restarted

[tasks/main.yml]

首先新建一个ftp_confg.conf文件。然后通过template命令将本段的ftp配置渲染到主机上的新建的文件

其中template中的src不用制定路径,默认在上级的templates目录中去寻找.
这里有一点很奇怪templatecommand不能写在同一个任务下面。否则会报错。提示语法错误

-
name: add the configration of FTP

command:
chdir=/home/zhf touch ftp_config.conf.j2

-
name: to template the file

template:
src=ftp.conf.j2 dest=/home/zhf/ftp_config.conf.j2

[vars/main.yml]

定义FTP服务主机IP

---

ftpserver:
192.168.0.9

定义模板文件

[templates/ftp.conf.j2]

server
{{ ftpserver }}

四 角色dele的定义:

task中删除掉之前建立的ftp_config.conf.j2

[task/main.yml]

-
name: dele the configration of FTP

command:
chdir=/home/zhf rm ftp_config.conf.j2

[handlers/main.yml]

-
name: after dele the conf then restart FTP

service:
name=vsftpd state=restarted

运行结果如下:

root@zhf-linux:/home/zhf/zhf/python_prj/role_test#
ansible-playbook -i hosts test.yml -f 10

PLAY
[add function for role test]
**********************************************

TASK
[setup]
*******************************************************************

ok:
[192.168.0.9]

TASK
[add : add the configration of FTP]
***************************************

changed:
[192.168.0.9]

[WARNING]:
Consider using file module with state=touch rather than running

touch

TASK
[add : to template the file]
**********************************************

changed:
[192.168.0.9]

PLAY
[dele function for dele test]
*********************************************

TASK
[setup]
*******************************************************************

ok:
[192.168.0.9]

TASK
[dele : dele the configration of FTP]
*************************************

changed:
[192.168.0.9]

[WARNING]:
Consider using file module with state=absent rather than running rm

PLAY
RECAP
*********************************************************************

192.168.0.9
: ok=5 changed=3 unreachable=0 failed=0

最后来介绍下playbook的循环和条件执行方法:

通常一个任务会做很多事情。如创建大量的用户和文件。安装很多包等。通过with_items方法可以帮助我们循环执行任务。参考下面的例子:

command:
chdir=/home/zhf touch {{ item }}.txt
这句中的item来自与with_items中的变量分别是test4和test5

root@zhf-linux:/home/zhf/zhf/python_prj/auto_manintance#
cat test2.yml

---

-
hosts: webservers

remote_user:
root

tasks:

-
name: create file by batch

command:
chdir=/home/zhf touch {{ item }}.txt

with_items:

-
test4

-
test5

这个示例与下面是等价的:

-
name: create file by batch

command:
chdir=/home/zhf touch test4.txt

-
name: create file by batch

command:
chdir=/home/zhf touch test5.txt

另外还可以嵌套循环:

-
name: create file by batch

command:
chdir=/home/zhf touch {{ item[0] }}.txt rm {{ item[1] }}

with_nested:

-
[‘test3’,’test4’]

-
[‘test5’]

对哈希使用循环:

假如你有以下变量:

---
users:
alice:
name: Alice Appleworth
telephone: 123-456-7890
bob:
name: Bob Bananarama
telephone: 987-654-3210

你想打印出每个用户的名称和电话号码.你可以使用 with_dict 来循环哈希表中的元素:

tasks:
- name: Print phone records
debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"
with_dict: "{{users}}"

对文件列表使用循环:

---
- hosts: all tasks: # first ensure our target directory exists
- file: dest=/etc/fooapp state=directory # copy each file over that matches the given pattern
- copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600
with_fileglob:
- /playbooks/files/fooapp/*
其他循环方式可以参考:http://ansible-tran.readthedocs.io/en/latest/docs/playbooks_loops.html#looping-over-hashes

python自动化运维九:Playbook的更多相关文章

  1. Python自动化运维的职业发展道路(暂定)

    Python职业发展之路 Python自动化运维工程 Python基础 Linux Shell Fabric Ansible Playbook Zabbix Saltstack Puppet Dock ...

  2. Python自动化运维:技术与最佳实践 PDF高清完整版|网盘下载内附地址提取码|

    内容简介: <Python自动化运维:技术与最佳实践>一书在中国运维领域将有“划时代”的重要意义:一方面,这是国内第一本从纵.深和实践角度探讨Python在运维领域应用的著作:一方面本书的 ...

  3. python自动化运维之CMDB篇-大米哥

    python自动化运维之CMDB篇 视频地址:复制这段内容后打开百度网盘手机App,操作更方便哦 链接:https://pan.baidu.com/s/1Oj_sglTi2P1CMjfMkYKwCQ  ...

  4. Day1 老男孩python自动化运维课程学习笔记

    2017年1月7日老男孩python自动化运维课程正式开课 第一天学习内容: 上午 1.python语言的基本介绍 python语言是一门解释型的语言,与1989年的圣诞节期间,吉多·范罗苏姆为了在阿 ...

  5. python自动化运维学习第一天--day1

    学习python自动化运维第一天自己总结的作业 所使用到知识:json模块,用于数据转化sys.exit 用于中断循环退出程序字符串格式化.format字典.文件打开读写with open(file, ...

  6. 【目录】Python自动化运维

    目录:Python自动化运维笔记 Python自动化运维 - day2 - 数据类型 Python自动化运维 - day3 - 函数part1 Python自动化运维 - day4 - 函数Part2 ...

  7. python自动化运维篇

    1-1 Python运维-课程简介及基础 1-2 Python运维-自动化运维脚本编写 2-1 Python自动化运维-Ansible教程-Ansible介绍 2-2 Python自动化运维-Ansi ...

  8. Python自动化运维 技术与最佳实践PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书

    点击获取提取码:7bl4 一.内容简介 <python自动化运维:技术与最佳实践>一书在中国运维领域将有"划时代"的重要意义:一方面,这是国内第一本从纵.深和实践角度探 ...

  9. python自动化运维八:Ansible

    Ansible是新出现的自动化运维工具,基于Python研发.糅合了众多老牌运维工具的优点实现了批量操作系统配置.批量程序的部署.批量运行命令等功能.仅需在管理工作站上安装ansible程序配置被管控 ...

随机推荐

  1. dedecms--二次开发之前后台登录分开

    最近在写dedecms系统下会员功能二次开发,然后发现在本地测试的时候每次登录后台,管理员帐号都会在前台页面也显示登录了,但是如果真的是在前台页面用管理员账号登录的话那是登陆不了的,所以我觉得这样的效 ...

  2. kafka优化–JVM参数配置优化

    https://blog.csdn.net/u013063153/article/details/73826403

  3. js 路径改变时获取url参数

    当我们在使用react或vue的router作路由跳转时,为了保持菜单与地址栏状态一致,我们可以使用window.onhashchange捕获#后面的变化 window.onhashchange = ...

  4. mac下 JMeter 4.0 进行多用户接口压力测试

    1.最近在做公司的内部系统,需要进行多用户压力测试,于是上网在官网下载了Jmeter 压缩包,并放在指定的目录解压,打开解压后文件夹到bin目录下: 执行sh jmeter  Jmeter就启动起来了 ...

  5. jsp网页在浏览器中不显示图片_eclipse环境下配置tomcat中jsp项目的虚拟路径

    遇到的问题是这种,在jsp网页中嵌入了本地的图片,由于会用到上传到服务器的图片,所以没有放到项目里面,而是把全部图片单独放到一个文件夹里,然后打算使用绝对路径把要显示的图片显示出来.比方是放在了E盘的 ...

  6. IOS 开发推荐经常使用lib

    1. Mantle Mantle 让我们能简化 Cocoa 和 Cocoa Touch 应用的 model 层.简单点说.程序中常常要进行网络请求,请求到得通常是 json 字符串.我们通常会建一个 ...

  7. C - The C Answer (2nd Edition) - Exercise 1-16

    /* Revise the main routine of the longest-line program so it will correctly print the length of arbi ...

  8. 【Python】输出程序运行的百分比

    对于一些大型的Python程序.我们须要在命令行输出其百分比,显得更加友好,以免被人误会程序陷入死循环.假死的窗口. 关键是利用到不换行的输出符\r,\r的输出.将直接覆盖掉此行的内容. 比方例如以下 ...

  9. d3js 添加数据

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  10. poj 1651 Multiplication Puzzle【区间DP】

    题目链接:http://poj.org/problem? id=1651 题意:初使ans=0,每次消去一个值,位置在pos(pos!=1 && pos !=n) 同一时候ans+=a ...