商城首页欢迎来到中国正版软件门户

您的位置:首页 >在 RHEL 上构建复杂的 Ansible Playbook

在 RHEL 上构建复杂的 Ansible Playbook

  发布于2026-08-13 阅读(0)

扫一扫,手机访问

{"position":0,"title":"介绍","layout":"doc-fullscreen","text":"## 介绍nn在本实验中,你将学习在 RHEL 上构建复杂 Ansible Playbook 的关键技术,以创建更易于管理、可扩展且可重用的自动化。你将从基本概念过渡到高级组织策略,重点关注如何精确控制自动化运行的主机,以及如何将大型 Playbook 拆分成逻辑上独立的模块化组件。nn你将首先掌握主机选择,使用基本组名、通配符、排除项和逻辑运算符来定位 inventory 中的特定节点。接下来,你将通过使用 `include_tasks` 和 `import_tasks` 将任务重构到单独的文件中来探索模块化。最后,你将学习使用 `import_playbook` 组合一个完整的、多 Playbook 的工作流,最终完成对你完全结构化和模块化的 Ansible 项目的执行和验证。n","need_verify":false,"has_solution":false},{"position":1,"title":"使用基本模式和通配符模式选择主机","layout":"doc-workbench-split","text":"## 使用基本模式和通配符模式选择主机nn在本步骤中,你将学习 Ansible 自动化中定位特定主机的基础知识。其核心是 Ansible inventory 文件,它列出了你管理的服务器,以及 Playbook 中的 `hosts` 指令,该指令指定一组任务应在哪些服务器上运行。我们将从安装 Ansible、创建基本的 inventory 和 Playbook 开始,然后探索如何使用组名和通配符模式选择主机。nn首先,让我们确保你的环境中已安装 Ansible。Ansible 默认未安装,因此你需要使用 DNF 包管理器进行安装。`ansible-core` 包提供了 Ansible 的核心命令行工具,包括 `ansible-playbook`。运行以下命令:nn```bashnsudo dnf install -y ansible-coren```nn你应该会看到类似以下的输出:nn```plaintextn...nInstalled:n ansible-core-2.16.x-x.el9.x86_64n ...nComplete!n```nn接下来,让我们为本次练习创建一个专用目录,以保持文件整洁。本步骤中所有后续操作都将在该新目录中进行:nn```bashnmkdir -p ~/project/ansible_patternsncd ~/project/ansible_patternsn```nn现在,创建一个 inventory 文件。Inventory 是一个文本文件,用于定义 Ansible 命令、模块和任务在其上运行的主机和主机组。我们将使用 INI 格式,因为它更简单。nn使用 `nano` 编辑器创建一个名为 `inventory` 的文件:nn```bashnnano inventoryn```nn向 `inventory` 文件添加以下内容。这定义了两个组:`webservers` 和 `dbservers`,每个组包含两个主机:nn```inin[webservers]nweb1.example.comnweb2.example.comnn[dbservers]ndb1.lab.netndb2.lab.netn```nn保存文件并退出 `nano`,按 `Ctrl+X`,然后按 `Y`,最后按 `Enter`。nnInventory 已准备就绪,现在让我们创建一个简单的 Playbook。此 Playbook 将使用 `ansible.builtin.debug` 模块打印一条消息,确认任务正在哪个主机上运行。这是测试主机模式而无需对系统进行任何实际更改的好方法。nn创建一个名为 `playbook.yml` 的新文件:nn```bashnnano playbook.ymln```nn添加以下 YAML 内容。最初,它将目标设置为 `webservers` 组中的所有主机:nn```yamln---n- name: Test Host Patternsn hosts: webserversn gather_facts: falsen tasks:n - name: Display the inventory hostnamen ansible.builtin.debug:n msg: "This task is running on {{ inventory_hostname }}"n```nn保存并退出编辑器。现在,使用 `ansible-playbook` 运行 Playbook。`-i` 标志用于指定我们的自定义 inventory 文件:nn```bashnansible-playbook playbook.yml -i inventoryn```nn输出应如下所示:nn```plaintextnPLAY [Test Host Patterns] ******************************************************nnTASK [Display the inventory hostname] ******************************************nok: [web1.example.com] => {n "msg": "This task is running on web1.example.com"n}nok: [web2.example.com] => {n "msg": "This task is running on web2.example.com"n}nnPLAY RECAP *********************************************************************nweb1.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0nweb2.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0n```nn如你所见,只有 `webservers` 组中的主机被定位。现在,让我们修改 Playbook 以使用通配符 (`*`)。通配符允许更灵活的模式匹配。nn编辑 `playbook.yml` 并将 `hosts` 行更改为 `hosts: "*.lab.net"`。请记住将包含通配符的模式用引号括起来:nn```yamln---n- name: Test Host Patternsn hosts: "*.lab.net"n gather_facts: falsen tasks:n - name: Display the inventory hostnamen ansible.builtin.debug:n msg: "This task is running on {{ inventory_hostname }}"n```nn再次运行 Playbook:nn```bashansible-playbook playbook.yml -i inventory 运行后,输出大致会是这样: PLAY [Test Host Patterns] ****************************************************** TASK [Display the inventory hostname] ****************************************** ok: [db1.lab.net] => { "msg": "This task is running on db1.lab.net" } ok: [db2.lab.net] => { "msg": "This task is running on db2.lab.net" } PLAY RECAP ********************************************************************* db1.lab.net : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 db2.lab.net : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 这一次,Play 只会在那些以 `.lab.net` 结尾的主机上执行。接下来,再用特殊关键字 `all`,把 inventory 里定义的所有主机都匹配出来。 最后,再编辑一次 `playbook.`yml` 并将 `hosts` 行更改为 `hosts: all`:nn```yamln---n- name: Test Host Patternsn hosts: alln gather_facts: falsen tasks:n - name: Display the inventory hostnamen ansible.builtin.debug:n msg: "This task is running on {{ inventory_hostname }}"n```nn运行 Playbook 以查看结果:nn```bashnansible-playbook playbook.yml -i inventoryn```nn输出将显示所有被定位的主机:nn```plaintextnPLAY [Test Host Patterns] ******************************************************nnTASK [Display the inventory hostname] ******************************************nok: [web1.example.com] => {n "msg": "This task is running on web1.example.com"n}nok: [web2.example.com] => {n "msg": "This task is running on web2.example.com"n}nok: [db1.lab.net] => {n "msg": "This task is running on db1.lab.net"n}nok: [db2.lab.net] => {n "msg": "This task is running on db2.lab.net"n}nnPLAY RECAP *********************************************************************ndb1.lab.net : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0ndb2.lab.net : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0nweb1.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0nweb2.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0n```nnPlaybook 现在将在你的 inventory 中的所有四个主机上运行,展示了 `all` 模式的强大功能。n","need_verify":true,"has_solution":false},{"position":2,"title":"使用排除项和逻辑运算符优化主机选择","layout":"doc-workbench-split","text":"## 使用排除项和逻辑运算符优化主机选择nn在本步骤中,你将通过学习如何使用排除项和逻辑运算符来提升你的主机选择技能。这些功能允许进行高度精确的定位,这在管理复杂环境时至关重要。你将学习如何使用 `!` (NOT) 运算符排除主机,以及如何使用 `&` (AND) 运算符组合组。我们将继续使用上一步中的 `inventory` 和 `playbook.yml` 文件。nn首先,请确保你位于正确的工作目录:nn```bashncd ~/project/ansible_patternsn```nn为了有效地演示逻辑运算符,我们需要在主机组之间创建一些重叠。让我们编辑 `inventory` 文件,添加一个名为 `production` 的新组,该组包含一个 Web 服务器和一个数据库服务器:nn```bashnnano inventoryn```nn将 `[production]` 组及其成员添加到文件末尾:nn```inin[webservers]nweb1.example.comnweb2.example.comnn[dbservers]ndb1.lab.netndb2.lab.netnn[production]nweb1.example.comndb1.lab.netn```nn保存文件并退出 `nano`,按 `Ctrl+X`,然后按 `Y`,最后按 `Enter`。nn现在,让我们练习排除。`!` 运算符(表示 NOT)允许你从选择中排除主机或组。修改你的 `playbook.yml` 以定位除 `dbservers` 组中的主机之外的所有主机:nn```bashnnano playbook.ymln```nn如下所示更新 `hosts` 行。模式 `all,!dbservers` 会选择所有主机,然后移除其中属于 `dbservers` 组的任何主机:nn```yamln---n- name: Test Host Patternsn hosts: all,!dbserversn gather_facts: falsen tasks:n - name: Display the inventory hostnamen ansible.builtin.debug:n msg: "This task is running on {{ inventory_hostname }}"n```nn保存并退出编辑器,然后运行 Playbook:nn```bashnansible-playbook playbook.yml -i inventoryn```nn你应该只会看到 Web 服务器被定位:nn```plaintextnPLAY [Test Host Patterns] ******************************************************nnTASK [Display the inventory hostname] ******************************************nok: [web1.example.com] => {n "msg": "This task is running on web1.example.com"n}nok: [web2.example.com] => {n "msg": "This task is running on web2.example.com"n}nnPLAY RECAP *********************************************************************nweb1.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0nweb2.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0n```nn正如预期的那样,只有 `webservers` 组中的主机被定位。nn接下来,让我们探索逻辑 AND 运算符。`&` 运算符仅选择同时存在于 *两个* 指定组中的主机(交集)。让我们修改 Playbook 以定位同时属于 `webservers` 组和 `production` 组的主机:nn```bashnnano playbook.ymln```nn将 `hosts` 行更改为 `webservers,&production`:nn```yamln---n- name: Test Host Patternsn hosts: webservers,&productionn gather_facts: falsen tasks:n - name: Display the inventory hostnamen ansible.builtin.debug:n msg: "This task is running on {{ inventory_hostname }}"n```nn保存并运行 Playbook:nn```bashnansible-playbook playbook.yml -i inventoryn```nn这次,只有两个组的交集将被定位:nn```plaintextnPLAY [Test Host Patterns] ******************************************************nnTASK [Display the inventory hostname] ******************************************nok: [web1.example.com] => {n "msg": "This task is running on web1.example.com"n}nnPLAY RECAP *********************************************************************nweb1.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0n```nn输出正确地显示只有 `web1.example.com` 被定位,因为它同时是 `webservers` 和 `production` 组的成员。这些运算符让你能够精确控制自动化影响的主机。n","need_verify":true,"has_solution":false},{"position":3,"title":"使用 include_tasks 和 import_tasks 模块化 Play","layout":"doc-workbench-split","text":"## 使用 `include_tasks` 和 `import_tasks` 模块化 Playnn在本步骤中,你将学习如何通过将大型 Ansible 项目分解为更小、可重用的文件来构建它们。随着 Playbook 的增长,将所有任务保存在单个文件中会变得难以管理。Ansible 为此提供了两个主要指令:`import_tasks` 和 `include_tasks`。两者都允许你从另一个文件中引入任务。nn- `import_tasks` 是**静态的**。它在 Playbook 被 Ansible 首次解析时处理。这最适合 Play 中无条件、结构化的部分。n- `include_tasks` 是**动态的**。它在 Play 执行期间处理。这使其适用于循环和条件语句。nn我们现在将重构我们的 Playbook 以同时使用它们。首先,请确保你位于项目目录中:nn```bashncd ~/project/ansible_patternsn```nn在继续之前,让我们更新 inventory 文件,使主机指向 localhost 以便在此实验环境中使用。这将允许 Playbook 成功运行:nn```bashnnano inventoryn```nn用以下配置替换内容,该配置将示例主机映射到 localhost:nn```inin[webservers]nweb1.example.com ansible_host=localhost ansible_connection=localnweb2.example.com ansible_host=localhost ansible_connection=localnn[dbservers]ndb1.lab.net ansible_host=localhost ansible_connection=localndb2.lab.net ansible_host=localhost ansible_connection=localn```nn保存并退出编辑器。此配置使用 `ansible_host=localhost` 将连接重定向到本地机器,并使用 `ansible_connection=local` 来避免 SSH 连接尝试。nn一种常见的做法是将可重用的任务文件存储在专用的子目录中。让我们创建一个名为 `tasks` 的目录:nn```bashnmkdir tasksn```nn现在,让我们为可能适用于许多服务器的通用设置任务创建一个文件。我们将在此处放置一个安装 `httpd` Web 服务器包的任务:nn```bashnnano tasks/web_setup.ymln```nn添加以下内容。请注意,此文件只是一个任务列表;它不包含完整的 Play 结构(如 `hosts:` 或 `name:`):nn```yamln- name: Install the httpd packagen ansible.builtin.dnf:n name: httpdn state: presentn become: truen```nn保存并退出 `nano`。接下来,创建第二个任务文件用于简单的验证步骤:nn```bashnnano tasks/verify_config.ymln```nn将此调试任务添加到此文件中:nn```yamln- name: Display a verification messagen ansible.builtin.debug:n msg: "Configuration tasks applied to {{ inventory_hostname }}"n```nn保存并退出编辑器。现在,让我们修改主 `playbook.yml` 文件以使用这些新的任务文件。我们将使用 `import_tasks` 进行静态设置,使用 `include_tasks` 进行动态验证消息:nn```bashnnano playbook.ymln```nn用以下内容替换 `playbook.yml` 的全部内容。此 Playbook 现在将目标设置为 `webservers` 组,并使用模块化任务文件:nn```yamln---n- name: Configure Web Serversn hosts: webserversn gather_facts: falsen tasks:n - name: Import web server setup tasksn import_tasks: tasks/web_setup.ymlnn - name: Include verification tasksn include_tasks: tasks/verify_config.ymln```nn保存文件并运行 Playbook:nn```bashnansible-playbook playbook.yml -i inventoryn```nn你应该会看到模块化任务正在执行:nn```plaintextnPLAY [Configure Web Servers] ***************************************************nnTASK [Import web server setup tasks] *******************************************nimported: /home/labex/project/ansible_patterns/tasks/web_setup.ymlnnTASK [Install the httpd package] ***********************************************nchanged: [web1.example.com]nchanged: [web2.example.com]nnTASK [Include verification tasks] **********************************************nincluded: /home/labex/project/ansible_patterns/tasks/verify_config.yml for web1.example.com, web2.example.comnnTASK [Display a verification message] ******************************************nok: [web1.example.com] => {n "msg": "Configuration tasks applied to web1.example.com"n}nok: [web2.example.com] => {n "msg": "Configuration tasks applied to web2.example.com"n}nnPLAY RECAP *********************************************************************nweb1.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0nweb2.example.com : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0n```nn请注意输出如何清晰地指示何时从各自的文件导入和包含任务。这种模块化方法使你的自动化更简洁,更易于维护。n","need_verify":true,"has_solution":false},{"position":4,"title":"使用 import_playbook 组合工作流","layout":"doc-workbench-split","text":"## 使用 `import_playbook` 组合工作流nn在本步骤中,你将学习如何使用 `import_playbook` 来编排整个 Playbook,以形成复杂的工作流。虽然 `import_tasks` 和 `include_tasks` 用于在单个 Play 中重用任务列表,但 `import_playbook` 在更高级别上运行。它允许你创建一个主 Playbook,该 Playbook 按特定顺序执行其他独立的 Playbook。这是管理大规模自动化(例如,配置整个应用程序堆栈)的标准方法。nn首先,让我们确保我们位于正确的目录中,并为这种新结构组织我们的项目:nn```bashncd ~/project/ansible_patternsn```nn将单个组件 Playbook 存储在专用的子目录中是一种最佳实践。让我们创建一个名为 `playbooks` 的目录:nn```bashnmkdir playbooksn```nn现在,将我们在上一步中创建的配置 Web 服务器的 Playbook 移动到这个新目录中。将其重命名以使其更具描述性也是一个好主意:nn```bashnmv playbook.yml playbooks/web_configure.ymln```nn但是,由于我们将 Playbook 移动到了子目录中,因此我们需要更新任务文件的相对路径。任务文件仍然位于相对于主项目目录的 `tasks/` 目录中,因此我们需要调整路径:nn```bashnnano playbooks/web_configure.ymln```nn在 Playbook 中更新路径,使用 `../tasks/` 而不是 `tasks/`:nn```yamln---n- name: Configure Web Serversn hosts: webserversn gather_facts: falsen tasks:n - name: Import web server setup tasksn import_tasks: ../tasks/web_setup.ymlnn - name: Include verification tasksn include_tasks: ../tasks/verify_config.ymln```nn保存并退出编辑器。nn让我们测试已更正的 Playbook,以确保路径正常工作:nn```bashnansible-playbook playbooks/web_configure.yml -i inventoryn```nn你应该会看到 Playbook 使用更正的路径成功执行。nn接下来,为配置数据库服务器创建一个新的独立 Playbook。此 Playbook 将定位 `dbservers` 组并安装 `mariadb` 包:nn```bashnnano playbooks/db_setup.ymln```nn将以下内容添加到文件中。这是一个完整、独立的 Play:nn```yamln---n- name: Configure Database Serversn hosts: dbserversn gather_facts: falsen tasks:n - name: Install mariadb packagen ansible.builtin.dnf:n name: mariadbn state: presentn become: true - name: Display a confirmation message ansible.builtin.debug: msg: "Database server {{ inventory_hostname }} configured." ``` 保存并退出编辑器。现在,两个 Playbook 组件就齐了:一个负责 Web 服务器,一个负责数据库服务器。 最后,再创建一个顶级的“主”Playbook。这个文件本身不放任何主机或任务,它的作用很单纯:按正确顺序导入其他 Playbook,定义整个工作流。 ```bash nano main.yml ``` 添加以下内容。这会创建一个工作流,先配置 Web 服务器,再配置数据库服务器: ```yaml --- - name: Import the web server configuration play import_playbook: playbooks/web_configure.yml - name: Import the database server configuration play import_playbook: playbooks/db_setup.yml ``` 保存并退出 `nano`。现在,运行 `main.yml` 这个 Playbook,就能执行整条工作流: ```bash ansible-playbook main.yml -i inventory ``` 输出会显示两个 Playbook 按顺序执行: ```plaintext PLAY [Configure Web Servers] *************************************************** TASK [Import web server setup tasks] *******************************************nimported: /home/labex/project/ansible_patterns/playbooks/../tasks/web_setup.ymlnnTASK [Install the httpd package] ***********************************************nok: [web1.example.com]nok: [web2.example.com]nnTASK [Include verification tasks] **********************************************nincluded: /home/labex/project/ansible_patterns/playbooks/../tasks/verify_config.yml for web1.example.com, web2.example.comnnTASK [Display a verification message] ******************************************nok: [web1.example.com] => {n "msg": "Configuration tasks applied to web1.example.com"n}nok: [web2.example.com] => {n "msg": "Configuration tasks applied to web2.example.com"n}nnPLAY [Configure Database Servers] **********************************************nnTASK [Install mariadb package] *************************************************nchanged: [db1.lab.net]nchanged: [db2.lab.net]nnTASK [Display a confirmation message] ******************************************nok: [db1.lab.net] => {n "msg": "Database server db1.lab.net configured."n}nok: [db2.lab.net] => {n "msg": "Database server db2.lab.net configured."n}nnPLAY RECAP *********************************************************************ndb1.lab.net : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0ndb2.lab.net : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0nweb1.example.com : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0nweb2.example.com : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0n```nn输出清楚地显示了两个独立的 Play 按顺序执行,演示了 `import_playbook` 如何有效地从较小的、可管理的部分组合成更大的工作流。n","need_verify":true,"has_solution":false},{"position":5,"title":"执行和验证完整的模块化 Playbook","layout":"doc-workbench-split","text":"## 执行和验证完整的模块化 Playbooknn在最后一步中,你将执行你构建的完整模块化工作流,更重要的是,你将学习如何验证自动化是否已在目标系统上达到预期状态。一个成功的 Playbook 运行固然好,但确认结果对于可靠的自动化至关重要。nn首先,请确保你位于主项目目录中:nn```bashncd ~/project/ansible_patternsn```nn在运行最终 Playbook 之前,让我们可视化你创建的完整项目结构。`tree` 命令非常适合此目的。如果尚未安装,你可以使用 `dnf` 进行安装:nn```bashnsudo dnf install -y treentree .n```nn你应该会看到类似以下的结构:nn```plaintextn.n├── inventoryn├── main.ymln├── playbooksn│ ├── db_setup.ymln│ └── web_configure.ymln└── tasksn ├── verify_config.ymln └── web_setup.ymlnn2 directories, 6 filesn```nn这种结构,包含一个主入口点 (`main.yml`)、单独的 Playbook 文件和可重用的任务文件,是管理 Ansible 项目的可扩展且可维护的方式。nn现在,通过运行你的顶层 `main.yml` Playbook 来执行整个工作流:nn```bashnansible-playbook main.yml -i inventoryn```nn在 Playbook 成功完成后,下一步至关重要的是验证。你需要确认系统处于你期望的状态。我们的 Playbook 设计用于在 Web 服务器上安装 `httpd` 包,在数据库服务器上安装 `mariadb` 包。由于此实验中的所有任务都在你的本地机器上运行,我们可以使用 `rpm` 命令直接验证它们的安装。nn首先,检查 `httpd` 包是否作为 Web 服务器配置的一部分被安装:nn```bashnrpm -q httpdn```nn你应该会看到确认包已安装的输出:nn```plaintextnhttpd-2.4.xx-x.el9.x86_64n```nn接下来,验证数据库服务器配置中 `mariadb` 包的安装:nn```bashnrpm -q mariadbn```nn同样,你应该会看到 mariadb 已安装的确认信息:nn```plaintextnmariadb-10.5.xx-x.el9.x86_64n```nn在输出中看到包名称,即可确认你的 Ansible Playbook 已按预期成功配置了系统。你现在已成功从头到尾构建、执行和验证了一个模块化的 Ansible 项目。n","need_verify":true,"has_solution":false},{"position":6,"title":"总结","layout":"doc-fullscreen","text":"## 总结nn在此次实验中,你学习了在 RHEL 上构建复杂 Ansible Playbook 的基本技术。你从主机选择的基础知识开始,使用基本组名、通配符、排除项和逻辑运算符来精确地定位 inventory 文件中定义的主机。然后,重点转移到模块化,你在此练习了使用 `include_tasks` 进行动态包含和使用 `import_tasks` 进行静态包含,将大型 Play 分解为更易于管理和重用的组件。nn在此基础上,你学习了如何通过 `import_playbook` 将单个 Playbook 链接在一起,以组合一个完整的多阶段工作流。实践过程包括安装 Ansible、创建项目结构,以及逐步将一个简单的 Playbook 重构为复杂的多文件结构。本次实验的最终环节是执行最终的复合 Playbook,并验证整个自动化工作流是否成功地针对正确的目标主机运行,展示了一种有组织且可扩展的自动化方法。n","need_verify":false,"has_solution":false}
本文转载于:https://labex.io/zh/tutorials/ansible-structuring-complex-ansible-playbooks-on-rhel-590576 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注