Ansible roles:角色管理
实验环境准备
准备实验环境:
            
            
              bash
              
              
            
          
          [furongwang@controller ~]$ mkdir web && cd web
[furongwang@controller web]$ cat > ansible.cfg <<'EOF'
[defaults]
remote_user = furongwang
inventory = ./inventory
[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False
EOF
[furongwang@controller web]$ cat > inventory <<'EOF'
controller
node1
node2
node3
node4
EOFAnsible 角色介绍
在生产环境中,Playbook 往往会变得冗长复杂,包含多个文件、任务和处理程序。随着开发的 Playbook 越来越多,代码重复利用变得尤为重要。
Ansible 角色提供了一种标准化方式,将任务、变量、文件、模板等资源打包在统一目录结构中,只需简单调用即可在不同项目中复用自动化代码。
Ansible 角色结构
通过以下命令初始化一个角色:
            
            
              bash
              
              
            
          
          [furongwang@controller web]$ ansible-galaxy init furongwang
- furongwang was created successfully
[furongwang@controller web]$ tree furongwang
furongwang
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml
8 directories, 8 files角色目录结构说明
- defaults:包含角色变量的默认值,优先级较低,易于被覆盖
- files:存放由角色任务引用的静态文件
- handlers:包含角色的处理程序定义
- meta:包含角色元信息,如作者、许可证、平台和依赖项
- tasks:包含角色的主要任务定义
- templates:存放由角色任务引用的 Jinja2 模板
- tests:包含测试用的清单和 Playbook
- vars:定义角色变量值,优先级较高
- README.md:提供角色描述、使用文档和示例
Ansible 角色目录位置
Ansible 默认在以下位置查找角色:
- ~/.ansible/roles
- /usr/share/ansible/roles
- /etc/ansible/roles
优先级从上到下依次降低。可以通过 ansible.cfg 中的 roles_path 变量自定义角色路径:
            
            
              ini
              
              
            
          
          [defaults]
roles_path = ./roles多个路径使用冒号分隔:
            
            
              ini
              
              
            
          
          roles_path = /etc/ansible/roles:/home/student/web/roles创建和使用角色
创建角色
            
            
              bash
              
              
            
          
          [furongwang@controller web]$ mkdir roles
[furongwang@controller web]$ ansible-galaxy init apache --init-path=./roles角色任务示例
            
            
              yaml
              
              
            
          
          # tasks/main.yml
---
# tasks file for apache
- name: install web
  yum:
    name: "{{ web_package }}"
    state: latest
- name: "start {{ web_service }}"
  service:
    name: "{{ web_service }}"
    state: started
    enabled: yes
- name: prepare motd
  template:
    src: motd.j2
    dest: /etc/motd
- name: prepare furongwang site
  template:
    src: furongwang.conf.j2
    dest: /etc/httpd/conf.d/furongwang.conf
  notify:
    - restart_web
- name: prepare DocumentRoot 
  file:
    path: "/var/www/html/{{ ansible_hostname }}" 
    state: directory
- name: prepare index.html
  template:
    src: index.html.j2
    dest: "/var/www/html/{{ ansible_hostname }}/index.html"调用角色
            
            
              yaml
              
              
            
          
          ---
- name: deploy apache
  hosts: node1
  roles:
    - apache角色依赖管理
角色可以依赖其他角色,这在构建复杂自动化流程时非常有用:
            
            
              yaml
              
              
            
          
          # roles/apache/meta/main.yml
dependencies:
- role: firewall
  service: http任务执行顺序
Ansible 按照特定顺序执行任务:
- pre_tasks 任务
- roles 任务
- tasks 任务
- post_tasks 任务
处理程序执行顺序更为复杂,涉及不同阶段通知的处理程序。
示例:
            
            
              bash
              
              
            
          
          # 准备环境
[furongwang@controller web]$ ansible-galaxy init test_task_exec_order --init-path=roles
[furongwang@controller web]$ vim roles/test_task_exec_order/tasks/main.yml
            
            
              yaml
              
              
            
          
          ---
# tasks file for test_task_exec_order
- name: task in role
  shell: echo 'task in role'测试剧本内容如下:
            
            
              yaml
              
              
            
          
          ---
- name: test task execute order
  hosts: node1
  gather_facts: false
  
  pre_tasks:
    - name: task in pre_tasks
      shell: echo 'task in pre_tasks'
  
  roles:
    - test_task_exec_order
  
  tasks:
    - name: task in tasks
      shell: echo 'task in tasks'
  post_tasks:
    - name: task in post_tasks
      shell: echo 'task in post_tasks'模拟执行结果:(使用了新目录)

Handlers 执行顺序
play中存在handlers任务,则按以下顺序执行:
- pre_tasks任务
- pre_tasks通知的handlers任务
- roles任务
- tasks 任务
- roles通知的handlers任务
- tasks通知的handlers任务
- post_tasks任务
- post_tasks通知的handlers任务
示例:
            
            
              bash
              
              
            
          
          # 准备环境
[furongwang@controller web]$ vim roles/test_task_exec_order/tasks/main.yml
---
# tasks file for test_task_exec_order
- name: task in role
  shell: echo 'task in role'
  notify:
    - role_handler
    
[furongwang@controller web]$ vim roles/test_task_exec_order/handlers/main.yml
---
# handlers file for test_task_exec_order
- name: role_handler
  shell: echo handle in role测试剧本内容如下:
            
            
              yaml
              
              
            
          
          ---
- name: test task execute order
  hosts: node1
  gather_facts: false
  pre_tasks:
    - name: task in pre_tasks
      shell: echo 'task in pre_tasks'
      notify:
        - iamhandler
  roles:
    - test_task_exec_order
  tasks:
    - name: task in tasks
      shell: echo 'task in tasks'
      notify:
        - iamhandler
  post_tasks:
    - name: task in post_tasks
      shell: echo 'task in post_tasks'
      notify:
        - iamhandler 
  handlers:
    - name: iamhandler
      shell: echo iamhandler执行结果如下:(使用了新目录)

include_role 和 import_role 模块
这两个模块允许在任务级别调用角色:
            
            
              yaml
              
              
            
          
          ---
- hosts: node1
  tasks:    
    - shell: echo 'first task'
    - name: use role in tasks
      import_role:
        name: hello主要区别:
- import_role在 Playbook 执行前解析角色
- include_role在任务执行时解析角色
Ansible 角色优势
- 标准化系统配置的基本要素
- 支持并行开发,提高团队协作效率
- 提高代码重用率,易于共享
- 使大型项目更易于管理
开发角色最佳实践
- 不要在角色中存储敏感信息
- 使用 ansible-galaxy init初始化角色
- 维护完整的 README.md 和 meta/main.yml 文件
- 保持角色功能专注单一
- 经常重用和重构角色
- 使用版本控制系统管理角色
使用系统角色
RHEL 系统提供了预置的系统角色:
            
            
              bash
              
              
            
          
          [furongwang@controller ~]$ sudo yum install -y rhel-system-roles时间同步角色示例
            
            
              yaml
              
              
            
          
          ---
- name: Time Synchronization
  hosts: node1
  vars:
    timesync_ntp_servers:
      - hostname: classroom.example.com   
        iburst: yes
    timezone: "Asia/Shanghai"
  roles:
    - rhel-system-roles.timesync
  tasks:
    - name: Set timezone
      timezone:
        name: "{{ timezone }}"使用 Ansible Galaxy 部署角色
Ansible Galaxy 是一个由社区管理的角色仓库,包含大量可重用的角色。
常用命令
            
            
              bash
              
              
            
          
          # 搜索角色
[furongwang@controller ~]$ ansible-galaxy search --platforms=EL haproxy
# 查看角色信息
[furongwang@controller ~]$ ansible-galaxy info geerlingguy.docker
# 安装角色
[furongwang@controller ~]$ ansible-galaxy install geerlingguy.haproxy
# 批量安装角色
[furongwang@controller ~]$ ansible-galaxy install -r requires.yml
# 查看本地角色清单
[furongwang@controller web]$ ansible-galaxy list
# /home/student/web/roles
- apache, (unknown version)
- firewall, (unknown version)
- test_task_exec_order, (unknown version)
# 角色管理其他命令
# 登入Ansible galaxy
[furongwang@controller ~]$ ansible-galaxy login
# 删除Ansible galaxy中角色
[furongwang@controller ~]$ ansible-galaxy delete
# 删除本地角色
[furongwang@controller ~]$ ansible-galaxy remove
# 或者rm删除相应目录
# 登出Ansible galaxy
[furongwang@controller ~]$ ansible-galaxy logout总结
 Ansible 角色是提升自动化代码复用性和维护性的重要工具。通过标准化目录结构、清晰的变量管理和依赖关系,角色使得复杂自动化任务的开发和维护变得更加高效。结合 Ansible Galaxy 社区资源,可以快速获取经过验证的高质量角色,大幅提升自动化项目开发效率。
 掌握 Ansible 角色管理,不仅能够提高个人工作效率,还能促进团队协作和知识共享,是每个 Ansible 用户必备的重要技能。