roles介绍

角色(roles)是ansible自1.2版本开始引入的新特性,用于层次性,结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单的说,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中、并可以便捷地include他们的一种机制。角色一般用于基于主机构建服务的场景中、但也可以是用于构建守护进程等场景中。

一个项目的目录结构

site.yml
webservers.yml
fooservers.yml
roles/
   common/
     files/
     templates/
     tasks/
     handlers/
     vars/
     defaults/
     meta/
   webservers/
     files/
     templates/
     tasks/
     handlers/
     vars/
     defaults/
     meta/
  • yml文件,用于定义此角色用到的各handler:在handler中使用include包含的其他的handler文件也应该位于此目录中;
  • files目录:存放由copy或script等模块调用的文件;
  • templates目录:templates模块会自动在此目录中寻找Jinja2模板文件;
  • tasks目录:至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表;此文件可以使用include包含其他的位于此目录中的task文件;
  • handlers目录:此目录中应当包含一个main;
  • vars目录:应当包含一个main.yml文件,用于定义此角色用到的变量;
  • meta目录:应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系;ansible 1.3及其以后的版本才支持
  • default目录:为当前角色设定默认变量时使用此目录;应当包含一个main.yml文件;

那么一个playbook就可以这样写

---
 - hosts: webservers
  roles:
     - common
     - webservers

这个 playbook 为一个角色 ‘x’ 指定了如下的行为:

  • 如果 roles/x/tasks/main.yml 存在, 其中列出的 tasks 将被添加到 play 中
  • 如果roles/x/handlers/main.yml 存在, 其中列出的 handlers 将被添加到 play 中
  • 如果roles/x/vars/main.yml 存在, 其中列出的 variables 将被添加到 play 中
  • 如果roles/x/meta/main.yml 存在, 其中列出的 “角色依赖” 将被添加到 roles 列表中 (1.3 andlater)
  • 所有 copy tasks 可以引用 roles/x/files/ 中的文件,不需要指明文件的路径。
  • 所有 scripttasks 可以引用 roles/x/files/ 中的脚本,不需要指明文件的路径。
  • 所有 template tasks 可以引用roles/x/templates/ 中的文件,不需要指明文件的路径。
  • 所有 include tasks 可以引用roles/x/tasks/ 中的文件,不需要指明文件的路径。

如果 roles 目录下有文件不存在,这些文件将被忽略。比如 roles 目录下面缺少了 ‘vars/’ 目录,这也没关系。

注意:你仍然可以在 playbook 中松散地列出 tasks,vars_files 以及 handlers,这种方式仍然可用,但 roles 是一种很好的具有组织性的功能特性,我们强烈建议使用它。如果你在 playbook 中同时使用 roles 和 tasks,vars_files 或者 handlers,roles 将优先执行。

而且,也可以使用参数化的 roles,这种方式通过添加变量来实现,比如:

---

- hosts: webservers
  roles:
    - common
    - { role: foo_app_instance, dir: '/opt/a',  port: 5000 }
    - { role: foo_app_instance, dir: '/opt/b',  port: 5001 }

当一些事情不需要频繁去做时,也可以为 roles 设置触发条件,像这样:

---

- hosts: webservers
  roles:
    - { role: some_role, when: "ansible_os_family == 'RedHat'" }

它的工作方式是:将条件子句应用到 role 中的每一个 task 上。

也可以给role分配指定的标签,比如

---

- hosts: webservers
  roles:
    - { role: foo, tags: ["bar", "baz"] }

如果 play 仍然包含有 ‘tasks’ section,这些 tasks 将在所有 roles 应用完成之后才被执行。

也可定义一些 tasks,让它们在 roles 之前以及之后执行,可以这样做:

---

- hosts: webservers

  pre_tasks:
    - shell: echo 'hello'

  roles:
    - { role: some_role }

  tasks:
    - shell: echo 'still busy'

  post_tasks:
    - shell: echo 'goodbye'

关于ansible的角色介绍基本就这些了,在以后工作学习中再遇到相关问题会继续补充,下边博文将会针对使用角色一键部署静态网站做演示。