目录一、前言二、核心区别import导入和 include包含三、导入完整剧本import_playbook四、导入任务文件import_tasks五、包含任务文件include_tasks六、条件语句作用区别七、任务文件高级用法变量传参八、使用场景与注意事项适用场景注意事项九、常见问题问答一、前言在实际写 Ansible 剧本时一旦项目变大所有任务都堆在一个 YAML 文件里会非常混乱代码重复、难以阅读、修改麻烦、出错概率高。为了解决这个问题Ansible 提供了 ** 导入import和包含include** 两种机制允许我们把任务、剧本拆成多个小文件在需要的时候调用进来。这样不仅结构清晰还能实现任务复用大幅提升可维护性。二、核心区别import导入和 include包含import 导入静态执行。Ansible 在解析剧本阶段就把文件内容直接插入到当前位置相当于 “复制粘贴进去”。include 包含动态执行。Ansible 在运行到这一行时才去加载文件支持根据条件动态决定是否加载。三、导入完整剧本import_playbookimport_playbook用于直接引入另一个完整的 Playbook 文件。它只能写在剧本最外层不能写在 tasks 里面。示例- name: 部署Web服务 import_playbook: web.yml - name: 部署数据库 import_playbook: db.yml也可以和当前剧本交替执行- name: 本地初始化 hosts: localhost tasks: - debug: msg开始执行主剧本 - name: 引入子剧本 import_playbook: other_play.yml执行顺序先运行主 Play再运行导入的所有 Play。四、导入任务文件import_tasksimport_tasks用于静态导入外部任务文件在解析时就把任务全部展开。示例任务文件web.yml- name: 安装 httpd dnf: name: httpd state: latest - name: 启动服务 service: name: httpd state: started enabled: true在主剧本中导入- name: 配置Web服务器 hosts: web tasks: - import_tasks: web.ymlimport_tasks 特点解析时就加载文件运行前就能看到所有任务。when条件会作用到导入的每一个任务。不支持循环不能用变量当文件名。支持--start-at-task从指定任务开始运行。五、包含任务文件include_tasksinclude_tasks是动态包含只有执行到这一行时才会加载文件。使用方式- name: 配置Web服务 hosts: web tasks: - include_tasks: web.ymlinclude_tasks 特点when只控制是否包含这个文件不影响文件内部任务。--list-tasks不会显示内部任务只显示这一行 include。不能用--start-at-task跳到内部任务。支持动态文件名、循环包含。六、条件语句作用区别方式条件作用范围说明import_*所有导入的任务每个任务都会带上条件include_*仅当前 include 行条件满足才加载文件内部任务不受影响简单理解import条件复制给所有任务include条件只决定要不要加载文件七、任务文件高级用法变量传参我们可以把任务文件写成通用模板通过传入变量实现复用。示例通用任务文件install.yml- name: 安装软件包 dnf: name: {{ package }} state: latest - name: 启动服务 service: name: {{ service }} state: started enabled: true调用时传入变量tasks: - import_tasks: install.yml vars: package: nginx service: nginx这样同一个文件可以安装 Nginx、Httpd、MySQL 等各种服务。八、使用场景与注意事项适用场景按功能拆分安装、配置、启动、初始化分开文件按环境拆分测试环境、生产环境使用不同任务通用逻辑复用创建用户、安装软件、关闭防火墙注意事项老版本include已经废弃不要使用静态导入优先用import_tasks更稳定、易调试动态条件加载用include_tasksimport_playbook 只能在顶层使用不能写在 tasks 里带条件的 import 会把条件应用到所有任务逻辑要清晰九、常见问题问答import_tasks 和 include_tasks 到底该怎么选答大多数情况下用import_tasks结构稳定、容易排查问题。只有需要根据变量动态加载文件时才用 include_tasks。import_playbook 可以写在任务里吗答不可以它只能出现在剧本顶层不能放在 tasks 下。为什么老的 include 不能用了答因为老版本行为不统一容易出问题官方已经用 import 和 include 系列替代。怎么让一个任务文件安装不同的软件答把文件名、服务名写成变量调用时使用 vars 传参即可通用化。为什么 --list-tasks 看不到 include 内部的任务答因为 include 是动态加载解析剧本时不会展开只有运行时才加载所以列表看不到。