从零开始编写Asible剧本
在日常运维中,我们经常需要在大量服务器上执行重复性任务——比如安装软件、修改配置、重启服务。Ansible 提供了两种执行方式:Ad-Hoc 命令和Playbook(剧本)。Ad-Hoc 适合临时性的快速操作,而 Playbook 则将经常执行的任务写入一个文件,随时按“剧本”执行,适合周期性、复杂的自动化场景。本文将从 Ansible Playbook 的基本概念讲起,深入 YAML 语法、Playbook 结构,并通过实战示例带你快速上手。
一、Playbook 概述
1.1 什么是 Ad-Hoc 命令?
Ad-Hoc 命令是 Ansible 提供的命令行执行方式,用于远程管理其他主机。它的特点是:
- 直接在终端输入,格式为
ansible <主机组> -m <模块> -a "<参数>" - 适合执行临时性、简单的任务,比如测试连通性、批量执行一条 Shell 命令
# 测试所有主机的连通性ansible all-mping# 在所有主机上创建 /tmp/test.txt 文件ansible all-mfile-a"path=/tmp/test.txt state=touch"更多Ad-hoc命令的用法可参考另一篇文章:自动化运维-ansible常用模块详解
1.2 什么是 Playbook?
Playbook 中文译为“剧本”,它把经常需要执行的多个任务按顺序写入一个 YAML 格式的文件中。剧本写好之后,我们随时可以根据剧本执行相关任务,而无需重复手动输入多条命令。
Playbook 与 Ad-Hoc 的核心区别:
| 特性 | Ad-Hoc 命令 | Playbook |
|---|---|---|
| 任务数量 | 只能执行单一任务 | 可包含多个任务,按顺序执行 |
| 持久性 | 无法保存复用 | 可持久保存,版本管理 |
| 条件控制 | 不支持 | 支持条件判断(when)、循环(loop) |
| 触发器 | 不支持 | 支持 handlers(仅在变更时触发) |
| 适用场景 | 临时、一次性操作 | 周期性、复杂的自动化运维 |
总结:Ad-Hoc 是“一次性命令”,Playbook 是“标准化剧本”,适合重复执行的复杂任务。
二、YAML 详解
Playbook 采用YAML格式编写。YAML 是一种可读性极高的数据序列化语言,它以数据为中心,重点描述数据之间的关系,非常适合作为配置文件格式。
2.1 YAML 的基本规则
- 注释:使用
#表示注释,注释内容不会被执行。 - 文档开始:一般建议以
---作为文档的开始标记(非强制,但推荐)。 - 键值对:使用
key: value表示,冒号后面必须有一个空格。 - 数组(列表):使用短横线
-表示列表项,横线后面也要加空格。 - 缩进:使用两个或以上空格表示层级,相同层级的缩进必须对齐,不能使用 Tab 键。
- 大小写敏感:YAML 区分大小写。
- 文件扩展名:通常为
.yaml或.yml。 - 跨行文本:如果需要跨行,可以使用
>(折叠为一行)或|(保留换行符)。
2.2 YAML 数据样例
键值对(字典)
name:张三age:28job:开发工程师数组(列表)
fruits:-Apple-Banana-Orange嵌套结构(层级关系通过缩进表示)
company:name:极客科技departments:-研发部-运维部address:city:北京district:海淀跨行文本
description:>这是一段很长的描述, 会被折叠成一行。preserve:|这是第二段, 换行符会被保留。三、Playbook 语法格式
一个 Playbook 文件中可以包含一个或多个 Play,每个 Play 通常包含以下核心组成部分:
3.1 基本结构
----hosts:<目标主机># 指定要执行的主机或主机组remote_user:<用户名># 远程执行任务的用户(可选)vars:# 变量定义(可选)var_name:valuetasks:# 任务列表(核心)-name:任务描述模块名:参数:值handlers:# 触发器(可选)-name:触发器名称模块名:参数:值roles:# 角色(高级用法,可选)-role_name注意:列表项前需要加短横线-,而列表项的参数前则不需要加短横线。
3.2 各组成部分说明
- hosts:必须字段,指定要操作的主机,可以是 IP、主机名或 Inventory 中定义的主机组(如
webservers、all)。 - remote_user:可选,指定远程执行用户,默认为当前用户。
- vars:定义变量,在 Playbook 中可以使用
{{ var_name }}引用。 - tasks:核心任务列表,每个任务调用一个 Ansible 模块(如
yum、copy、service),任务按从上到下的顺序执行。 - handlers:定义触发器,被
notify调用。仅在任务产生变更时才会执行,通常用于重启服务。 - roles:通过角色方式组织 Playbook,实现代码复用,本文暂不展开。
3.3 如何运行 Playbook
使用ansible-playbook命令执行:
# 正常执行ansible-playbook playbook.yml# 剧本语法检查,没有报错则无语法错误ansible-playbook playbook.yml --syntax-check# 检查语法(模拟执行,不真正变更)ansible-playbook--checkplaybook.yml# 指定额外的变量ansible-playbook playbook.yml-e"version=1.0"四、简单示例:使用ansible playbook部署 Nginx
假设我们要在webserver组的全部主机上安装并启动 Nginx,Playbook 可以这样写:
----name:在 Web 服务器上安装并启动 Nginxhosts:webservertasks:-name:安装 Nginxyum:name:nginxstate:present-name:启动 Nginx 并设置开机自启service:name:nginxstate:startedenabled:yes执行:
ansible-playbook nginx_deploy.yml五、编写高质量 Playbook 的最佳实践
给每个 Play 和 Task 起清晰的名字
执行时会显示名字,方便调试和日志追踪。保持幂等性
好的 Playbook 多次运行结果应一致,不会因为重复执行而意外改变系统状态。善用变量和模板
将可变参数提取为变量,使用 Jinja2 模板生成配置文件,提高复用性。合理使用 handlers
只在必要时(如配置变更)触发重启,避免无效操作。使用
--check模式进行测试
重大变更前先执行ansible-playbook --check预演,确保结果符合预期。缩进统一用空格,不用 Tab
YAML 严格要求,建议编辑器设置“用空格替代 Tab”。将 Playbook 纳入版本控制
使用 Git 管理 Playbook,记录每一次变更,便于团队协作和回溯。
结语
从 Ad-Hoc 命令到 Playbook,是从“随意敲命令”到“标准化自动化”的蜕变。Playbook 把繁琐的运维操作变成可读、可复用、可追溯的代码,极大提升了运维效率和可靠性。
本文从 Ansible Playbook 的基本概念出发,详细介绍了 YAML 格式规范、Playbook 的组成结构,并通过实际例子演示了如何编写和使用。下一节将介绍ansible 常用模块的playbook使用方法;如果你有疑问,欢迎留言交流。