← 返回首页
🔧

Ansible Roles 角色管理

📂 devops ⏱ 3 min 553 words

Ansible Roles 角色管理

什么是 Role

Role 是 Ansible 中组织 Playbook 的最佳方式,它将变量、任务、处理程序、模板、文件等组件按目录结构组织,实现代码的模块化和复用。

Role 目录结构

roles/
└── nginx/
    ├── defaults/
    │   └── main.yml          # 默认变量
    ├── vars/
    │   └── main.yml          # 角色变量
    ├── tasks/
    │   └── main.yml          # 任务文件
    ├── handlers/
    │   └── main.yml          # 处理程序
    ├── templates/
    │   └── nginx.conf.j2     # Jinja2 模板
    ├── files/
    │   └── custom.conf       # 静态文件
    ├── meta/
    │   └── main.yml          # 角色元数据
    └── README.md             # 角色文档

创建 Role

使用 ansible-galaxy 创建

# 创建基本角色结构
ansible-galaxy init roles/nginx

# 查看生成的目录
ls -la roles/nginx/

手动创建目录

mkdir -p roles/nginx/{defaults,vars,tasks,handlers,templates,files,meta}

编写 Role

defaults/main.yml

# 默认变量(可被覆盖)
---
nginx_port: 80
nginx_user: www-data
nginx_worker_processes: auto
nginx_worker_connections: 1024

vars/main.yml

# 角色变量(优先级高,不可被覆盖)
---
nginx_config_dir: /etc/nginx
nginx_log_dir: /var/log/nginx

tasks/main.yml

---
- name: 安装 Nginx
  apt:
    name: nginx
    state: present
    update_cache: yes
  when: ansible_os_family == "Debian"
  tags: install

- name: 安装 Nginx (RedHat)
  yum:
    name: nginx
    state: present
  when: ansible_os_family == "RedHat"
  tags: install

- name: 复制配置文件
  template:
    src: nginx.conf.j2
    dest: "{{ nginx_config_dir }}/nginx.conf"
    owner: root
    group: root
    mode: '0644'
    backup: yes
  notify: Restart Nginx
  tags: config

- name: 确保服务运行
  service:
    name: nginx
    state: started
    enabled: yes
  tags: service

- name: 配置防火墙
  ufw:
    rule: allow
    port: "{{ nginx_port }}"
    proto: tcp
  when: ansible_os_family == "Debian"
  tags: firewall

handlers/main.yml

---
- name: Restart Nginx
  service:
    name: nginx
    state: restarted
  listen: "restart nginx"

- name: Reload Nginx
  service:
    name: nginx
    state: reloaded
  listen: "reload nginx"

templates/nginx.conf.j2

user {{ nginx_user }};
worker_processes {{ nginx_worker_processes }};
pid /run/nginx.pid;

events {
    worker_connections {{ nginx_worker_connections }};
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;
    
    include /etc/nginx/conf.d/*.conf;
}

meta/main.yml

---
galaxy_info:
  author: Your Name
  description: Nginx installation and configuration
  license: MIT
  min_ansible_version: 2.9
  platforms:
    - name: Ubuntu
      versions:
        - focal
        - bionic
    - name: EL
      versions:
        - 7
        - 8
  galaxy_tags:
    - nginx
    - webserver
    - http
    
dependencies:
  - role: common
  - role: firewall
    vars:
      firewall_allowed_ports:
        - 80
        - 443

使用 Role

在 Playbook 中引用

---
- hosts: webservers
  become: yes
  
  roles:
    - common
    - role: nginx
      vars:
        nginx_port: 8080
        nginx_worker_processes: 4
    - role: app
      tags: deploy

使用 Role 依赖

# roles/app/meta/main.yml
dependencies:
  - role: nginx
    vars:
      nginx_port: 8080
  - role: python

Role 变量优先级

# 优先级从高到低:
# 1. 命令行变量 (-e)
# 2. tasks 中的 vars
# 3. Role vars/main.yml
# 4. Playbook vars
# 5. Inventory vars
# 6. Role defaults/main.yml

Galaxy 管理

从 Galaxy 安装 Role

# 搜索 Role
ansible-galaxy search nginx

# 安装 Role
ansible-galaxy install geerlingguy.nginx

# 查看已安装 Role
ansible-galaxy list

# 从 requirements.yml 安装
ansible-galaxy install -r requirements.yml

requirements.yml

---
roles:
  - name: geerlingguy.nginx
    version: "3.1.0"
  - name: geerlingguy.mysql
    version: "4.0.0"
  
  # 从 GitHub 安装
  - name: custom-role
    src: https://github.com/user/repo.git
    version: main
    scm: git

发布 Role 到 Galaxy

# 初始化角色
ansible-galaxy init my-role

# 打包角色
ansible-galaxy role init my-role

# 上传到 Galaxy
ansible-galaxy role import GitHub用户/repo 角色名

实践案例

创建 Web 服务器 Role

# roles/webserver/tasks/main.yml
---
- name: 安装 Web 服务器
  include_tasks: "install-{{ ansible_os_family | lower }}.yml"

- name: 配置 Nginx
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: Restart Nginx

- name: 配置站点
  template:
    src: site.conf.j2
    dest: "/etc/nginx/sites-available/{{ app_name }}"
  notify: Reload Nginx

- name: 启用站点
  file:
    src: "/etc/nginx/sites-available/{{ app_name }}"
    dest: "/etc/nginx/sites-enabled/{{ app_name }}"
    state: link
  notify: Reload Nginx

使用 Role 构建 Playbook

---
- name: 部署完整的 Web 应用
  hosts: webservers
  become: yes
  
  roles:
    - role: common
      tags: base
    
    - role: firewall
      vars:
        firewall_allowed_ports:
          - 22
          - 80
          - 443
      tags: security
    
    - role: nginx
      vars:
        nginx_port: 80
        nginx_ssl_port: 443
      tags: webserver
    
    - role: app
      vars:
        app_name: myapp
        app_port: 8080
      tags: deploy
    
    - role: monitoring
      vars:
        node_exporter_port: 9100
      tags: monitoring

Role 最佳实践

总结

Role 是 Ansible 自动化的核心组织方式。通过合理使用 Role,可以实现代码复用、简化维护,并构建复杂的自动化解决方案。