TT Lab
开始
学习 学习路径 课程

Ansible 实战

做出可复用的 role

在 TT Lab 中继续学习

目标

把 playbook 片段整理为 role,形成可复用的单元,并用不同参数多次调用同一个 role。

为什么重要

role 的本质不是“拆分代码”,而是“预先约定规范,使其无需额外配置即可复用”。放在 templates/ 中的文件无需写完整路径即可找到,handlers/main.yml 中的 handler 也无需注册便可使用。借助这些约定,即使是别人编写的 role,也能推断其结构。真正决定可复用性的,是对 defaults 与 vars 的选择——如果把用户需要修改的值放入 vars,它会因优先级过高而无法从外部覆盖,最终这个 role 只能被复制、修改并再次分叉。当 role 超过两个时,为变量名加上 role 名称前缀的习惯也会开始体现价值。

步骤

  1. 在 /root/ans/roles/roles/webapp 下创建 tasks、defaults、handlers、templates、meta 目录以及 tasks/main.yml。
  2. 在 /root/ans/roles/roles/webapp/defaults/main.yml 中定义 webapp_port: 8080 和 webapp_root: /root/ans/roles/artifacts。
  3. 在 /root/ans/roles/roles/webapp/tasks/main.yml 中加入至少两个有名称的 task,执行后应创建 /root/ans/roles/artifacts 目录。
  4. 创建 /root/ans/roles/roles/webapp/templates/webapp.conf.j2,并将其渲染到 /root/ans/roles/artifacts/webapp.conf。结果中必须有 port = 8080 行,且模板必须引用 webapp_port 变量。
  5. 在 /root/ans/roles/roles/webapp/handlers/main.yml 中定义 restart webapp handler,并从 /root/ans/roles/roles/webapp/tasks/main.yml 的 task 中通过 notify 调用它。handler 要创建 /root/ans/roles/artifacts/restart.marker。
  6. 创建 /root/ans/roles/roles/baseline role(入口为 /root/ans/roles/roles/baseline/tasks/main.yml),让它留下 /root/ans/roles/artifacts/baseline.stamp,并在 /root/ans/roles/roles/webapp/meta/main.yml 的 dependencies 中声明该依赖。
  7. 在 /root/ans/roles/site.yml 中调用 webapp role 两次:一次使用默认值(webapp.conf,port 8080),另一次使用 webapp_port: 9443 创建 /root/ans/roles/artifacts/staging.conf。不得复制 role 目录。
  8. 将第二次运行 playbook 的输出保存到 /root/ans/roles/out/run2.txt,将 ansible-lint 结果保存到 /root/ans/roles/out/lint.txt。第二次运行必须为 changed=0,且不得触发 handler。

参考

创建 role 骨架目录

在 /root/ans/roles/roles/webapp 下创建 tasks、defaults、handlers、templates、meta 目录以及 tasks/main.yml。

ansible-galaxy role init 会生成标准结构。所需目录为 tasks/defaults/handlers/templates/meta。

定义两个默认值

在 /root/ans/roles/roles/webapp/defaults/main.yml 中定义 webapp_port: 8080 和 webapp_root: /root/ans/roles/artifacts。

预期可被覆盖的值应放在 defaults 中,并为名称加上 role 名称前缀。

编写并运行 role task

在 /root/ans/roles/roles/webapp/tasks/main.yml 中加入至少两个有名称的 task,执行后应创建 /root/ans/roles/artifacts 目录。

tasks/main.yml 是入口。至少要有两个 task,并且每个都必须有名称。

用 role 模板生成配置文件

创建 /root/ans/roles/roles/webapp/templates/webapp.conf.j2,并将其渲染到 /root/ans/roles/artifacts/webapp.conf。结果中必须有 port = 8080 行,且模板必须引用 webapp_port 变量。

templates/ 中的文件只写文件名即可找到。不要硬编码端口值,应使用变量。

定义并触发 role handler

在 /root/ans/roles/roles/webapp/handlers/main.yml 中定义 restart webapp handler,并从 /root/ans/roles/roles/webapp/tasks/main.yml 的 task 中通过 notify 调用它。handler 要创建 /root/ans/roles/artifacts/restart.marker。

handlers/main.yml 中的 handler 会自动注册。运行后请留下标记文件。

声明依赖 role 并使其先运行

创建 /root/ans/roles/roles/baseline role(入口为 /root/ans/roles/roles/baseline/tasks/main.yml),让它留下 /root/ans/roles/artifacts/baseline.stamp,并在 /root/ans/roles/roles/webapp/meta/main.yml 的 dependencies 中声明该依赖。

单独创建 baseline role,并写入 meta/main.yml 的 dependencies。依赖 role 会先运行。

用不同参数调用同一 role 两次

在 /root/ans/roles/site.yml 中调用 webapp role 两次:一次使用默认值(webapp.conf,port 8080),另一次使用 webapp_port: 9443 创建 /root/ans/roles/artifacts/staging.conf。不得复制 role 目录。

可以在 play 的 roles 段中将变量与 role 名称一起传入。不得复制 role。

验证重跑幂等性并通过 lint

将第二次运行 playbook 的输出保存到 /root/ans/roles/out/run2.txt,将 ansible-lint 结果保存到 /root/ans/roles/out/lint.txt。第二次运行必须为 changed=0,且不得触发 handler。

第二次运行应为 changed=0,handler 也应保持静默。还要保存 ansible-lint 结果。