【Linux&Ansible】学习笔记合集七

Ansible 复杂 Playbook 管理与角色化实践

一、Ansible 复杂 Play 与 Playbook 管理

在 Ansible 自动化运维中,面对多任务、多主机的复杂场景,需通过任务拆分、模块化导入、变量复用实现 Playbook 的轻量化与可维护性,核心围绕任务文件拆分、嵌套导入、通用任务封装展开实操。

1. 环境准备与基础 Playbook 编写

(1)切换工作目录

进入实验专属工作目录,统一管理 Playbook、任务文件及相关资源,执行命令:

复制代码
cd ~/projects-review
(2)编写基础单文件 Playbook

编写playbook.yml实现 web 服务基础部署,包含 httpd 安装、启动、配置文件拷贝,指定单台 / 多台目标主机:

复制代码
cat playbook.yml << 'EOF'
---
- name: Install and configure web service
  hosts:
    - servera.lab.example.com
    - serverb.lab.example.com
    - serverc.lab.example.com
    - serverd.lab.example.com
  tasks:
    - name: Install httpd
      ansible.builtin.dnf:
        name: httpd
        state: latest
    - name: Enable and start httpd
      ansible.builtin.service:
        name: httpd
        enabled: true
        state: started
    - name: Tuning configuration installed
      ansible.builtin.copy:
        src: files/tune.conf
        dest: /etc/httpd/conf.d/tune.conf
        owner: root
        group: root
EOF
(3)内置变量测试主机匹配

编写host-test.yml,使用 Ansible 内置变量inventory_hostname测试通配符主机匹配规则,关闭事实收集提升执行效率:

复制代码
cat > host-test.yml << 'EOF'
---
- name: List inventory hostnames
  hosts: server*.lab.example.com
  gather_facts: no
  tasks:
    - name: List inventory hostnames
      ansible.builtin.debug:
        msg: "{{ inventory_hostname }}"
EOF

执行测试命令,验证主机匹配结果:

复制代码
ansible-navigator run -m stdout host-test.yml
(4)简化 Playbook 主机配置

修改playbook.yml,使用通配符简化多主机配置,适配批量部署场景:

复制代码
vim playbook.yml
# 替换hosts配置为通配符形式
hosts: server*.lab.example.com

2. 任务文件拆分与静态导入

将基础 Playbook 中的任务按功能拆分,通过import_tasks实现任务文件的静态导入,实现任务模块化管理。

(1)创建任务目录

创建专属任务目录,统一存放拆分后的任务文件:

复制代码
mkdir tasks
(2)拆分 web 服务核心任务

编写tasks/web_tasks.yml,封装 httpd 安装、启动、配置文件拷贝核心任务,配置 handler 触发条件:

复制代码
cat > tasks/web_tasks.yml << "EOF"
---
- name: Install httpd
  ansible.builtin.dnf:
    name: httpd
    state: latest

- name: Enable and start httpd
  ansible.builtin.service:
    name: httpd
    enabled: true
    state: started

- name: Tuning configuration installed
  ansible.builtin.copy:
    src: files/tune.conf
    dest: /etc/httpd/conf.d/tune.conf
    owner: root
    group: root
    mode: 0644
  notify:
    - restart httpd
EOF
(3)重构基础 Playbook 并导入任务

修改playbook.yml,通过import_tasks导入 web 核心任务,新增防火墙部署相关任务,定义 handler 实现配置变更后 httpd 重启:

复制代码
cat > playbook.yml << "EOF"
---
- name: Install and configure web service
  hosts: server*.lab.example.com

  tasks:
    - name: Import the web_tasks.yml task file
      import_tasks: tasks/web_tasks.yml

    - name: Install firewalld
      ansible.builtin.dnf:
        name: firewalld
        state: latest

    - name: Enable and start the firewall
      ansible.builtin.service:
        name: firewalld
        enabled: true
        state: started

    - name: Open the port for http
      ansible.posix.firewalld:
        service: http
        immediate: true
        permanent: true
        state: enabled

  handlers:
    - name: restart httpd
      ansible.builtin.service:
        name: httpd
        state: restarted
EOF

3. 全量任务拆分与多层级导入

将防火墙任务也拆分独立文件,实现Playbook→核心任务文件→功能任务文件的多层级模块化管理,进一步提升可维护性。

(1)拆分防火墙任务文件

编写tasks/firewall_tasks.yml,封装防火墙安装、启动、http 端口开放任务:

复制代码
cat > tasks/firewall_tasks.yml << "EOF"
---
- name: Install firewalld
  ansible.builtin.dnf:
    name: firewalld
    state: latest

- name: Enable and start the firewall
  ansible.builtin.service:
    name: firewalld
    enabled: true
    state: started

- name: Open the port for http
  ansible.posix.firewalld:
    service: http
    immediate: true
    permanent: true
    state: enabled
EOF
(2)重构 Playbook 实现多任务文件导入

修改playbook.yml,通过import_tasks分别导入 web 和防火墙任务文件,精简主 Playbook 内容:

复制代码
cat > playbook.yml << "EOF"
---
- name: Install and configure web service
  hosts: server*.lab.example.com

  tasks:
    - name: Import the web_tasks.yml task file
      import_tasks: tasks/web_tasks.yml

    - name: Import the firewall_tasks.yml task file
      import_tasks: tasks/firewall_tasks.yml

  handlers:
    - name: restart httpd
      ansible.builtin.service:
        name: httpd
        state: restarted
EOF

4. 通用任务封装与变量传参

提取软件安装 + 服务启动的通用逻辑,封装为可复用任务文件,通过变量传参实现多服务适配,实现任务逻辑的最大化复用。

(1)封装通用任务文件

编写tasks/install_and_enable.yml,定义package和service通用变量,适配任意软件的安装与服务启动:

复制代码
cat > tasks/install_and_enable.yml << "EOF"
---
- name: Install {{ package }}
  ansible.builtin.dnf:
    name: "{{ package }}"
    state: latest

- name: Enable and start {{ service }}
  ansible.builtin.service:
    name: "{{ service }}"
    enabled: true
    state: started
EOF
(2)修改子任务文件实现变量传参

修改tasks/web_tasks.yml,导入通用任务文件并传递 httpd 相关变量:

复制代码
cat > tasks/web_tasks.yml << "EOF"
---
- name: Install and start httpd
  import_tasks: install_and_enable.yml
  vars:
    package: httpd
    service: httpd

- name: Tuning configuration installed
  ansible.builtin.copy:
    src: files/tune.conf
    dest: /etc/httpd/conf.d/tune.conf
    owner: root
    group: root
    mode: 0644
  notify:
    - restart httpd
EOF

修改tasks/firewall_tasks.yml,导入通用任务文件并传递 firewalld 相关变量:

复制代码
cat > tasks/firewall_tasks.yml << "EOF"
---
- name: Install and start firewalld
  import_tasks: install_and_enable.yml
  vars:
    package: firewalld
    service: firewalld

- name: Open the port for http
  ansible.posix.firewalld:
    service: http
    immediate: true
    permanent: true
    state: enabled
EOF

5. Playbook 语法检查与执行

完成多层级任务封装与导入后,先进行语法校验,再执行 Playbook 实现批量部署。

(1)语法检查

执行语法检查命令,验证 Playbook 及所有导入任务文件的语法合法性:

复制代码
ansible-navigator run -m stdout playbook.yml --syntax-check
(2)执行 Playbook

执行最终的 Playbook,实现目标主机的 web 服务与防火墙自动化部署:

复制代码
ansible-navigator run -m stdout playbook.yml

二、使用角色和 Ansible 内容集合简化 Playbook

Ansible角色(Role) 和内容集合(Collection) 是实现自动化代码标准化、可复用的核心特性,通过角色封装完整的功能逻辑,通过集合管理角色与相关资源,大幅简化复杂场景的 Playbook 编写。

1. 环境准备与内容集合安装

(1)切换工作目录

进入角色实验专属工作目录:

复制代码
cd ~/role-review
(2)安装 Ansible 内容集合

将redhat.rhel_system_roles集合安装到项目本地collections/目录,实现本地资源隔离:

复制代码
ansible-galaxy collection install -p collections/ redhat-rhel_system_roles-1.19.3.tar.gz
(3)验证集合安装结果

执行命令查看已安装的集合,确认版本与路径正确性:

复制代码
ansible-galaxy collection list

2. 基础角色化 Playbook 编写

编写基础 Playbookweb_dev_server.yml,指定目标主机组,开启强制处理程序确保 handler 必执行:

复制代码
vim web_dev_server.yml << 'EOF'
---
- name: Configure Dev Web Server
  hosts: dev_webserver
  force_handlers: yes
EOF
(1)语法检查与基础执行
复制代码
# 语法检查
ansible-navigator run -m stdout web_dev_server.yml --syntax-check
# 基础执行
ansible-navigator run -m stdout web_dev_server.yml

3. 从 Git 仓库拉取现成角色

通过requirements.yml配置 Git 仓库中的现成角色,实现角色的自动化拉取与安装,提升开发效率。

(1)创建角色目录
复制代码
mkdir -v roles
(2)编写角色拉取配置文件

编写roles/requirements.yml,指定 Git 仓库地址、版本控制系统、角色版本:

复制代码
vim roles/requirements.yml << 'EOF'
- name: infra.apache
  src: git@workstation.lab.example.com:infra/apache
  scm: git
  version: v1.4
EOF
(3)拉取并安装角色

执行命令从 Git 仓库拉取指定版本的角色,安装到项目本地roles/目录:

复制代码
ansible-galaxy install -r roles/requirements.yml -p roles

4. 自定义角色创建与依赖配置

通过ansible-galaxy init创建标准化自定义角色,配置角色依赖实现功能复用,封装专属业务逻辑。

(1)创建自定义角色目录结构

使用ansible-galaxy init自动生成标准化的自定义角色apache.developer_configs目录结构:

复制代码
cd roles
ansible-galaxy init apache.developer_configs
cd ..
(2)配置角色依赖

修改自定义角色的元数据文件roles/apache.developer_configs/meta/main.yml,指定依赖的现成角色infra.apache:

复制代码
vim roles/apache.developer_configs/meta/main.yml << 'EOF'
dependencies:
  - name: infra.apache
    src: git@workstation.lab.example.com:infra/apache
    scm: git
    version: v1.4
EOF
(3)填充自定义角色资源

将业务相关的任务文件和模板文件放入自定义角色的指定目录,实现资源封装:

复制代码
# 覆盖角色任务文件
mv -v developer_tasks.yml roles/apache.developer_configs/tasks/main.yml
# 移动Jinja2模板文件到角色模板目录
mv -v developer.conf.j2 roles/apache.developer_configs/templates/

5. 组变量配置与角色引用

通过组变量(group_vars) 为目标主机组统一配置变量,在 Playbook 中引用自定义角色,实现角色的自动化执行。

(1)创建组变量目录并配置变量
复制代码
# 创建目标主机组的组变量目录
mkdir -pv group_vars/dev_webserver
# 移动变量文件到组变量目录
mv -v web_developers.yml group_vars/dev_webserver/
(2)在 Playbook 中引用自定义角色

修改web_dev_server.yml,添加roles节点引用自定义角色apache.developer_configs:

复制代码
vim web_dev_server.yml << 'EOF'
---
- name: Configure Dev Web Server
  hosts: dev_webserver
  force_handlers: yes
  roles:
    - apache.developer_configs
EOF
(3)语法检查与执行
复制代码
# 语法检查
ansible-navigator run -m stdout web_dev_server.yml --syntax-check
# 执行Playbook
ansible-navigator run -m stdout web_dev_server.yml

6. 前置任务配置与 Block-Rescue 异常处理

通过pre_tasks 配置系统级前置检查任务,结合Block-Rescue异常处理结构,实现 SELinux 配置的容错性处理,确保核心部署任务的稳定性。

(1)配置 pre_tasks 前置任务

修改web_dev_server.yml,添加pre_tasks节点,封装 SELinux 配置的异常处理逻辑:

复制代码
vim web_dev_server.yml << 'EOF'
---
- name: Configure Dev Web Server
  hosts: dev_webserver
  force_handlers: yes
  pre_tasks:
    - name: Verify SELinux configuration
      block:
        - include_role:
            name: redhat.rhel_system_roles.selinux
      rescue:
        - name: Handle general failure
          ansible.builtin.fail:
            msg: "SELinux role failed."
          when: not selinux_reboot_required
        - name: Restart managed host
          ansible.builtin.reboot:
            msg: "Ansible rebooting system for updates."
        - name: Reapply SELinux role to complete changes
          include_role:
            name: redhat.rhel_system_roles.selinux
  roles:
    - apache.developer_configs
EOF
(2)配置 SELinux 组变量

将 SELinux 相关变量文件移动到目标主机组的组变量目录,实现 SELinux 配置的统一管理:

复制代码
mv -v selinux.yml group_vars/dev_webserver/
(3)语法检查与最终执行
复制代码
# 语法检查
ansible-navigator run -m stdout web_dev_server.yml --syntax-check
# 最终执行
ansible-navigator run -m stdout web_dev_server.yml

7. 部署结果验证

通过curl命令访问目标主机的 web 服务,验证角色化部署的最终效果:

复制代码
curl servera
curl servera:9081
curl servera:9082

三、核心知识点总结

  1. 复杂 Playbook 管理 :通过import_tasks实现任务文件的静态拆分与多层级导入,提取通用逻辑封装为可复用任务文件,通过变量传参适配多服务场景,大幅提升 Playbook 可维护性;
  2. Ansible 内容集合 :通过ansible-galaxy collection实现集合的本地安装与管理,实现自动化资源的隔离与复用,是企业级 Ansible 开发的标准规范;
  3. 角色(Role) :通过ansible-galaxy init生成标准化角色目录,支持现成角色拉取 和自定义角色开发 ,配置meta/main.yml实现角色依赖管理,封装完整的业务功能逻辑;
  4. 变量与前置任务 :通过组变量(group_vars) 为目标主机组统一配置变量,通过pre_tasks实现系统级前置检查,结合force_handlers确保 handler 强制执行;
  5. 异常处理 :在pre_tasks中结合Block-Rescue结构实现异常捕获与容错处理,支持服务重启、角色重执行等逻辑,提升 Playbook 的健壮性。
相关推荐
Android系统攻城狮5 分钟前
Linux FFmpeg深度解析之av_parser_init调用流程与实战(二十一)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
动词ing7 分钟前
【学习笔记】51单片机 模块化编程
笔记·学习·51单片机
HideF21 分钟前
Linux 查看用户和组
linux
海绵宝宝转agent27 分钟前
计网基础知识
网络·笔记·学习·智能路由器
峯58033 分钟前
一文学习FastAPI
学习·fastapi
寺中人36 分钟前
CentOS 7进程与任务管理
linux·运维·centos·服务器搭建与管理·linux运维命令·nohup screen
外收内放39 分钟前
ENSP学习记录(6)
开发语言·学习·php
隔振降噪研究员1 小时前
裁断机一响,楼板为什么会跟着抖?
大数据·linux·数据库·人工智能
女神下凡3 小时前
芯参谋(87):Linux 系统(SPI NOR)驱动开发指南
linux·运维·arm开发·驱动开发·嵌入式硬件·设计规范
wuminyu9 小时前
JVM规范学习总结:解释器与JIT编译器如何处理JVM字节码
java·linux·c语言·jvm·c++