目录
引言:什么是playbook?
剧本,就像一些综艺节目的剧本一个意思。按照剧本发展故事情节 在ansible中剧本也是类似的作用,第一步干啥,第二部干啥,第三步干啥....
一、Playbook
playbooks是 一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活。简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复杂应用程序的基础。Playbook可以定制配置,可以按照指定的操作步骤有序执行,支持同步和异步方式。
值得注意的是playbook是通过YAML格式来进行描述定义的。可以类比linux中执行shell脚本一样,批量执行命令。 ansible中的剧本也是一样,批量处理任务,而 playbook用的是yaml格式!
1.1、playbook中的核心元素
- hosts:执行的远程主机列表
- tasks:任务,由模板定义的操作列表
- vars:变量,内置变量或者自定义变量在playboook中调用
- templates:模板,即 使用模板语法的文件;可替换模板中的变量并实现一些简单逻辑的而文件
- handlers:和notify结合使用 ;当某条件满足时,触发执行的操作
- tags:标签,指定某条件下,用于选择运行playbook中的部分代码。Ansible具有幂等性,因此会自动跳过没有变化的部分,有些业务执行比较长,如果确认没有问题就可以通过tags跳过这些片段
- roles:角色
1.2、playbook中的基础组件
hosts:playbook中的每个play的目的都是为了让某个或者某些主机在某个指定的用户身份执行任务。hosts用于指定任务的主机,须事先定义在主机清单中
形式如下:
- hosts: websrvs
remote_user:可用于hosts和tasks中,也可以通过指定sudo的方式在远程主机上执行,其可用于paly全局或某任务;此外甚至可以在sudo时使用sudo_user指定sudo时切换的用户
- hosts: 192.168.176.128
remote_user: root
tasks:任务列表;格式有两种:
action: module argument
module: argument
建议使用第二种
特别注意:shell和command模块后面跟命令,而非key=value 某任务的状态在运行后changed时,可通过‘notify’通知给相应的handlers 任务可以通过‘tags’打标签,而后可在absible-playbook命令上使用-t指定进行调用
---
tasks:
- name: disable selinux
command: /sbin/setenforce 0
---
# 如果命令或者脚本的退出码不为零,可以使用以下方式替代
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand || /bin/true
---
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand
ignore_errors: True
1.3、playbook格式说明
Hosts: 主机,部署目标
Tasks: 任务,ansible,执行目的
Varlables: 变量
Templates: 包含了模板语法的文本文件;
Handlers: 有特定条件触发的任务
Roles : 角色 (特别介绍)
以下为playbook常用到的YMAL格式:
1、文件的第一行应该以 "---" (三个连字符)开始,表明YMAL文件的开始。
2、在同一行中,#之后的内容表示注释,类似于shell,python和ruby。
3、YMAL中的列表元素以”-”开头然后紧跟着一个空格,后面为元素内容。
4、同一个列表中的元素应该保持相同的缩进。否则会被当做错误处理。
5、play中hosts,variables,roles,tasks等对象的表示方法都是键值中间以":"分隔表示,":"后面还要增加一个空格
6、yml文件名以yml结尾或者yaml结尾
示例1:**
---
- hosts: all
remote_user: root
tasks:
- name: install a group
group: name=mygrp system=true
- name: install a user
user: name=user1 group=mygrp system=true
示例2
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd
- name: start httpd service
service: name=httpd state=started
主要由三个部分组成。
hosts部分:使用hosts指示使用哪个主机或主机组来运行下面的tasks,每个playbook都必须指定hosts,hosts也可以使用通配符格式。主机或主机组在inventory清单中指定,可以使用系统默认的/etc/ansible/hosts,也可以自己编辑,在运行的时候加上-i选项,指定清单的位置即可。在运行清单文件的时候,--list-hosts选项会显示那些主机将会参与执行task的过程中。 remote_user:指定远端主机中的哪个用户来登录远端系统,在远端系统执行task的用户,可以任意指定,也可以使用sudo,但是用户必须要有执行相应task的权限。 tasks:指定远端主机将要执行的一系列动作。tasks的核心为ansible的模块,前面已经提到模块的用法。tasks包含name和要执行的模块,name是可选的,只是为了便于用户阅读,不过还是建议加上去,模块是必须的,同时也要给予模块相应的参数。
1.4、实例:httpd服务剧本
1 vim test1.yaml --- #yaml文件以---开头,以表明这一个yaml文件,可省略
2
3 - name: first play #定义一个play的名称,可省略 gather_facts: false #设置不进行facts信息收集,这可以加快执行速度,可省略 hosts: webservers #指定要执行任务的被管理主机组,如多个主机组用冒号分隔 remote_user: root #指定被管理主机上执行任务的用户 tasks: #定义任务列表,任务列表中的各任务按次序逐个在hosts中指定的主机上执行
4
5 - name: test connection #自定义任务名称 ping: #使用 module: [options] 格式来定义一个任务
6 - name: disable selinux command: '/sbin/setenforce 0' #command模块和shell模块无需使用key=value格式 ignore_errors: True #如执行命令的返回值不为0,就会报错,tasks停止,可使用ignore_errors忽略失败的任务
7 - name: disable firewalld service: name=firewalld state=stopped #使用 module: options 格式来定义任务,option使用key=value格式
8 - name: install httpd yum: name=httpd state=latest
9 - name: install configuration file for httpd copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf #这里需要一个事先准备好的/opt/httpd.conf文件 notify: "restart httpd" #如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作
10 - name: start httpd service service: enabled=true name=httpd state=started handlers: #handlers中定义的就是任务,此处handlers中的任务使用的是service模块
11 - name: restart httpd #notify和handlers中任务的名称必须一致 service: name=httpd state=restarted ##Ansible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler,这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启。
运行playbook
1 ansible-playbook test1.yaml
2 //补充参数:
3 -k(–ask-pass):用来交互输入ssh密码
4 -K(-ask-become-pass):用来交互输入sudo密码
5 -u:指定用户
6 ansible-playbook test1.yaml --syntax-check #检查yaml文件的语法是否正确
7 ansible-playbook test1.yaml --list-task #检查tasks任务
8 ansible-playbook test1.yaml --list-hosts #检查生效的主机
9 ansible-playbook test1.yaml --start-at-task='install httpd' #指定从某个task开始运行
二、playbook中的模块
2.1、Templates 模块
1、先准备一个以 .j2 为后缀的 template 模板文件,设置引用的变量
1 cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2
2
3 vim /opt/httpd.conf.j2
4 Listen {{http_port}} #42行,修改
5 ServerName {{server_name}} #95行,修改
6 DocumentRoot "{{root_dir}}" #119行,修改
2、修改主机清单文件,使用主机变量定义一个变量名相同,而值不同的变量
1 vim /etc/ansible/hosts
2 [webservers]
3 192.168.118.104 http_port=192.168.118.104:80 server_name=www.accp.com:80 root_dir=/etc/httpd/htdocs
4
5 [dbservers]
6 192.168.118.102 http_port=192.168.118.102:80 server_name=www.benet.com:80 root_dir=/etc/httpd/htdocs
3、编写 playbook
vim apache.yaml
---
- hosts: all
remote_user: root
vars:
- package: httpd
- service: httpd
tasks:
- name: install httpd package
yum: name={{package}} state=latest
- name: install configure file
template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf #使用template模板
notify:
- restart httpd
- name: create root dir
file: path=/etc/httpd/htdocs state=directory
- name: start httpd server
service: name={{service}} enabled=true state=started
handlers:
- name: restart httpd
service: name={{service}} state=restarted
ansible-playbook apache.yaml
2.2、tags 模块
- 可以在一个playbook中为某个或某些任务定义“标签”,在执行此playbook时通过ansible-playbook命令使用--tags选项能实现仅运行指定的tasks。
- playbook还提供了一个特殊的tags为always。作用就是当使用always当tags的task时,无论执行哪一个tags时,定义有always的tags都会执行。
vim webhosts.yaml
---
- hosts: webservers
remote_user: root
tasks:
- name: Copy hosts file
copy: src=/etc/hosts dest=/opt/hosts
tags:
- only #可自定义
- name: touch file
file: path=/opt/testhost state=touch
tags:
- always #表示始终要运行的代码
ansible-playbook webhosts.yaml --tags="only"
vim dbhosts.yaml
---
- hosts: dbservers
remote_user: root
tasks:
- name: Copy hosts file
copy: src=/etc/hosts dest=/opt/hosts
tags:
- only
- name: touch file
file: path=/opt/testhost state=touch
ansible-playbook dbhosts.yaml --tags="only"
//分别去两台被管理主机上去查看文件创建情况
2.3、Roles 模块
- Ansible为了层次化、结构化地组织Playbook,使用了角色(roles),roles可以根据层次型结构自动装载变量文件、task以及handlers等。简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include它们。roles一般用于基于主机构建服务的场景中,但也可以用于构建守护进程等场景中。
1、roles 的目录结构
cd /etc/ansible/ tree roles/ roles/ ├── web/ │ ├── files/ │ ├── templates/ │ ├── tasks/ │ ├── handlers/ │ ├── vars/ │ ├── defaults/ │ └── meta/ └── db/ ├── files/ ├── templates/ ├── tasks/ ├── handlers/ ├── vars/ ├── defaults/ └── meta/
2、roles 内各目录含义解释
(1)files
- 用来存放由 copy 模块或 script 模块调用的文件。
(2)templates
- 用来存放 jinjia2 模板,template 模块会自动在此目录中寻找 jinjia2 模板文件。
(3)tasks
- 此目录应当包含一个 main.yml 文件,用于定义此角色的任务列表,此文件可以使用 include 包含其它的位于此目录的 task 文件。
(4)handlers
- 此目录应当包含一个 main.yml 文件,用于定义此角色中触发条件时执行的动作。
(5)vars
- 此目录应当包含一个 main.yml 文件,用于定义此角色用到的变量。
(6)defaults
- 此目录应当包含一个 main.yml 文件,用于为当前角色设定默认变量。
(7)meta
- 此目录应当包含一个 main.yml 文件,用于定义此角色的特殊设定及其依赖关系。
3、在一个 playbook 中使用 roles 的步骤
(1)创建以 roles 命名的目录
1 mkdir /etc/ansible/roles/ -p #yum装完默认就有
(2)创建全局变量目录(可选)
mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all #文件名自己定义,引用的时候注意
(3)在 roles 目录中分别创建以各角色名称命令的目录,如 httpd、mysql
mkdir /etc/ansible/roles/httpd
mkdir /etc/ansible/roles/mysql
(4)在每个角色命令的目录中分别创建files、handlers、tasks、templates、meta、defaults和vars目录,用不到的目录可以创建为空目录,也可以不创建
mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta}
(5)在每个角色的 handlers、tasks、meta、defaults、vars 目录下创建 main.yml 文件,千万不能自定义文件名
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
(6)修改 site.yml 文件,针对不同主机去调用不同的角色
vim /etc/ansible/site.yml
---
- hosts: webservers
remote_user: root
roles:
- httpd
- hosts: dbservers
remote_user: root
roles:
- mysql
(7)运行 ansible-playbook
cd /etc/ansible
ansible-playbook site.yml