Ansible之Playbook
Posted 礁之
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ansible之Playbook相关的知识,希望对你有一定的参考价值。
文章目录
一、Playbook概述
(1)Playbook简介
-
Playbook又叫做剧本,Playbook与ad-hoc相比,是一种完全不同的允许ansible的方式,类似于shell脚本。ad-hoc无法持久使用,而playbook可以持久使用
-
playbook是由一个或者多个play组成的列表,play的主要功能是在于将事先归并为一组的主机,装扮成事先通过ansible中的task定义好的角色,从根本上来讲,所谓的task无非就是调用ansible的一个模块,将多个play组织在一个playbook中,最终的目的是让它们联合起来按照事先编排的机制完成某一个任务
-
playbook可以指定主机组,指定的主机组会执行task,而task就是调用多个ansible的模块,这个类似于shell的脚本
(2)Playbook核心元素
- Hosts执行的远程主机的列表,可以指定多个主机组
- Tasks任务集,任务集中会调用各种ansible模块
- Variables内置变量或者自定义变量在playbook中调用
- Templates模板,使用模板语法的文件,比如配置文件,以.conf结尾的文件是无法直接调用变量的,但是使用模板语法的文件可以直接调用变量
- Handlers和notity结合使用,即触发器和动作,由特定的条件触发的操作,满足条件才会执行,否则不执行
- tags标签,tasks任务集中每次调用模块都可以写一个标签,用户可以通过标签来执行单条命令,因为playbook默认是全部执行的
(3)Playbook语法
-
playbook使用yaml语法格式,所以文件后缀为.yaml或者.yml
-
剧本的语法规则
-
每个play开头都需要打—,也可以使用…来表示play的结尾,也可以省略
-
在第二行开始正常写剧本的内容,一般都会写上该剧本的功能
-
使用#可以注释代码
-
缩进必须统一,不能和空格、tab混用
-
缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行实现的
-
YAML文件内容和Linux系统大小写判断方式一致,是区分大小写的,字典中key和value的值都需要区分大小写
-
字典中的key和value可以同行写也可以换行写,同行写使用”:“来分割
-
和python一样,字典中的value的值可以是字符串也可以是列表
-
一个完整的代码块功能至少需要两个元素,分别是name和task
-
(4)剧本格式示例
[root@ansible ~]# vim /etc/ansible/hosts #修改hosts文件
。。。。。。
[web]
192.168.100.203
[data]
192.168.100.204
#保存退出
[root@ansible ~]# vim playbook.yaml #编写剧本
---
- hosts: web
remote_user: root
vars:
http_port: 8080
tasks:
- name: 使用yum安装httpd
yum: name=httpd state=installed
- name: 启动httpd
service: name=httpd state=started
- name: 编写httpd网页
copy: content="192.168.100.203" dest=/var/www/html/index.html
- hosts: data
remote_user: root
tasks:
- name: 在root下创建一个aaa.txt文件
file: path=/root/aaa.txt state=touch
- name: 往aaa.txt文件中写入内容
copy: content="aaaaaaaaaaaa" dest=/root/aaa.txt
[root@ansible ~]# ansible-playbook -C playbook.yaml #执行剧本前先使用-C监测是否有问题
PLAY [web] ******************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [使用yum安装httpd] *********************************************************************************************************************
changed: [192.168.100.203]
TASK [启动httpd] **************************************************************************************************************************
changed: [192.168.100.203]
TASK [编写httpd网页] ************************************************************************************************************************
changed: [192.168.100.203]
PLAY [data] *****************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.204]
TASK [在root下创建一个aaa.txt文件] **************************************************************************************************************
changed: [192.168.100.204]
TASK [往aaa.txt文件中写入内容] ******************************************************************************************************************
changed: [192.168.100.204]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=4 changed=3 unreachable=0 failed=0
192.168.100.204 : ok=3 changed=2 unreachable=0 failed=0
[root@ansible ~]# ansible-playbook playbook.yaml #执行剧本
PLAY [web] ******************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [使用yum安装httpd] *********************************************************************************************************************
changed: [192.168.100.203]
TASK [启动httpd] **************************************************************************************************************************
changed: [192.168.100.203]
TASK [编写httpd网页] ************************************************************************************************************************
changed: [192.168.100.203]
PLAY [data] *****************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.204]
TASK [在root下创建一个aaa.txt文件] **************************************************************************************************************
changed: [192.168.100.204]
TASK [往aaa.txt文件中写入内容] ******************************************************************************************************************
changed: [192.168.100.204]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=4 changed=3 unreachable=0 failed=0
192.168.100.204 : ok=3 changed=2 unreachable=0 failed=0
剧本中可以自定义变量,但是引用到文件的话是需要使用jinjia2模板的
[root@node1 ~]# scp /etc/httpd/conf/httpd.conf root@192.168.100.202:/root #先把203上的配置文件传到ansible主机上
[root@ansible ~]# mv httpd.conf httpd.conf.j2 #修改名称
[root@ansible ~]# vim httpd.conf.j2 #修改文件内容
。。。。。。
42 Listen http_port #想要使用变量就需要使用两个括起来,中间写变量名称
。。。。。。
#保存退出
[root@ansible ~]# vim playbook02.yaml #写一个新的剧本
---
- hosts: web
remote_user: root
vars:
http_port: 8080
tasks:
- name: 复制httpd的主配置文件
template: src=/root/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
- name: 重新启动httpd
service: name=httpd state=restarted
#保存退出
[root@ansible ~]# ansible-playbook -C playbook02.yaml #监测剧本是否有问题
PLAY [web] ******************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [复制httpd的主配置文件] ********************************************************************************************************************
changed: [192.168.100.203]
TASK [重新启动httpd] ************************************************************************************************************************
changed: [192.168.100.203]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=3 changed=2 unreachable=0 failed=0
[root@ansible ~]# ansible-playbook playbook02.yaml #执行剧本
PLAY [web] ******************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [复制httpd的主配置文件] ********************************************************************************************************************
changed: [192.168.100.203]
TASK [重新启动httpd] ************************************************************************************************************************
changed: [192.168.100.203]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=3 changed=2 unreachable=0 failed=0
[root@ansible ~]# curl 192.168.100.203:8080 #验证效果
192.168.100.203
[root@ansible ~]# ansible 192.168.100.204 -m shell -a 'cat /root/aaa.txt'
192.168.100.204 | SUCCESS | rc=0 >>
aaaaaaaaaaaa
(5)Playbook的运行方式
[root@ansible ~]# ansible-playbook -h #查看帮助信息
#ansible-playbook常用选项:
--check 或者 -C #监测剧本是否有问题,不会真正进行操作
--list-hosts #列出剧本中要执行任务的主机
--list-tags #列出剧本中所有定义的标签
--list-tasks #列出剧本中定义的所有任务集
--limit #主机列表,只针对主机列表中的某个主机或者某个组执行
-f #指定并发数,默认为5个
-t #指定标签运行,运行某一个或多个标签,前提是剧本中有定义标签
-v #显示过程,使用vv和vvv会更加详细
二、剧本中的元素属性
-主机与用户
-
在一个剧本开始时,最先定义的是要操作的主机和用户
-
标准格式:
--- #固定格式
- hosts: web #指定主机组或者主机,主机的话写ip就行
remote_user: root #指定使用远程主机的那个用户执行剧本的任务
- 也可以在某一个tasks中定义执行该任务的远程用户
tasks:
- name: 测试
remote_user: aaa #指定执行用户为aaa
shell: pwd
- 使用sudo授权用户执行任务
tasks:
- name: 测试
remote_user: aaa #指定执行用户为aaa
sudo: yes #表示使用sudo授权
shell: pwd
-tasks任务列表
- 每一个task必须有一个名称name,这样在运行playbook的时候,从其输出的任务执行信息中可以很清楚的辨别该任务是属于哪一个task的,如果没有定义name,action的值将会用做输出信息中标记对应的task
- 每一个playbook中可以包含一个或者多个tasks任务列表,每一个tasks完成具体的一件事,比如创建一个用户或者安装一个软件等,在hosts中定义的主机或者主机组都将会执行该hosts对应的task任务列表
tasks:
- name: create new file #创建aaa文件
file: path=/opt/aaa state=touch
- name: create new user #创建新用户aaa
user: name=abc state=present
-Handlers动作与Notify触发
- 很多时候当某一个配置发现改变时,通常需要重启服务,例如httpd的主配置文件发生改变了,就需要重启服务使配置生效,而这个时候在剧本中就可以用handlers和notify做一个“触发器”,一旦httpd的主配置文件发生改变,就会触发,然后进行动作,重启服务
[root@ansible ~]# vim playnook01.yaml #编写剧本
---
#这是一个用于安装httpd的剧本
- hosts: web
remote_user: root
tasks:
- name: 安装httpd
yum: name=httpd state=installed
- name: 修改配置文件
template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: #触发
- restart httpd #这个触发的名称是自定义的,表示这个触发的名称是restart httpd
- name: 启动httpd
service: name=httpd state=started
handlers: #动作
- name: restart httpd #这个名称就是上面的名称,也就是指定restart httpd执行什么命令
service: name=httpd state=restarted #添加执行的命令
#保存退出
[root@ansible ~]# sed -i "s/80/8080/g" httpd.conf #把主配置文件的端口修改为8080,这个配置文件可以先在远程主机上安装复制过来后在使用yum -y remove 删除httpd
[root@ansible ~]# ansible-playbook -C playnook01.yaml #监测一下写好的剧本有没有问题
PLAY [web] ******************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [安装httpd] **************************************************************************************************************************
changed: [192.168.100.203]
TASK [修改配置文件] ***************************************************************************************************************************
changed: [192.168.100.203]
TASK [启动httpd] **************************************************************************************************************************
changed: [192.168.100.203]
RUNNING HANDLER [restart httpd] *********************************************************************************************************
changed: [192.168.100.203]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=5 changed=4 unreachable=0 failed=0
[root@ansible ~]# ansible-playbook playnook01.yaml #执行剧本
PLAY [web] ******************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [安装httpd] **************************************************************************************************************************
ok: [192.168.100.203]
TASK [修改配置文件] ***************************************************************************************************************************
changed: [192.168.100.203]
TASK [启动httpd] **************************************************************************************************************************
changed: [192.168.100.203]
RUNNING HANDLER [restart httpd] *********************************************************************************************************
changed: [192.168.100.203]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=5 changed=3 unreachable=0 failed=0 #成功执行3条
[root@ansible ~]# ansible web -m shell -a 'echo "aaaaa" > /var/www/html/index.html' #编写网页
192.168.100.203 | SUCCESS | rc=0 >>
[root@ansible ~]# curl 192.168.100.203:8080 #测试访问
aaaaa
正常安装httpd也会执行,这是因为我的目标主机已经安装了httpd,所以没有执行
[root@ansible ~]# sed -i "s/8080/80/g" httpd.conf #修改配置文件再次执行剧本
[root@ansible ~]# ansible-playbook playnook01.yaml #再次执行剧本
PLAY [web] ******************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [安装httpd] **************************************************************************************************************************
ok: [192.168.100.203]
TASK [修改配置文件] ***************************************************************************************************************************
changed: [192.168.100.203]
TASK [启动httpd] **************************************************************************************************************************
ok: [192.168.100.203]
RUNNING HANDLER [restart httpd] *********************************************************************************************************
changed: [192.168.100.203]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=5 changed=2 unreachable=0 failed=0 #发现这一次只执行成功两条命令
在执行剧本时,只有一些操作发生改变,剧本中的命令才会执行,例如第一次执行成功三条命令,其中一条是启动httpd,但是在第二次和第三次执行剧本时,启动httpd的命令是没有执行的,这是因为第一次已经执行成功,而第二、三次在目标主机上执行是没有变化的所以不会执行,故第一次和第二次都修改了配置文件,所以触发了restart httpd的动作,所以执行成功,而第三次什么修改都不做,那么目标主机也不会有任何变化,所以没有一条命令执行成功
-Playbook中变量的使用
-首先先定义主机组
[root@ansible ~]# tail -7 /etc/ansible/hosts
[web01]
192.168.100.203
[web02]
192.168.100.204
[web:children]
web01
web02
-命令行执行变量
#执行剧本时可以通过-e参数传入变量,这样传入的变量在目标剧本中都可以被调用,属于全局变量,并且这样定义的变量优先级是最高的
[root@ansible ~]# vim playbook02.yaml
---
- hosts: web01
remote_user: root
tasks:
- name: 创建新文件
file: name= hehe state=touch #这里定义变量hehe
#保存退出
[root@ansible ~]# ansible-playbook -e "hehe=aaaaaa" playbook02.yaml #使用-e导入变量hehe,并且执行剧本,要注意这样导入变量的剧本,在使用-C监测是会报错的
PLAY [web01] ****************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [创建新文件] ****************************************************************************************************************************
changed: [192.168.100.203]
TASK [写入数据] *****************************************************************************************************************************
changed: [192.168.100.203]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=3 changed=2 unreachable=0 failed=0
[root@ansible ~]# ansible web01 -m shell -a 'ls' #验证效果
192.168.100.203 | SUCCESS | rc=0 >>
aaaaaa
anaconda-ks.cfg
-hosts文件中自定义变量
#在ansible的hosts文件中可以自定义变量,定义的是主机或者一个组的变量,要注意的是,一个组定义的变量的优先级没有单个主机定义变量的优先级高
[root@ansible ~]# vim /etc/ansible/hosts #分别给主机和组定义变量测测试效果
[web01]
192.168.100.203 hehe=bbbbbb
[web02]
192.168.100.204
[web01:vars]
hehe=aaaaaa
[root@ansible ~]# ansible web01 -m shell -a 'rm -rf aaaaaa' #删除aaaaaa
[WARNING]: Consider using the file module with state=absent rather than running rm. If you need to use command because file is
insufficient you can add warn=False to this command task or set command_warnings=False in ansible.cfg to get rid of this message.
192.168.100.203 | SUCCESS | rc=0 >>
[root@ansible ~]# ansible-playbook -C playbook02.yaml #监测剧本
PLAY [web01] ****************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [创建新文件] ****************************************************************************************************************************
changed: [192.168.100.203]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=2 changed=1 unreachable=0 failed=0
[root@ansible ~]# ansible-playbook playbook02.yaml #执行剧本
PLAY [web01] ****************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [创建新文件] ****************************************************************************************************************************
changed: [192.168.100.203]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=2 changed=1 unreachable=0 failed=0
[root@ansible ~]# ansible web01 -m shell -a 'ls' #验证效果,发现是主机定义的变量生效了
192.168.100.203 | SUCCESS | rc=0 >>
anaconda-ks.cfg
bbbbbb
-剧本文件中定义变量
#在编写剧本时,可以直接在剧本中定义变量,然后直接引用,可以一次性定义多个变量,注意剧本里定义的变量的优先级是没有通过-e参数定义变量的优先级高的
[root@ansible ~]# vim playbook02.yaml #修改剧本文件
---
- hosts: web01
remote _user: root
vars: #定义变量
hehe: abcde
tasks:
- name: 创建新文件
file: name= hehe state=touch
[root@ansible ~]# ansible web01 -m shell -a 'rm -rf bbbbbb' #删除之前创建的文件
[WARNING]: Consider using the file module with state=absent rather than running rm. If you need to use command because file is
insufficient you can add warn=False to this command task or set command_warnings=False in ansible.cfg to get rid of this message.
192.168.100.203 | SUCCESS | rc=0 >>
[root@ansible ~]# ansible-playbook -C playbook02.yaml #监测剧本是否有问题
PLAY [web01] ****************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [创建新文件] ****************************************************************************************************************************
changed: [192.168.100.203]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=2 changed=1 unreachable=0 failed=0
[root@ansible ~]# ansible-playbook playbook02.yaml #执行剧本
PLAY [web01] ****************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [创建新文件] ****************************************************************************************************************************
changed: [192.168.100.203]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=2 changed=1 unreachable=0 failed=0
[root@ansible ~]# ansible web01 -m shell -a 'ls' #验证效果
192.168.100.203 | SUCCESS | rc=0 >>
abcde
anaconda-ks.cfg
[root@ansible ~]# ansible web01 -m shell -a 'rm -rf abcde' #删除abcde
[WARNING]: Consider using the file module with state=absent rather than running rm. If you need to use command because file is
insufficient you can add warn=False to this command task or set command_warnings=False in ansible.cfg to get rid of this message.
192.168.100.203 | SUCCESS | rc=0 >>
[root@ansible ~]# ansible-playbook -e "hehe=aaaaaa" playbook02.yaml #使用-e参数执行剧本
PLAY [web01] ****************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************
ok: [192.168.100.203]
TASK [创建新文件] ****************************************************************************************************************************
changed: [192.168.100.203]
PLAY RECAP ******************************************************************************************************************************
192.168.100.203 : ok=2 changed=1 unreachable=0 failed=0
[root@ansible ~]# ansible web01 -m shell -a 'ls' #验证效果,发现是-e参数定义的变量生效
192.168.100.203 | SUCCESS | rc=0 >>
aaaaaa
anaconda-ks.cfg
-调用setup模块获取变量
#setup模块默认是获取主机信息的,有时候在剧本中需要使用,所以可以直接调用,其实就是内置变量
[root@ansible ~]# vim playbook03.yaml
---
- hosts: web01
以上是关于Ansible之Playbook的主要内容,如果未能解决你的问题,请参考以下文章
ansible学习笔记7-playbooks之执行一个playbook