前言
角色的作用就是规范化,将一个playbook各部分分门别类的放置在规定好的目录中。就如同linux系统一样,/etc/就是放配置的,/bin 就是放程序的,/tmp 就是放临时文件的 …
ansible 会基于官方规定好的目录结构, 去自动加载目录中的文件. 当一个需求很复杂的时候, 我们就可以基于角色对需求进行分组.
最后, 如果你不按照这个规定来走, 那么ansible角色模块就找不到相关东西.
角色结构
这是一个官方项目的例子
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html# 官方文档
site.yml
webservers.yml
fooservers.yml
roles/
common/
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
defaults/
meta/
例子中,common 和 webservers 就是两个角色
关于角色的目录,必须包含下面列举出来的目录之一,目录可以为空。但是如果你使用到了某个目录,那么部分目录需要包含main.yml文件。
- tasks 角色用到的主要任务列表
- handlers 角色或者角色外用到的任务后续处理
- defaults 角色默认变量
- vars 角色其余变量,优先级大于 defaults 中定义的变量
- files 角色部署中牵扯到的文件
- templates 角色的jinja2模板
- meta 角色的元数据信息,例如角色的属性(作者, 说明, 一些特殊功能等)
最后,目录中main.yml用来存储主配置信息。在这里,你可以包含其它的子任务,在子任务中详细描述。
例如,在 tasks/main.yml 中,通过 import_tasks,包含其它子任务,就像下面这样
main 包含 redhat 和 debian。当系统是 redhat 时,安装 httpd 包,当系统是 debian 时,安装 apache2 包
# roles/xxx/tasks/main.yml
- name: added in 2.4, previously you used 'include'
import_tasks: redhat.yml
when: ansible_facts['os_family']|lower == 'redhat'
- import_tasks: debian.yml
when: ansible_facts['os_family']|lower == 'debian'
# roles/xxx/tasks/redhat.yml
- yum:
name: "httpd"
state: present
# roles/xxx/tasks/debian.yml
- apt:
name: "apache2"
state: present
使用角色
---
# file: site.yml
- include: webservers.yml
- include: fooservers.yml
---
# file: webservers.yml
- hosts: webservers
roles:
- common
- webservers
只运行 webservers 角色,可以通过 site.yml 添加 limit 限制执行,也可以直接调用
ansible-playbook site.yml --limit webservers
ansible-playbook webservers.yml
角色优先级
角色中针对 tasks, handlers, vars 有一个优先级概念. 优先级大的会覆盖掉优先级小的配置.
优先级由大到小如下:
cli 层面参数 > role-xxx-dir > playbook-xxx > role-defaults-dir
这里 cli 层面参数指的是 ansible-playbook -e vara=‘a’ test.play 这种外部传递变量的行为
这里 role-xxx-dir 指的是 role 特定目录里的配置, 例如 tasks, handlers, vars
这里 playbook-xxx 指的是直接写入 ploybook 中的部分
这里 role-defaults-dir 指的是角色目录中的 defaults 默认变量目录
角色复制
如果你想让一个角色多次执行,就如同下面这样
---
- hosts: webservers
roles:
- moo
- moo
有下列两种方式:
- moo,拥有不同的参数
- 将
allow_duplicates: true
写入 moo/meta/main.yml
角色标签
我们一定要针对角色中的tasks添加标签(tags). 原因在于, 有些时候, 当我们只想修改部署很久的一堆机器的某个服务时, 我们只需要在执行角色的 playbook 的时候,追加 --tags 即可帮助我们执行项目中某一个任务,而不必执行所有任务.
比如, 我们有个部署项目, 其中有一个初始化角色( common ). common 中有众多的初始化任务, 其中一个任务是 ntp 服务的 安装/配置/启动/重启 .
ntp 服务配置如下:
---
# file: roles/common/tasks/main.yml
- name: be sure ntp is installed
yum: pkg=ntp state=installed
tags: ntp
- name: be sure ntp is configured
template: src=ntp.conf.j2 dest=/etc/ntp.conf
notify:
- restart ntpd
tags: ntp
- name: be sure ntpd is running and enabled
service: name=ntpd state=running enabled=yes
tags: ntp
---
# file: roles/common/handlers/main.yml
- name: restart ntpd
service: name=ntpd state=restarted
现在, 我们只想修改生产环境的 ntp 服务的配置, 那么只需要将 ntp.conf.j2 模板配置好之后, 重新执行这个playbooks即可. 就想下面这样:
ansible-playbook -i production site.yml --tags ntp