90DaysOfDevOps 实战:用 Ansible Roles 与 Galaxy 重构 Playbook,让配置管理可扩展 文档/教程【免费下载链接】90DaysOfDevOpsThis repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.项目地址https://gitcode.com/gh_mirrors/90/90DaysOfDevOps点击查看免费下载导读本文是 90DaysOfDevOps 项目中 2022/pl/day66.md 的深度展开主题是Ansible Playbook 的进阶工程化在完成 Vagrant 四节点实验环境与 Web 服务器配置后通过拆分 tasks/handlers 到子目录和引入 Ansible Roles ansible-galaxy两种手段将单体 Playbook 重构为结构清晰、可复用、可扩展的自动化代码。读完本文你将掌握 Playbook 瘦身、import_tasks静态导入、ansible-galaxy init角色脚手架、角色目录规范以及如何处理旧版include语法的弃用警告——这些能力正是把 DevOps 配置管理从小实验推向生产级的基础。回顾Day 65 建立的实验环境在进入本课之前项目此前已通过 Configmgmt/Vagrantfile 拉起了一个包含 4 台虚拟机的迷你实验室并指定其中的 Linux 节点作为 Ansible 控制机control node。前文已跑通了若干 Playbook 场景最终得到一份能让 web01 与 web02 各自成为独立 Web 服务器的 Playbook。也就是说此刻我们的拓扑是控制机Linux 节点承载 Ansible 与 SSH 管理web01 / web02已被配置为 Apache2 Web 服务器另外两台节点尚无角色后续将分别承担数据库mysql与负载均衡nginx职能。前序 Playbook 的完整代码位于 Configmgmt/ansible-scenario1首个含模板的单体版本与 Configmgmt/simple_play.yml最简示例可以对照阅读体会演进脉络。让 Playbook 保持整洁拆分 tasks 与 handlers当 Playbook 里任务、处理器、模板越来越多时单个 YAML 文件会迅速变得难以维护。原文给出的第一步重构是把**任务tasks和处理器handlers**分别抽到独立子目录中让 Playbook 本体只保留编排逻辑。第一步把 tasks 抽到独立文件将原本写在 Playbook 中的 Apache 部署任务复制到tasks/apache2_install.yml- name: ensure apache is at the latest version apt: nameapache2 statelatest - name: write the apache2 ports.conf config file template: srctemplates/ports.conf.j2 dest/etc/apache2/ports.conf notify: restart apache - name: write a basic index.html file template: src: templates/index.html.j2 dest: /var/www/html/index.html notify: - restart apache - name: ensure apache is running service: name: apache2 state: started这段任务的职责非常清晰对应四条核心动作任务模块作用aptapt确保 apache2 为最新版本写入 ports.conftemplate用 Jinja2 模板渲染 Apache 端口配置并notify触发重启写入 index.htmltemplate渲染自定义欢迎页到/var/www/html/同样触发重启启动服务service确保 apache2 处于 started 状态注意notify的用法它并不会立即执行重启而是登记一个 handler只有在该任务真正改变状态时才在 Playbook 末尾触发——这正是 Ansible 幂等设计的体现。第二步把 handlers 抽到独立文件同样把重启处理器复制到handlers/main.yml- name: restart apache service: name: apache2 state: restarted第三步Playbook 通过导入引用它们重构后的 Playbook 更名为playbook2.yml通过import_tasks把外部文件静态引入。仓库中的真实实现见 Configmgmt/ansible-scenario2/playbook2.yml- hosts: webservers become: yes vars: http_port: 8000 https_port: 4443 html_welcome_msg: Hello 90DaysOfDevOps - Welcome to Day 66! tasks: - import_tasks: tasks/apache2_install.yml handlers: - import_tasks: handlers/main.yml这里值得留意Playbook 通过vars声明了http_port、https_port、html_welcome_msg三个变量它们会被模板消费详见下文模板如何消费变量。整份重构后的完整场景代码位于 Configmgmt/ansible-scenario2目录结构如下ansible-scenario2/ ├── handlers/ │ └── main.yml # restart apache 处理器 ├── tasks/ │ └── apache2_install.yml ├── templates/ │ ├── index.html.j2 │ └── ports.conf.j2 └── playbook2.yml验证用 curl 检查那次简单的改动原文提示如果你从仓库复制文件会注意到 write a basic index.html file 任务发生了变化——template的写法从src... dest...键值对风格变成了src: ...和dest: ...YAML 映射风格。两种语法等价后者是更规范、可读性更好的现代写法仓库中的 ansible-scenario2/tasks/apache2_install.yml 同时保留了这两种风格正好用来对比学习。在控制机上执行验证命令curl web01:8000curl 之所以访问 8000 端口是因为ports.conf.j2模板将 Apache 监听端口渲染为{{ http_port }}而http_port在 Playbook 的vars中被赋值为 8000。执行后应能看到由index.html.j2渲染出的欢迎页内容。到这里第一层重构完成Playbook 本体只剩编排信息任务与处理器各自归位即使未来任务数量成倍增长文件也不会失控。Roles 与 Ansible Galaxy把 Web 服务器配置变成可复用单元拆分 tasks/handlers 只是整理而Roles角色才是 Ansible 实现复用与分层的核心机制。当我们要把剩余节点配置为数据库服务器与负载均衡器时用 Role 把某类主机该做什么完整封装是标准的工程化路径。ansible-galaxy角色管理的瑞士军刀ansible-galaxy是 Ansible 自带的角色管理命令既可以从 Ansible Galaxy 共享社区下载现成角色也可以本地初始化一个标准角色骨架。本课用它来创建 apache2 角色ansible-galaxy init roles/apache2执行后会在roles/apache2/下生成一套标准的角色目录结构。仓库中该角色已完整落地见 Configmgmt/ansible-scenario3/roles/apache2roles/apache2/ ├── defaults/ │ └── main.yml # 角色默认变量最低优先级 ├── handlers/ │ └── main.yml # restart apache ├── meta/ │ └── main.yml # 角色元数据作者、依赖等 ├── tasks/ │ ├── apache2_install.yml │ └── main.yml # 角色任务入口 ├── templates/ │ ├── index.html.j2 │ └── ports.conf.j2 ├── tests/ │ ├── inventory │ └── test.yml # 角色自测用例 ├── vars/ │ └── main.yml # 角色内部变量 └── README.md这套目录是 Ansible 的约定优于配置Ansible 运行角色时会按固定顺序加载这些目录中的main.yml——先是defaults默认值最低优先级随后按依赖关系加载meta最后执行taskshandlers、templates、vars则各司其职。迁移现有内容到角色结构骨架建好后把上一节ansible-scenario2中的成果搬入对应目录tasks/apache2_install.yml→roles/apache2/tasks/apache2_install.ymltemplates/index.html.j2、templates/ports.conf.j2→roles/apache2/templates/handlers/main.yml→roles/apache2/handlers/main.yml。由于 Ansible 约定角色的任务入口固定为tasks/main.yml还需在入口文件中导入真正的任务清单。仓库实现见 Configmgmt/ansible-scenario3/roles/apache2/tasks/main.yml--- # tasks file for roles/apache2 - import_tasks: apache2_install.yml改造 Playbook从声明任务到声明角色接下来把 Playbook 改为引用角色。在playbook1.ymltasks 直接内联与playbook2.ymltasks 用 import_tasks 引入两个版本中任务与处理器的声明方式各不相同而角色化之后Playbook 只需在roles键下罗列角色名即可。仓库中重构后的 Configmgmt/ansible-scenario3/playbook3.yml 如下- hosts: webservers become: yes vars: http_port: 8000 https_port: 4443 html_welcome_msg: Hello 90DaysOfDevOps - Welcome to Day 66! roles: - apache2对比playbook2.yml原来的tasks:与handlers:段落消失了取而代之的是roles: - apache2。Ansible 会自动寻找roles/apache2/目录并执行其中的任务与处理器同时角色内部可以访问 Playbook 级vars中声明的变量。运行角色化后的 Playbookansible-playbook playbook3.yml处理弃用警告include 与 import_tasks 的取舍运行playbook3.yml时输出中会出现一条deprecation弃用警告。原因在于早期版本中tasks/main.yml使用旧式include指令来引入任务文件而旧式裸include已被 Ansible 官方弃用。虽然 Playbook 仍能执行但按官方建议应尽快修正。修复方式是把tasks/main.yml中的引入方式改为import_tasks静态导入在 Playbook 解析阶段就把任务展开--- # tasks file for roles/apache2 - import_tasks: apache2_install.yml这里可以展开说明两者的本质区别这也是从源码结构能清晰观察到的设计意图import_tasks静态导入解析期展开任务列表在运行前就已确定支持when条件作用于整段导入、不支持循环变量传递适合导入结构固定的任务清单——角色入口用它最稳妥include_tasks动态导入运行期按需加载支持在循环中按变量动态决定导入哪个文件但会带来一定解析开销与行为不确定性。修复后再次运行ansible-playbook playbook3.yml弃用警告即消失。修正后的完整场景代码见 Configmgmt/ansible-scenario3。模板如何消费变量从源码看渲染链路角色化后模板文件被迁移到roles/apache2/templates/下。阅读仓库源码可以完整还原变量 → 模板 → 目标文件的渲染链路ports.conf.j2 的核心行Listen {{ http_port }} IfModule ssl_module Listen {{ https_port }} /IfModule IfModule mod_gnutls.c Listen {{ https_port }} /IfModuleindex.html.j2 的完整内容html h1{{ html_welcome_msg }}/h1 /html可见ports.conf.j2消费http_port、https_portindex.html.j2消费html_welcome_msg三者都由 Playbook 级vars提供。这也解释了为什么curl web01:8000能取到 8000 端口上的欢迎页——模板渲染、端口监听、内容展示形成了一条完整的自动化链路。角色内defaults/main.yml与vars/main.yml目前是空的见 defaults/main.yml说明变量优先级完全由 Playbook 顶层vars提供实际生产中可以下沉到defaults让角色自带默认值并允许被外部覆盖。为负载均衡与通用配置再建两个角色Web 服务器角色化只是开始。剩余的数据库节点与负载均衡节点同样需要角色化继续用ansible-galaxy初始化# common适用于所有服务器通用工具、基础配置 ansible-galaxy init roles/common # nginx用于负载均衡 / 反向代理节点 ansible-galaxy init roles/nginx至此仓库中已具备 apache2、common、nginx 三个角色。项目后续场景ansible-scenario4、ansible-scenario5、ansible-scenario6、ansible-scenario7在此基础上持续演进从 nginx 负载均衡配置roles/nginx/tasks/configure_nginx.yml、roles/nginx/templates/mysite.j2、common 通用工具安装roles/common/tasks/install_tools.yml到group_vars/all/common_variables.yml的变量分层以及 mysql 角色roles/mysql/tasks/install_mysql.yml、setup_mysql.yml——把每个节点职能封装成角色正是本课方法论在后续章节的延续也是读者可以提前通读这些目录来印证的方向。小结与下一步本课完成了两级重构模块级拆分tasks、handlers、templates 各归其位Playbook 只保留编排与变量ansible-scenario2角色级抽象用ansible-galaxy init生成标准角色骨架把 Web 服务器配置整体封装为roles/apache2Playbook 通过roles:一行引用并顺手修复了旧式include的弃用警告ansible-scenario3。这两种做法都指向同一个目标让 Playbook 在节点数量与业务复杂度增长时依然保持清晰、可复用、可测试。已部署但尚未配置的数据库与负载均衡节点将在下一篇Day 67中借助 common、nginx、mysql 等角色逐步落地。想要继续动手实践请把 Configmgmt/ansible-scenario3 的完整目录复制到控制机对照本文逐文件阅读再在实验环境中重跑ansible-playbook playbook3.yml观察输出差异。赞分享文档/教程【免费下载链接】90DaysOfDevOpsThis repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.项目地址https://gitcode.com/gh_mirrors/90/90DaysOfDevOps点击查看免费下载相关推荐90DaysOfDevOps Day 66 实战用 Ansible Galaxy 与 Roles 重构 Apache Playbook90DaysOfDevOps Day 66 实战用 Ansible Galaxy 与 Roles 重构 Apache Playbook 本文是 90DaysO文档/教程90DaysOfDevOps Day66Ansible Playbook 结构优化——从扁平任务到 Roles 与 Ansible Galaxy 的角色化重构90DaysOfDevOps Day66Ansible Playbook 结构优化——从扁平任务到 Roles 与 Ansible Galaxy 的角色化重构文档/教程90DaysOfDevOps 第 66 天Ansible Playbooks 进阶——任务与处理器拆分、Roles 与 Ansible Galaxy 实战90DaysOfDevOps 第 66 天Ansible Playbooks 进阶——任务与处理器拆分、Roles 与 Ansible Galaxy 实战 本文档/教程上一篇5分钟掌握PUBG罗技鼠标宏告别压枪烦恼的终极指南下一篇GitHub Copilot GPT 提示词全解析AI 编程助手的系统指令设计、能力矩阵与输出协议创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考