Ansible Roles:模块化组织 Playbook
Ansible Roles 角色管理:结构化组织 Playbook
什么是 Role
Role(角色)是 Ansible 组织 Playbook 的结构化方式,将任务、变量、模板、文件等按照标准目录结构组织,便于复用和管理。Role 是 Ansible 推荐的最佳实践。
Role 目录结构
site.yml
webservers.yml
fooservers.yml
roles/
├── common/
│ ├── defaults/
│ │ └── main.yml
│ ├── files/
│ ├── handlers/
│ │ └── main.yml
│ ├── meta/
│ │ └── main.yml
│ ├── tasks/
│ │ └── main.yml
│ ├── templates/
│ │ └── config.j2
│ ├── tests/
│ │ ├── inventory
│ │ └── test.yml
│ └── vars/
│ └── main.yml
└── webservers/
└── ...(同上结构)
目录说明
| 目录 | 说明 |
|---|---|
| defaults/ | 默认变量(优先级最低) |
| files/ | 静态文件(使用 copy 模块复制) |
| handlers/ | Handlers(处理器) |
| meta/ | Role 元信息(依赖关系等) |
| tasks/ | 任务列表 |
| templates/ | Jinja2 模板文件 |
| tests/ | 测试文件 |
| vars/ | 变量(优先级高于 defaults) |
创建 Role
使用 ansible-galaxy 创建
# 创建 Role
ansible-galaxy role init myrole
# 创建完整 Role
ansible-galaxy role init --init-path roles myrole
# 创建简化 Role
ansible-galaxy role init --init-path roles myrole --role-skeleton=default
手动创建 Role
# 创建目录结构
mkdir -p roles/myrole/{defaults,files,handlers,meta,tasks,templates,vars}
# 创建任务文件
cat > roles/myrole/tasks/main.yml << EOF
---
- name: Install package
apt:
name: "{{ package_name }}"
state: present
- name: Copy configuration
template:
src: config.j2
dest: /etc/myapp/config.conf
notify: Restart service
EOF
# 创建 handlers 文件
cat > roles/myrole/handlers/main.yml << EOF
---
- name: Restart service
service:
name: "{{ service_name }}"
state: restarted
EOF
# 创建默认变量
cat > roles/myrole/defaults/main.yml << EOF
---
package_name: myapp
service_name: myapp
config_path: /etc/myapp
EOF
使用 Role
在 Playbook 中使用 Role
---
- name: Apply roles
hosts: webservers
become: yes
roles:
- common
- nginx
- mysql
传递变量给 Role
---
- name: Apply roles with variables
hosts: webservers
become: yes
roles:
- role: nginx
nginx_port: 8080
nginx_worker_processes: 4
- role: mysql
mysql_root_password: secret
mysql_databases:
- app_db
- test_db
条件执行 Role
---
- name: Conditional roles
hosts: all
become: yes
roles:
- role: common
- role: docker
when: ansible_os_family == "Debian"
- role: selinux
when: ansible_selinux.status == "enabled"
Role 依赖
定义依赖
roles/myrole/meta/main.yml:
---
dependencies:
- role: common
version: "1.0"
- role: nginx
nginx_port: 8080
- src: geerlingguy.docker
version: "3.0.0"
依赖变量
---
dependencies:
- role: common
vars:
common_timezone: "UTC"
- role: nginx
vars:
nginx_port: "{{ my_role_nginx_port }}"
完整示例:Nginx Role
Role 结构
roles/nginx/
├── defaults/
│ └── main.yml
├── handlers/
│ └── main.yml
├── tasks/
│ ├── main.yml
│ ├── install.yml
│ └── configure.yml
└── templates/
├── nginx.conf.j2
└── site.conf.j2
默认变量
defaults/main.yml:
---
nginx_port: 80
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_document_root: /var/www/html
nginx_server_name: localhost
Handlers
handlers/main.yml:
---
- name: Reload Nginx
service:
name: nginx
state: reloaded
- name: Restart Nginx
service:
name: nginx
state: restarted
主任务文件
tasks/main.yml:
---
- name: Include install tasks
include_tasks: install.yml
tags: ['install']
- name: Include configure tasks
include_tasks: configure.yml
tags: ['configure']
tasks/install.yml:
---
- name: Install Nginx (Debian)
apt:
name: nginx
state: present
update_cache: yes
when: ansible_os_family == "Debian"
- name: Install Nginx (RedHat)
yum:
name: nginx
state: present
when: ansible_os_family == "RedHat"
tasks/configure.yml:
---
- name: Ensure document root exists
file:
path: "{{ nginx_document_root }}"
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Copy Nginx configuration
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
notify: Reload Nginx
- name: Copy site configuration
template:
src: site.conf.j2
dest: /etc/nginx/sites-available/default
owner: root
group: root
mode: '0644'
notify: Reload Nginx
- name: Start Nginx
service:
name: nginx
state: started
enabled: yes
使用 Nginx Role
---
- name: Deploy web servers
hosts: webservers
become: yes
roles:
- role: nginx
nginx_port: 8080
nginx_document_root: /var/www/myapp
nginx_server_name: myapp.example.com
tags: ['nginx']
Ansible Galaxy
安装第三方 Role
# 安装 Role
ansible-galaxy role install geerlingguy.docker
# 安装多个 Role
ansible-galaxy role install geerlingguy.docker geerlingguy.nginx
# 安装到指定目录
ansible-galaxy role install geerlingguy.docker -p roles/
# 从 requirements.yml 安装
ansible-galaxy role install -r requirements.yml
requirements.yml
---
roles:
- name: docker
src: geerlingguy.docker
version: "3.0.0"
- name: nginx
src: geerlingguy.nginx
- name: mysql
src: https://github.com/geerlingguy/ansible-role-mysql.git
version: master
创建和发布 Role
# 初始化 Role
ansible-galaxy role init myrole
# 构建 Role 归档
ansible-galaxy role build
# 发布 Role(需要 Galaxy 账户)
ansible-galaxy role publish
最佳实践
- 模块化设计: 每个角色负责单一功能
- 默认变量: 在 defaults/main.yml 中定义默认值
- 文档化: 添加 README 说明 Role 用法
- 版本控制: 使用 Git 管理 Role 版本
- 依赖管理: 使用 meta/main.yml 管理依赖
- 测试: 编写测试用例验证 Role 功能
总结
Role 是 Ansible 组织代码的最佳方式,能够大幅提高 Playbook 的可维护性和复用性。通过本文的学习,你已经掌握了 Role 的目录结构、创建方法、使用技巧和依赖管理等知识。合理使用 Role 可以让你的自动化运维更加专业和高效。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。







