← 返回首页
🔧

Ansible Role:可复用组件

📂 devops ⏱ 3 min 479 words

Ansible Role:可复用组件

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/
    │   └── ssl.crt           # 静态文件
    ├── meta/
    │   └── main.yml          # 角色元数据
    └── README.md             # 文档

创建Role

# 使用ansible-galaxy创建Role骨架
ansible-galaxy init roles/nginx

# 目录结构
roles/nginx/
├── defaults/
│   └── main.yml
├── files/
├── handlers/
│   └── main.yml
├── meta/
│   └── main.yml
├── tasks/
│   └── main.yml
├── templates/
├── tests/
│   ├── inventory
│   └── test.yml
└── vars/
    └── main.yml

编写Role

defaults/main.yml

# roles/nginx/defaults/main.yml
---
nginx_user: www-data
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_listen_port: 80
nginx_server_name: localhost
nginx_root: /var/www/html
nginx_ssl_enabled: false
nginx_ssl_certificate: ""
nginx_ssl_certificate_key: ""

tasks/main.yml

# roles/nginx/tasks/main.yml
---
- name: 安装nginx
  ansible.builtin.apt:
    name: nginx
    state: present
    update_cache: yes
  when: ansible_os_family == "Debian"

- name: 安装nginx(CentOS)
  ansible.builtin.yum:
    name: nginx
    state: present
  when: ansible_os_family == "RedHat"

- name: 复制nginx配置
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'
    validate: "nginx -t -c %s"
  notify: reload nginx

- name: 复制站点配置
  ansible.builtin.template:
    src: site.conf.j2
    dest: /etc/nginx/conf.d/{{ nginx_server_name }}.conf
  notify: reload nginx

- name: 创建web根目录
  ansible.builtin.file:
    path: {{ nginx_root }}
    state: directory
    owner: {{ nginx_user }}
    group: {{ nginx_user }}
    mode: '0755'

- name: 启动nginx
  ansible.builtin.service:
    name: nginx
    state: started
    enabled: yes

handlers/main.yml

# roles/nginx/handlers/main.yml
---
- name: reload nginx
  ansible.builtin.service:
    name: nginx
    state: reloaded

- name: restart nginx
  ansible.builtin.service:
    name: nginx
    state: restarted

templates/nginx.conf.j2

# roles/nginx/templates/nginx.conf.j2
user {{ nginx_user }};
worker_processes {{ nginx_worker_processes }};
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections {{ nginx_worker_connections }};
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    sendfile on;
    keepalive_timeout 65;

    include /etc/nginx/conf.d/*.conf;
}

meta/main.yml

# roles/nginx/meta/main.yml
---
galaxy_info:
  author: DevOps Engineer
  description: Nginx installation and configuration
  license: MIT
  min_ansible_version: "2.10"
  platforms:
    - name: Ubuntu
      versions:
        - focal
        - jammy
    - name: EL
      versions:
        - '8'
        - '9'
  dependencies: []

使用Role

在Playbook中使用

# site.yml
---
- name: 配置Web服务器
  hosts: webservers
  become: yes
  
  roles:
    - role: common
    - role: nginx
      vars:
        nginx_listen_port: 80
        nginx_server_name: example.com
    - role: app
      vars:
        app_port: 8080

条件应用

- name: 配置服务器
  hosts: all
  become: yes
  
  roles:
    - role: common
    - role: nginx
      when: install_nginx | default(true)
    - role: mysql
      when: "'dbservers' in group_names"

角色依赖

# roles/webapp/meta/main.yml
---
dependencies:
  - role: common
  - role: nginx
    vars:
      nginx_listen_port: 80
  - role: python
    vars:
      python_version: "3.10"

Galaxy角色

# 搜索角色
ansible-galaxy search nginx

# 安装角色
ansible-galaxy install geerlingguy.nginx

# 从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"

实践:完整Web服务器Role

# roles/webserver/tasks/main.yml
---
- name: 安装基础软件包
  ansible.builtin.apt:
    name: "{{ item }}"
    state: present
  loop:
    - nginx
    - python3
    - python3-pip
    - supervisor

- name: 创建应用用户
  ansible.builtin.user:
    name: {{ app_user }}
    system: yes
    shell: /bin/bash
    home: /home/{{ app_user }}

- name: 配置nginx
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: reload nginx

- name: 配置应用
  ansible.builtin.template:
    src: app.conf.j2
    dest: /etc/app/config.yml
  notify: restart app

- name: 启动服务
  ansible.builtin.service:
    name: "{{ item }}"
    state: started
    enabled: yes
  loop:
    - nginx
    - supervisor

常用命令

# 创建Role
ansible-galaxy init roles/myrole

# 列出本地Role
ansible-galaxy list

# 从Galaxy安装
ansible-galaxy install username.rolename

# 从Git安装
ansible-galaxy install git+https://github.com/user/repo.git,main

总结

Role是Ansible实现代码复用和标准化的核心机制。编写良好的Role可以提高自动化代码的可维护性和可移植性。