import_playbook 是静态导入,在解析阶段展开并合并所有内容,确保全局变量和严格顺序;include_playbook 是动态包含,支持条件、循环和运行时决策,但变量作用域更局部。

import_playbook 与 include_playbook 的本质区别
两者都用于拆分和复用 playbook,但执行时机和行为完全不同:
import_playbook 是静态导入,在 Ansible 解析阶段就展开整个被导入的 playbook,所有任务、变量、角色、处理器都会被提前合并进主 playbook,最终形成一个逻辑上“扁平”的执行计划。它不支持基于变量或条件动态决定是否导入,也不支持在循环中使用。
include_playbook 是动态包含,在运行时按需加载,支持 when 条件判断、loop 循环触发,还能根据 inventory 或 runtime 变量跳过或选择性执行。但它不能在 play 级别之外(如 vars: 块中)定义变量并被后续 play 直接继承——变量作用域更局部。
超大型部署骨架的分层设计原则
建议按职责和变更频率划分层级,从外到内依次为:
- site.yml:顶层入口,仅做环境识别(prod/staging)、全局变量加载、基础连接校验,然后 import 各核心阶段
- stages/ 目录:存放 provision.yml(基础系统初始化)、configure.yml(中间件与服务配置)、deploy.yml(应用包分发与启停)、validate.yml(健康检查与冒烟测试)——这些统一用 import_playbook,确保阶段顺序严格、变量全局可见、错误可集中捕获
- components/ 目录:存放可插拔模块,如 nginx.yml、redis-cluster.yml、logrotate.yml。它们通过 include_playbook 被 stages 中的 task 动态调用,支持按主机 group、tag 或自定义标记(如 app_type: api)条件包含
关键实践技巧与避坑点
构建稳定骨架需注意以下细节:
- 使用 import_playbook 时,被导入文件中的 vars: 会自动提升为当前 play 的变量,但若多个 import 定义同名变量,后导入者覆盖前者;建议只在 stage 层统一声明 vars_files: 加载 group_vars/all 或 env_vars/{{ env }}.yml
- include_playbook 中无法直接用 loop 遍历 playbook 列表(Ansible 不支持),但可用 include_tasks + loop + 动态文件名组合实现组件批量加载
- 所有跨 stage 共享的数据(如生成的证书路径、部署版本号)应写入 hostvars[inventory_hostname] 或使用 set_fact: cacheable=true,避免因 import 导致变量丢失
- 在 CI/CD 流水线中,对 import_playbook 的修改需触发全量回归;而 include_playbook 的变更可配合 tag 精确控制执行范围,提升发布效率
一个精简但可扩展的骨架示例
目录结构:
deploy/
├── site.yml # import stages/provision.yml 等
├── stages/
│ ├── provision.yml # import components/ntp.yml, components/kernel-tune.yml
│ └── deploy.yml # include_playbook: "{{ item }}" with_items: "{{ app_components }}"
├── components/
│ ├── ntp.yml # idempotent time sync
│ ├── nginx.yml # include_tasks for template + service
│ └── redis-cluster.yml # supports cluster_mode: true/false via vars
└── group_vars/
└── all.yml # common_timeout: 300, app_components: ["nginx", "redis-cluster"]

















