python自动化运维九:Playbook
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目录中去寻找.
这里有一点很奇怪。template和command不能写在同一个任务下面。否则会报错。提示语法错误
-
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的更多相关文章
- Python自动化运维的职业发展道路(暂定)
Python职业发展之路 Python自动化运维工程 Python基础 Linux Shell Fabric Ansible Playbook Zabbix Saltstack Puppet Dock ...
- Python自动化运维:技术与最佳实践 PDF高清完整版|网盘下载内附地址提取码|
内容简介: <Python自动化运维:技术与最佳实践>一书在中国运维领域将有“划时代”的重要意义:一方面,这是国内第一本从纵.深和实践角度探讨Python在运维领域应用的著作:一方面本书的 ...
- python自动化运维之CMDB篇-大米哥
python自动化运维之CMDB篇 视频地址:复制这段内容后打开百度网盘手机App,操作更方便哦 链接:https://pan.baidu.com/s/1Oj_sglTi2P1CMjfMkYKwCQ ...
- Day1 老男孩python自动化运维课程学习笔记
2017年1月7日老男孩python自动化运维课程正式开课 第一天学习内容: 上午 1.python语言的基本介绍 python语言是一门解释型的语言,与1989年的圣诞节期间,吉多·范罗苏姆为了在阿 ...
- python自动化运维学习第一天--day1
学习python自动化运维第一天自己总结的作业 所使用到知识:json模块,用于数据转化sys.exit 用于中断循环退出程序字符串格式化.format字典.文件打开读写with open(file, ...
- 【目录】Python自动化运维
目录:Python自动化运维笔记 Python自动化运维 - day2 - 数据类型 Python自动化运维 - day3 - 函数part1 Python自动化运维 - day4 - 函数Part2 ...
- python自动化运维篇
1-1 Python运维-课程简介及基础 1-2 Python运维-自动化运维脚本编写 2-1 Python自动化运维-Ansible教程-Ansible介绍 2-2 Python自动化运维-Ansi ...
- Python自动化运维 技术与最佳实践PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书
点击获取提取码:7bl4 一.内容简介 <python自动化运维:技术与最佳实践>一书在中国运维领域将有"划时代"的重要意义:一方面,这是国内第一本从纵.深和实践角度探 ...
- python自动化运维八:Ansible
Ansible是新出现的自动化运维工具,基于Python研发.糅合了众多老牌运维工具的优点实现了批量操作系统配置.批量程序的部署.批量运行命令等功能.仅需在管理工作站上安装ansible程序配置被管控 ...
随机推荐
- 在tomcat发布项目遇到的问题
今天从SVN上把系统导入本地发生了异常,问题如下: java.math.BigInteger cannot be cast to java.lang.Long 百度一番后发现是因为使用Mysql8.0 ...
- 简单说明PHP的垃圾收集机制是怎样的?【转】
原文链接: https://www.cnblogs.com/gengyi/p/6372020.html?utm_source=itdadao&utm_medium=referral. 对变 ...
- Android之观察者/被观察者模式Observer/Observable
Android 本身也是有观察者模式的.虽然项目中很多需要通知数据改变的地方,用了EventBus,但是不得不说这个观察者模式还是很好用的.最近在开发新版本的时候引用了腾讯的IM,之前写直播的时候就用 ...
- Codeforces 919 A. Supermarket
这场cf有点意思,hack场,C题等于1的特判hack很多人(我hack成功3个人,上分了,哈哈哈,咳咳...) D题好像是树形dp,E题好像是中国剩余定理,F题好像还是dp,具体的不清楚,最近dp的 ...
- Codeforces Gym101572 G.Galactic Collegiate Programming Contest (2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017))
Problem G Galactic Collegiate Programming Contest 这个题题意读了一会,就是几个队参加比赛,根据实时的信息,问你1号队的实时排名(题数和罚时相同的时候并 ...
- 精读《Function Component 入门》
1. 引言 如果你在使用 React 16,可以尝试 Function Component 风格,享受更大的灵活性.但在尝试之前,最好先阅读本文,对 Function Component 的思维模式有 ...
- 洛谷——P1331 海战
P1331 海战 题目描述 在峰会期间,武装部队得处于高度戒备.警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞机.此外,巡洋船只和舰队将被派去保护海岸线.不幸的是因为种种原因,国防 ...
- make makefile cmake qmake都是什么,有什么区别
原文:https://www.zhihu.com/question/27455963 作者:玟清链接:https://www.zhihu.com/question/27455963/answer/36 ...
- 嗅探X-Windows服务按键工具xspy
嗅探X-Windows服务按键工具xspy X-Windows完整名字是X Windows图形用户接口.它是一种计算机软件系统和网络协议.它为联网计算机提供了一个基础的图形用户界面(GUI)和丰富 ...
- java 字符串压缩长度并解压
package com.wy.data.emaildata.util; import org.apache.commons.io.FileUtils; import java.io.ByteArray ...