依赖是角色自带的顺序声明
一个角色往往需要前提:装好基础包、配好仓库、创建账号。把这些前提写进角色的元数据,调用方就只用一个角色名,内部顺序由角色自己保证。依赖的执行时机在角色自身任务之前,并且同一次执行中重复出现的依赖通常只执行一次,这既避免重复劳动,也带来“某角色没按预期跑第二遍”的困惑。
基本信息
| 声明位置 | 角色的元数据文件,列出依赖角色并可附带参数 |
|---|---|
| 执行时机 | 依赖先于角色自身任务执行 |
| 去重行为 | 同一依赖在一次执行中通常只执行一次,是否允许重复由参数控制 |
| 传参方式 | 可在依赖声明中传入变量,覆盖依赖角色自身的默认值 |
| 顺序控制 | 依赖之间按声明顺序执行;跨角色的先后也可用前置与后置任务段实现 |
| 风险点 | 依赖成环与依赖过多都会让执行顺序难以预测 |
典型使用场景
- 基础前提:所有应用角色依赖统一的基线角色(账号、时区、日志)
- 中间件前置:应用角色依赖它所需的运行时或数据库客户端
- 配置仓库:装包前必须先配好软件源角色
- 顺序固化:把“先建用户再装服务”的顺序写进角色,调用方不必记住
- 参数下发:依赖角色按调用场景接收不同参数,避免复制角色
- 分层交付:平台角色作为依赖被业务角色引用,形成清晰的责任链
依赖声明与顺序
依赖声明与顺序
# roles/app/meta/main.yml
# dependencies:
# - role: baseline # 先跑基线
# vars:
# baseline_ntp_server: ntp.internal
# - role: repo_setup # 再配软件源
# - role: runtime # 再装运行时
# vars:
# runtime_version: "3.11"
- hosts: web
roles:
- role: baseline # 显式列出时按列出顺序执行
tags: [baseline]
- role: app # app 的依赖若已执行过,通常不会重复执行
tags: [app]
- hosts: web
pre_tasks: # 需要在所有角色之前完成的动作
- name: 打开防火墙端口
ansible.builtin.command: /usr/local/bin/open-port.sh
tasks:
- name: 角色之后的收尾动作
ansible.builtin.debug:
msg: 角色已执行完毕顺序控制手段
| 手段 | 时机 | 适用与注意 |
|---|---|---|
| 角色依赖声明 | 角色自身任务之前 | 表达“角色自带的前提”,去重行为需注意 |
| 前置任务段 | 所有角色之前 | 全局准备动作,例如开端口、装基础包 |
| 后置任务段 | 所有角色之后 | 全局收尾动作,例如注册监控、跑验收 |
| 任务文件引入 | 角色内部按需 | 角色内部的步骤拆分与条件引入 |
| 显式角色列表 | 按列表顺序 | 调用方希望明确控制顺序时使用 |
“依赖只执行一次”是常见困惑来源:多个角色都依赖同一个基线时,基线只在第一次被拉起时执行。若确实需要重复执行某角色,需要在声明处显式允许重复,或改由调用方在角色列表里明确列出。
依赖链过长或成环时,执行顺序难以预测,排障成本会显著上升。经验做法是把依赖控制在两层以内,跨层的通用能力通过前置任务段显式编排,让顺序在剧本里一眼可见。
依赖还是编排
判断标准是“这个前提是否只对该角色成立”:只对该角色成立(例如运行时版本)写进依赖;对整批主机都成立(例如基础加固、监控注册)应放在剧本层的显式编排里。把这个边界划清,角色之间的耦合会明显下降。