Ansible 角色使用指南
Ansible 角色使用指南
1. 引言
在 Ansible 实践中,随着 Playbook 开发数量的增加,开发者常会面临代码重复利用的需求。例如,为某一应用配置 MySQL 数据库的 Playbook,可能需要调整主机名、密码等参数后用于另一应用,但复杂 Playbook(含多个包含 / 导入文件、任务与处理程序)的复制复用难度较高
Ansible 角色(Role)通过标准化目录结构,将任务、变量、文件、模板等资源打包,实现代码的通用化复用。只需复制角色目录到新项目,即可在 Playbook 中调用,同时支持通过变量自定义角色行为,大幅提升 Ansible 配置的效率与可维护性
2. Ansible 角色概述
2.1 角色的核心作用
以通用方式打包 Ansible 资源(任务、变量、文件、模板等),解决以下问题:
- 避免复杂 Playbook 的重复复制与修改
- 实现代码在多项目间的快速迁移与复用
- 通过变量自定义角色行为,适配不同场景(如不同应用的 MySQL 配置)
2.2 角色的核心优点
- 便捷共享:分组整理内容,便于与团队成员共享代码
- 标准化系统要素:可编写角色定义 Web 服务器、数据库服务器、Git 仓库等基础系统组件
- 简化大项目管理:拆分复杂项目为多个角色,降低维护难度
- 支持并行开发:不同管理员可并行开发不同角色,提升协作效率
- 多来源获取:除自定义外,可从 RHEL 系统角色包(
rhel-system-roles
)或 Ansible Galaxy 社区获取现成角色
3. Ansible 角色的标准化结构
Ansible 角色通过固定的子目录组织资源,每个子目录对应特定功能,核心结构如下表所示:
目录名称 | 核心用途 | 关键文件 / 说明 |
---|---|---|
Defaults | 存储角色变量的默认值(优先级最低,可被 Playbook 覆盖) | main.yml :定义默认变量,如数据库默认端口、用户名 |
Files | 存储角色任务引用的静态文件(如配置文件、脚本) | 无需特殊命名,任务中直接引用文件名(Ansible 自动在此目录查找) |
Handlers | 存储角色的处理程序(需触发的任务,如服务重启) | main.yml :定义处理程序,如restart httpd |
Meta | 存储角色的元数据 | main.yml :包含作者、许可证、支持平台、角色依赖等信息 |
Tasks | 存储角色的核心任务 | main.yml :定义角色的执行步骤,如安装软件、配置服务 |
Templates | 存储角色任务引用的Jinja2 模板文件(后缀.j2 ,支持变量替换) | 如index.html.j2 ,任务中通过template 模块引用 |
Tests | 存储角色的测试资源 | 包含测试用清单(Inventory)和test.yml Playbook |
Vars | 存储角色的内部变量(优先级较高,不建议 Playbook 修改) | main.yml :定义角色内部使用的固定变量,如软件安装路径 |
4. 在 Playbook 中使用 Ansible 角色
4.1 基本使用方法
在 Playbook 的roles
部分指定角色名称,Ansible 会自动加载角色的任务、变量、处理程序等资源
4.1.1 简单调用示例
# /etc/ansible/test.yml
---
- name: 测试角色调用hosts: node1 # 目标受控节点roles: - role1 # 第一个角色- role2 # 第二个角色(按顺序执行)
4.1.2 角色资源引用规则
- 任务中使用
copy
/script
模块时,直接引用Files
目录下的文件名(无需路径) - 使用
template
模块时,直接引用Templates
目录下的.j2
文件(无需路径) - 使用
include_tasks
/import_tasks
时,直接引用Tasks
目录下的任务文件
4.2 变量覆盖与自定义
角色的变量优先级:Playbook中定义的变量
> Vars目录变量
> Defaults目录变量
。可在 Playbook 中传递变量,覆盖角色默认值
4.2.3 示例:创建并调用sy
角色
-
初始化角色
使用ansible-galaxy init
命令创建角色目录结构:[student@master ansible]$ cd roles/ [student@master roles]$ ansible-galaxy init sy - Role sy was created successfully
定义角色内部变量(Vars)
编辑sy/vars/main.yml
,设置高优先级内部变量:[student@master roles]$ vim sy/vars/main.yml --- # vars file for sy a1: 11 # 变量a1默认值11 a2: 22 # 变量a2默认值22 ~
编写角色任务(Tasks)
编辑sy/tasks/main.yml
,定义任务(引用变量a1
):
[student@master roles]$ vim sy/tasks/main.yml
---
# tasks file for sy
- name: a1 #输出变量a1的值debug:msg: "{{ a1 }}" # 引用变量a1
~
创建 Playbook 调用角色并覆盖变量
编辑/etc/ansible/test.yml
,在调用sy
角色时覆盖a1
的值:
[student@master roles]$ cd ..
[student@master ansible]$ vim test.yml
---
- name: # 测试变量覆盖hosts: node1roles:- role: sy # 指定角色a1: 333 # 覆盖Vars中的a1(从11改为333)
~
执行 Playbook 验证结果
[root@master ansible]# ansible-playbook test.yml
# 输出结果中,msg会显示333(而非11),说明变量已覆盖
[student@master ansible]$ ansible-playbook test.yml PLAY [node1] *******************************************************************TASK [Gathering Facts] *********************************************************
ok: [node1]TASK [sy : a1] *****************************************************************
ok: [node1] => {"msg": 333
}PLAY RECAP *********************************************************************
node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
5. 控制角色与任务的执行顺序
5.1 默认执行顺序
Playbook 中任务的默认执行流程:
pre_tasks(预任务)
→ roles(角色任务)
→ tasks(普通任务)
→ post_tasks(后任务)
- 处理程序(Handlers):若
pre_tasks
触发处理程序,会在roles
前执行;若tasks
触发,会在post_tasks
前执行
5.2 示例:自定义执行顺序
[student@master ansible]$ vim order_test.yml
---
- name: # 测试执行顺序hosts: node1pre_tasks: # 预任务(角色前执行)- name: aaa 预任务:输出aaashell:cmd: echo aaanotify: cc # 触发处理程序cc(会在角色前执行)roles: # 角色任务(预任务后执行)- sypost_tasks: # 后任务(角色与处理程序后执行)- name: ooo 后任务:输出ooodebug:msg: ooohandlers: # 处理程序- name: ccdebug:msg: iii
~
[student@master ansible]$ ansible-playbook order_test.yml PLAY [node1] *******************************************************************TASK [Gathering Facts] *********************************************************
ok: [node1]TASK [aaa] *********************************************************************
changed: [node1]RUNNING HANDLER [cc] ***********************************************************
ok: [node1] => {"msg": "iii"
}TASK [sy : a1] *****************************************************************
ok: [node1] => {"msg": 11
}TASK [ooo] *********************************************************************
ok: [node1] => {"msg": "ooo"
}PLAY RECAP *********************************************************************
node1 : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
执行结果顺序:
- 执行
pre_tasks
中的 “输出 aaa” - 触发并执行处理程序
cc
(输出 iii) - 执行
sy
角色的任务 - 执行
post_tasks
中的 “输出 ooo”
5.3 动态 / 静态导入角色
除roles
部分外,可通过include_role
(动态)或import_role
(静态)在普通任务中导入角色:
[student@master ansible]$ vim dynamic_import.yml
---
- name: # 动态导入角色示例hosts: node1tasks:- name: # 普通任务1:输出信息debug:msg: chenyufdsf- name: # 导入sy角色(动态)include_role: # 动态导入(运行时加载)name: sy# 或使用import_role: name: cy(静态导入,解析时加载)- name: # 普通任务2:输出信息debug:msg: 11111
~
6. Ansible 角色创建示例:部署 HTTP 服务
6.1 需求
- 根据下列要求,在/home/student/ansible/roles 中创建名为 httpd 的角色:
1)安装 httpd 软件,并能够开机自动运行
2)开启防火墙,并允许 httpd 通过
3)使用模板 index.html.j2,用来创建/var/www/html/index.html 网页,
内容如下(HOSTNAME 是受管理节点的完全域名,IPADDRESS 是 IP 地址):
Welcome to HOSTNAME on IPADDRESS
然后创建剧本 /home/student/ansible/myrole.yml,为 webtest 主机组启用 httpd 角色
6.2 步骤
1. 初始化http
角色
[student@master ansible]$ cd roles/
[student@master roles]$ ansible-galaxy init httpd
- Role httpd was created successfully
2. 编写 Jinja2 模板(Templates)
创建index.html.j2
,引用 Ansiblefacts 获取主机信息:
[student@master roles]$ cd httpd/
[student@master httpd]$ vim templates/index.html.j2
Welcome to {{ ansible_fqdn }} on {{ ansible_default_ipv4.address }}
~
3. 编写角色任务(Tasks)
编辑http/tasks/main.yml
,定义所有执行步骤:
[student@master httpd]$ vim tasks/main.yml
---
# tasks file for httpd
- name: install pkgyum:name:- httpd- firewalldstate: present- name: cp htmltemplate:src: index.html.j2dest: /var/www/html/index.html- name: restart serviceservice:name: "{{ item }}"state: restartedenabled: yesloop:- httpd- firewalld- name: set firewalldfirewalld:service: httpstate: enabledpermanent: yesimmediate: yes
~
4. 创建 Playbook 调用http
角色
编辑/etc/ansible/myrole.yml
,在webtest节点上运行:
[student@master httpd]$ cd ..
[student@master roles]$ cd ..
[student@master ansible]$ vim myrole.yml
---
- name: httpdhosts: webtestroles:- httpd
~
5. 执行 Playbook
[student@master ansible]$ ansible-playbook myrole.yml
7. RHEL 系统角色
RHEL 提供预定义的系统角色(rhel-system-roles
),可快速配置常见系统服务
7.1 安装系统角色
[student@master ansible]$ yum -y install rhel-system-roles
7.2 常用 RHEL 系统角色
角色名称 | 功能描述 |
---|---|
rhel-system-roles.kdump | 配置 kdump 崩溃恢复服务 |
rhel-system-roles.network | 配置网络接口(IP、网关等) |
rhel-system-roles.selinux | 管理 SELinux(模式、文件上下文、布尔值) |
rhel-system-roles.timesync | 配置时钟同步(NTP/PTP) |
rhel-system-roles.postfix | 配置 Postfix 作为邮件传输代理(MTA) |
rhel-system-roles.firewall | 配置主机防火墙规则 |
rhel-system-roles.tuned | 配置 tuned 服务,优化系统性能 |
7.3 系统角色位置
安装后,角色存储于/usr/share/ansible/roles/
目录下
7.4 示例:使用timesync
角色配置时钟同步
需求
在所有受控节点上使用timesync
角色,配置:
- 使用 NTP 协议同步时间
- 时间服务器为
classroom.example.com
- 启用
iburst
参数(快速同步)
步骤
- 复制系统角色到 Ansible 角色目录
[student@master ansible]$ cd /usr/share/ansible/roles/
[student@master roles]$ ls
.....
rhel-system-roles.timesync
.....
[student@master roles]$ cp -r rhel-system-roles.timesync -p /home/student/ansible/roles/timesync
2.创建 Playbook(timesync.yml)
[student@master ansible]$ vim timesync.yml
---
- name: timesync # 配置时钟同步hosts: test01vars: # 定义角色变量timesync_ntp_servers:- hostname: ansible.example.com # 时间服务器iburst: yes # 启用iburstroles:- timesync # 调用timesync角色
~
3.执行 Playbook
[student@master ansible]$ ansible-playbook timesync.yml
8. 从 Ansible Galaxy 安装与管理角色
Ansible Galaxy(galaxy.ansible.com)是社区角色仓库,可通过ansible-galaxy
命令下载、安装、管理角色
8.1 角色安装路径
- 默认路径:
~/.ansible/roles
(遵循 Ansible 的roles_path
配置) - 自定义路径:使用
-p DIRECTORY
选项指定
8.2 安装角色(通过 requirements 文件)
1. 创建 requirements 文件
定义需安装的角色及来源(本地文件、HTTP 链接等):
# /etc/ansible/roles/test.yml(requirements文件)
- name: haproxy # 角色名src: file:///root/haproxy.tar.gz # 本地角色压缩包- name: phpinfo # 角色名src: file:///root/phpinfo.tar.gz # 本地角色压缩包
2. 执行安装命令
[root@server ansible]# ansible-galaxy install -r /etc/ansible/roles/test.yml -p /etc/ansible/roles/
# -r:指定requirements文件;-p:指定安装目录
# 输出:
# - downloading role from file:///root/haproxy.tar.gz
# - extracting haproxy to /etc/ansible/roles/haproxy
# - haproxy was installed successfully
# - downloading role from file:///root/phpinfo.tar.gz
# - extracting phpinfo to /etc/ansible/roles/phpinfo
# - phpinfo was installed successfully
8.3 管理本地角色
1. 列出本地角色
[root@server ansible]# ansible-galaxy list
# 输出:
# /etc/ansible/roles
# - haproxy, (unknown version)
# - phpinfo, (unknown version)
2. 删除本地角色
[root@server ansible]# ansible-galaxy remove haproxy
# 输出:- successfully removed haproxy# 验证删除结果
[root@server ansible]# ansible-galaxy list
# /etc/ansible/roles
# - phpinfo, (unknown version)
9. 总结
Ansible 角色通过标准化目录结构,实现了代码的复用、共享与标准化管理,大幅简化了复杂项目的配置与维护。核心价值包括:
- 复用性:打包资源,跨项目快速调用
- 灵活性:通过变量自定义角色行为,适配不同场景
- 可维护性:拆分大项目为独立角色,支持并行开发
- 丰富性:可使用自定义角色、RHEL 系统角色或 Ansible Galaxy 社区角色
掌握角色的创建、使用与管理,是提升 Ansible 自动化效率的关键步骤