Playbool 是由一个或多个 play 组成的列表,主要功能是将 task 定义好的角色归并为一组进行统一管理,也就是通过 task 调用 Ansible 的模板将多个 play 组织在一个 Playbook 中运行。
playbooks本身由以下各部分组成
(1)Tasks:任务,即调用模块完成的某操作;
(2)Variables:变量
(3)Templates:模板
(4)Handlers:处理器,当某条件满足时,触发执行的操作;
(5)Roles:角色。
下面是一个 playbook 的示例
在编辑剧本时,对格式要求较为严格,需要注意一下几点,不然会出现语法上的错误。
1.第一行 “-“ 与 “hosts” 之间有空格,冒号后也要空格。
2.各层级之间要首行对其,如 hosts 、user、tasks、handlers.
3.tasks 中执行的任务是 tasks 的子项,需要首行缩进,并保持对齐。
执行一个 playbook 格式如下:
ansible-playbook [yaml 文件名]
例如:ansible-playbook test.yml
参数:-k(–ask-pass) 用来交互输入ssh密码
-K(-ask-become-pass) 用来交互输入sudo密码
-u 指定用户
补充命令:
ansible-playbook nginx.yaml --syntax-check #检查yaml文件的语法是否正确
ansible-playbook nginx.yaml --list-task #检查tasks任务
ansible-playbook nginx.yaml --list-hosts #检查生效的主机
ansible-playbook nginx.yaml --start-at-task='Copy Nginx.conf' #指定从某个task开始运行
接下来介绍 Playbook 的基本组件。
一.Hosts 和 Users 介绍
Playbook 的设计目的是为了让某个或某些主机以某个或者用户的身份去执行相应的任务。其中用于指定要指定任务的主机用 hosts 定义,可以是一个主机名也可是由冒号分割的多个主机组;用于指定被管理主机上执行任务的用户 remote_user 来定义。
- hosts: webserver #指定主机组,可以是一个或多个组。
remote_user: root #指定远程主机执行的用户
remote_user 也可以定义指定用户通过 sudo 的方法在被管理主机上运行指令,还可指定远程主机sudo 切换用户:
- hosts: mysql
remote_user: root
become: yes #2.6版本以后的参数,之前是sudo,意思为切换用户运行
become_user: mysql #指定sudo用户为mysql
二.tasks列表和action
Play的主体部分是task列表,task列表中的各任务按次序逐个在hosts中指定的主机上执行,即在所有主机上完成第一个任务后再开始第二个任务。在运行playbook时(从上到下执行),如果一个host执行task失败,整个tasks都会回滚,请修正playbook 中的错误,然后重新执行即可。
task 的任务是按照指定的参数去执行模块。每个 task 都使用 name 输出 Playbook 的运行结果。
简单示例如下:
[root@bogon .ssh]# vim a.yml
执行 Playbook
在被管理主机 webserver 上查看安装情况
三.Handlers 介绍
Handlers 用于当关注的资源发生变化是所采取的操作,在 notify 中列出的操作便称为 handler ,也就是在 notify 中需要调用 handler 中定义的操作。而 notify 这个动作在每个 play 的最后被触发,仅在所有的变化发生完成后一次性地执行指定操作。
事例:
- hosts: webserver
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd state=latest
- name: install configuration file for httpd
copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf //复制配置文件
notify: //调用 handler 中定义的操作
-restart httpd
- name: start httpd service
service: enabled=true name=httpd state=started
handlers: 如果没有被notify,则Handlers不会执行,假如被notify了,则Handlers被执行
- name: restart httpd
service: name=httpd state=restarted
也可以引入变量
在 Ansible 中变量名仅能有字母、数字、下划线组成,并且只能以字母开头。
- hosts: webserver
remote_user: root
vars: //定义变量
- package: httpd //变量名:变量值
- service: httpd
tasks:
- name: install httpd package
yum: name={{package}} state=latest //引用第一个变量值,使用两个{}
- name: install configuration file for httpd
copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
-restart httpd
- name: start httpd service
service: enabled=true name={{service}} state=started //引用第二个变量值
handlers:
- name: restart httpd
service: name={{service}} state=restarted
在 playbook 中使用变量的方法有以下几种:
(1)通过 ansible 命令传递
例如:编辑如下 yaml
vi a.yml
---
- hosts: mysql
remote_user: root
vars: //定义变量
- user:
tasks:
- name: add new user
user: name={{user}} //使用 user 模块调用
然后执行命令: ansible-playbook a.yml -e "user=testvar"
可以执行命令查看:ansible mysql -m command -a 'tail /etc/passwd'
(2)直接在 yaml 中定义变量。(如 hanndlers 事例)
(3)直接引用一些变量
如:引用ansible的固定变量
vi test.yml
---
- hosts: mysql
remote_user: root
tasks:
- name: copy file
copy: content="{{ansible_all_ipv4_addresses}}," dest=/opt/vars.txt//此变量是查看主机网卡 ipv4 地址的固定变量
执行命令:ansible-playbook test.yml
再如:引用主机变量
vi /etc/ansible/hosts
在mysql组的主机后面添加如下
[mysql]
192.168.66.148 testvar="66.148" #定义testvar变量的值为66.148
vi test.yml #添加{{testvar}}主机变量
---
- hosts: mysql
remote_user: root
tasks:
- name: copy file
copy: content="{{ansible_all_ipv4_addresses}},{{testvar}}" dest=/opt/vars.txt
执行命令:ansible-playbook test.yml
四. 条件测试
如果需要根据变量、facts(setup)或此前任务的执行结果来作为某task执行与否的前提时要用到条件测试,在Playbook中条件测试使用when子句。
(1)在task后添加when子句即可使用条件测试:when子句支持jinjia2表达式或语法,例如:
vi when.yml
---
- hosts: mysql
remote_user: root
tasks:
- name: "shutdown CentOS"
command: /sbin/shutdown -h now //调用 command 模块关闭主机
when: ansible_distribution == "CentOS" //条件判断当被管理主机版本为 Centos 时,关机。其它版本不关机
(2)多条件判断 (判断语句为且的关系,条件都要满足)
vi when.yml
---
- hosts: mysql
remote_user: root
tasks:
- name: "shut down CentOS 7 systems"
command: /sbin/shutdown -r now
when:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version == "7"//判断条件为版本为 Centos 且版本号为 7
(3)组条件判断
vi when.yml
---
- hosts: mysql
remote_user: root
tasks:
- name: "shut down CentOS 6 and Debian 7 systems"
command: /sbin/shutdown -t now
when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or
(ansible_distribution == "Debian" and ansible_distribution_major_version == "7")//判断条件为:只要是 Centos 6 或者 Debian 7 都关机
(4)自定义变量进行条件测试
vim when.yml
---
- hosts: all
vars: //定义变量
exist: "True" //存在值为 True
tasks:
- name: creaet file
command: touch /tmp/test.txt
when: exist | match("True") //判断条件当存在值匹配为 True ,创建 /tmp/test.txt 文件
- name: delete file
command: rm -rf /tmp/test.txt
when: exist | match("False") //判断条件当存在值匹配为 Fales , 删除 /tmp/test.txt 文件
五. 迭代
需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句指明迭代的元素列表即可。例如:
- hosts: webserver
remote_user: root
tasks:
- name: "Install Packages"
yum: name={{ item }} state=latest //其使用格式为将需要迭代的内容定义为item变量引用
with_items: //通过with_items语句指明迭代的元素列表
- httpd
- mysql-server
- php