Ansible自动化(十四):Roles(角色)

一、Role 是什么?

Ansible Role(角色) 是一种将 Playbook 模块化、结构化的方式,用于提高自动化脚本的可重用性、可维护性和可移植性。

  • 核心思想:把一个完整的 Playbook 拆分成多个逻辑部分(如任务、变量、模板、文件等),并组织成标准目录结构。
  • 解决的问题
    • Playbook 越写越长,难以维护;
    • 不同项目之间重复编写相似逻辑;
    • 缺乏标准化和共享机制。

一句话总结:Role = 标准化的 Playbook 组件包,便于跨项目复用。


二、Roles 的目录结构及作用

使用 ansible-galaxy init <role_name> 可以快速生成标准角色目录:

bash 复制代码
ansible-galaxy init website

生成的目录结构如下:

复制代码
website/
├── defaults/         # 默认变量(优先级最低)
├── files/            # 静态文件(如 index.html)
├── handlers/         # 触发器(如 restart nginx)
├── meta/             # 元数据(依赖、作者信息等)
├── tasks/            # 主要任务(角色的核心)
├── templates/        # Jinja2 模板文件(如 nginx.conf.j2)
├── tests/            # 测试用例(如何调用该角色)
├── vars/             # 自定义变量(优先级高于 defaults)
└── README.md         # 使用说明文档

各目录详解:

目录 用途 示例
defaults/main.yml 定义默认变量值 web_name: nginx
vars/main.yml 用户自定义变量(覆盖 defaults) port: 8080
tasks/main.yml 执行的主要任务列表 安装软件、启动服务等
handlers/main.yml 被 notify 触发的任务 重启服务
templates/*.j2 Jinja2 模板文件 动态生成配置文件
files/ 静态文件(直接复制) HTML 页面、证书等
meta/main.yml 角色元信息(依赖、平台支持等) 依赖其他角色
tests/ 测试 playbook 和 inventory 如何运行此角色

三、实战:开发一个 Nginx Web 网站角色(website)

🎯 需求说明:

  • 默认部署 nginx
  • 若用户指定其他 Web 服务器(如 httpd),则部署指定服务;
  • 若为 nginx,则:
    • 监听 ens160 接口 IP 的 8080 端口;
    • /usr/share/nginx/html/test.html 中写入 hello roles

1. 创建角色

bash 复制代码
ansible-galaxy init website

2. 编写各组件

defaults/main.yml(默认变量)
yaml 复制代码
---
web_name: nginx

如果用户未指定 web_name,则默认使用 nginx。


files/test.html
html 复制代码
hello roles

这是一个静态文件,将被复制到目标主机。


handlers/main.yml
yaml 复制代码
---
- name: get_status
  systemd:
    name: nginx
    state: restarted

当配置文件变更时,触发此 handler 重启 nginx。


tasks/main.yml(核心任务)
yaml 复制代码
---
- name: install pkgs for web
  yum:
    name: "{{ web_name }}"
    state: present

- name: start service
  service:
    name: "{{ web_name }}"
    state: started

- name: modify nginx configure file
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  when: web_name == "nginx"
  notify: get_status

- name: copy file for test.html
  copy:
    src: test.html
    dest: /usr/share/nginx/html/test.html
  when: web_name == "nginx"

使用 when 条件判断,仅在部署 nginx 时执行特定任务。


templates/nginx.conf.j2
jinja2 复制代码
...
listen       {{ ansible_ens160.ipv4.address }}:8080 default_server;
...

利用 Ansible 自动收集的 facts(如 ansible_ens160.ipv4.address)动态生成监听地址。
💡 注意:确保目标主机有 ens160 网卡,或根据实际网卡名调整(如 ens33)。


3. 调用角色的 Playbook(site.yml

yaml 复制代码
---
- hosts: webservers
  roles:
    - website

或传入变量:

yaml 复制代码
---
- hosts: webservers
  vars:
    web_name: httpd
  roles:
    - website

四、复杂角色的高级用法

1. 拆分 tasks(提高可读性)

tasks/main.yml 太长时,可拆分为多个文件:

yaml 复制代码
# tasks/main.yml
---
- include_tasks: install_pkgs.yml
- include_tasks: start_service.yml
- include_tasks: modify_file.yml
- include_tasks: copy_file.yml

每个子文件只负责一个功能,便于团队协作。


2. 使用 pre_taskspost_tasks

在角色执行前后插入额外任务:

yaml 复制代码
---
- hosts: node02
  pre_tasks:
    - name: Ensure nginx is not installed
      yum:
        name: nginx
        state: absent
  roles:
    - website
  post_tasks:
    - name: Confirm deployment success
      debug:
        msg: "website role success"

⚠️ 执行顺序始终为:
pre_tasksrolestasks(如果有)→ post_tasks


五、使用外部角色

1. 红帽官方角色(RHEL 系统)

bash 复制代码
yum install rhel-system-roles -y

包含网络、防火墙、内核调优等企业级角色。


2. Ansible Galaxy(社区角色库)

官网:https://galaxy.ansible.com

常用命令:
命令 说明 示例
ansible-galaxy search nginx 搜索角色 查找 nginx 相关角色
ansible-galaxy role install geerlingguy.nginx 安装角色 从 Galaxy 下载
ansible-galaxy role install geerlingguy.nginx -p ./roles 指定安装路径 存放到当前项目 roles 目录
ansible-galaxy role list 列出已安装角色 查看本地有哪些角色
ansible-galaxy role info geerlingguy.nginx 查看角色详情 作者、版本、描述等
ansible-galaxy role remove geerlingguy.nginx 卸载角色 删除本地角色

✅ 最佳实践:将角色安装到项目内的 roles/ 目录,避免全局污染。


六、Ansible 版本演进简述

版本 特点
Ansible 2.9 及以前 所有模块内置,单体架构
Ansible-core 2.10+ 拆分为:• ansible-core(核心引擎 + 100+ 基础模块)• Collections(内容集合) :包含模块、插件、角色等完整 Ansible = ansible-core + Collections
Ansible Navigator 在容器中运行 Ansible(开发友好)
Red Hat AAP (Ansible Automation Platform) 企业级平台(原 Tower/AWX)

🔍 重要提示 :从 Ansible 2.10 开始,很多模块(如 firewalld)不再默认包含,需通过 Collections 安装。


七、角色管理最佳实践

  • 命名规范 :使用 作者名.角色名(如 geerlingguy.nginx);
  • 版本控制:通过 Git 管理自研角色;
  • 依赖管理 :在 meta/main.yml 中声明依赖;
  • 测试驱动 :利用 tests/ 目录编写测试用例;
  • 文档齐全README.md 必须包含使用示例。

✅ 练习题(巩固所学)

基础题

  1. 使用 ansible-galaxy init myweb 创建一个新角色。
  2. defaults/main.yml 中设置默认 web 服务为 nginx,端口为 8080
  3. 编写 tasks/main.yml,实现:
    • 安装指定 web 服务;
    • 启动服务;
    • 若为 nginx,复制 index.html 到网页根目录。
  4. 创建 templates/nginx.conf.j2,使其监听 {``{ ansible_default_ipv4.address }}:{``{ port }}
  5. 编写一个 playbook 调用该角色,并传入变量 web_name: httpd

进阶题

  1. tasks/main.yml 拆分为 install.ymlconfig.ymlstart.yml 三个文件,并用 include_tasks 引入。
  2. 在 playbook 中添加 pre_tasks,确保旧版 nginx 被卸载;添加 post_tasks,输出"部署完成"。
  3. 从 Ansible Galaxy 安装 geerlingguy.docker 角色到本地 roles/ 目录,并查看其 README。
  4. 解释 defaultsvars 中同名变量哪个生效?为什么?
  5. 如果目标主机网卡是 eth0 而不是 ens160,如何让模板自动适配任意网卡 IP?

💡 提示 :第 10 题可使用 ansible_default_ipv4.address(默认路由接口的 IP)或遍历 ansible_interfaces 动态获取。


相关推荐
Nobody__117 小时前
解决多台服务器 UID/GID 做对齐后,文件系统元数据未更新的情况
运维·服务器
兆龙电子单片机设计18 小时前
【STM32项目开源】STM32单片机智能语音家居控制系统
stm32·单片机·嵌入式硬件·物联网·开源·自动化
梦想的旅途218 小时前
基于 UI 自动化(RPA)实现企业微信外部群操作的架构设计
ui·自动化·rpa
霸气十足+拼命+追梦少年18 小时前
服务器挂载U盘或硬盘
运维·服务器
小杰帅气18 小时前
进程优先级与切换调度
linux·运维·服务器
码农学院18 小时前
使用腾讯翻译文本
服务器·数据库·c#
华纳云IDC服务商18 小时前
DNS负载均衡能自动避开故障服务器吗?
运维·服务器·负载均衡
奋斗的阿狸_198619 小时前
键盘组合键监听与 xterm 唤醒程序
linux·运维·服务器
小张成长计划..19 小时前
【linux】2:linux权限的概念
linux·运维·服务器