LabHub
学习 学习路径 课程

Ansible 基础

写第一个 playbook,并用检查模式跑一遍

在 LabHub 中继续学习

目标

使用 playbook 声明服务器的期望状态,并在执行前通过检查模式确认影响范围。

为什么重要

shell 脚本描述“要做什么”,而 playbook 描述“结束时应处于什么状态”。正因如此,同一个 playbook 无论运行多少次,结果都应一致。实现这一特性的不是语法,而是模块——file 模块发现目录已经存在时不会做任何事,如果只有权限不同,也只会修正权限。相反,command/shell 不知道当前状态,因此总会报告发生了变更。所以,“有专用模块就不用 shell”并非风格偏好,而是正确性问题。最后,--check --diff 是首次接触生产服务器前的最后一道安全措施。

步骤

  1. 创建 /root/ans/play/site.yml。其中只有一个 play,必须有 namehostsweb,并且要通过 ansible-playbook -i /root/ans/inventory/hosts.ini --syntax-check
  2. 添加并执行一个 file 模块 task,用于创建 /root/ans/artifacts/app 目录,并将权限设为 0755
  3. 使用 copy 模块创建 /root/ans/artifacts/app/app.conf。文件中必须分别有一行 listen_port=8080env=lab。其中不要把 env 的值硬编码,而应提取为 app_env 变量并将默认值设为 lab(第 6 步会修改该值)。
  4. 至少创建 3 个 task,并为每个 task 添加 name
  5. 给处理配置的 task 添加 config 标签,使用 --tags config 执行,并将输出保存到 /root/ans/out/tags.txt
  6. 使用 --check --diff -e app_env=stage 运行 playbook,并将输出保存到 /root/ans/out/check.txt。输出的 diff 中应显示 env=stage,但实际的 /root/ans/artifacts/app/app.conf 仍必须保持 env=lab此步骤绝对不要真正应用变更。
  7. /opt/lab/fixtures/ansible/motd.seed 复制到 /root/ans/artifacts/motd,再用 lineinfile 修改为 Welcome=labhubOwner=platform-team。必须保留 Banner=unset 行,并且以 Welcome= 开头的行只能有一行。
  8. /opt/lab/fixtures/ansible/broken-play.yml 复制到 /root/ans/play/fixed.yml,修复其中四处错误并运行。最终 /root/ans/artifacts/fixed/report.txt 中要包含 fixed by student,同时保留 handler 定义和 notify。

参考

创建 playbook 骨架并通过语法检查

创建 /root/ans/play/site.yml。其中只有一个 play,必须有 namehostsweb,并且要通过 ansible-playbook -i /root/ans/inventory/hosts.ini --syntax-check

playbook 顶层是列表。每个 play 都要包含 namehoststasks,然后用 --syntax-check 验证。

用 file 模块创建目录

添加并执行一个 file 模块 task,用于创建 /root/ans/artifacts/app 目录,并将权限设为 0755

不要使用 shell 命令,请使用 file 模块。检查 state 的值和 mode 的写法(引号)。

用 copy 模块部署配置文件

使用 copy 模块创建 /root/ans/artifacts/app/app.conf。文件中必须分别有一行 listen_port=8080env=lab。其中不要把 env 的值硬编码,而应提取为 app_env 变量并将默认值设为 lab(第 6 步会修改该值)。

copy 模块也可以不使用 src,而通过 content 直接提供内容。多行内容使用 YAML 块标量。把环境值提取为变量,以便稍后修改。

为所有 task 添加名称

至少创建 3 个 task,并为每个 task 添加 name

至少要有 3 个 task,不能有任何一个 task 缺少 name。

添加标签并只运行部分 task

给处理配置的 task 添加 config 标签,使用 --tags config 执行,并将输出保存到 /root/ans/out/tags.txt

给配置相关 task 添加 tags: [config],并使用 --tags config 运行。务必至少保留一个没有标签的 task,这样才能看出执行范围确实被缩小。

一个容易误解的点:被 --tags 过滤掉的 task 不会显示为 skipping,而是完全不出现在输出中,skipped= 也仍为 0。这与被 when: 过滤的情况不同——后者已进入执行范围,只是在条件判断时被跳过,因此会留下记录。

使用检查模式预览变更

使用 --check --diff -e app_env=stage 运行 playbook,并将输出保存到 /root/ans/out/check.txt。输出的 diff 中应显示 env=stage,但实际的 /root/ans/artifacts/app/app.conf 仍必须保持 env=lab此步骤绝对不要真正应用变更。

--check --diff 后通过 -e 传入不同的值。输出中应显示将要发生的变化,但实际文件必须保持不变。

只修改现有文件中的指定行

/opt/lab/fixtures/ansible/motd.seed 复制到 /root/ans/artifacts/motd,再用 lineinfile 修改为 Welcome=labhubOwner=platform-team。必须保留 Banner=unset 行,并且以 Welcome= 开头的行只能有一行。

先把 fixture 复制到 /root/ans/artifacts/motd,再用 lineinfile 修改。必须通过 regexp 找到已有行,避免重复增加。

修复损坏的 playbook

/opt/lab/fixtures/ansible/broken-play.yml 复制到 /root/ans/play/fixed.yml,修复其中四处错误并运行。最终 /root/ans/artifacts/fixed/report.txt 中要包含 fixed by student,同时保留 handler 定义和 notify。

其中有两个模块参数名、一个 state 值和一个顶层键名是错误的。请查看错误信息指向哪一行。