创建角色
1 创建角色目录结构
1.1 角色创建流程
在Ansible中创建角色不需要特别的开发工具。创建和使用角色包含三个步骤:
- 创建角色目录结构
- 定义角色内容
- 在playbook中使用角色
1.2 角色目录创建说明
默认情况下,Ansible在Ansible Playbook所在目录的roles子目录中查找角色。这样,用户可以利用playbook和其他支持文件存储角色。
如果Ansible无法在该位置找到角色,它会按照顺序在Ansible配置设置roles_path所指定的目录中查找。此变量包含要搜索的目录的冒号分隔列表。此变量的默认值为:
~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
这允许用户将角色安装到由多个项目共享的系统上。例如,用户可能将自己的角色安装在自己的主目录下的~/.ansible/roles子目录中,而系统可能将所有用户的角色安装在/usr/share/ansible/roles目录中。
每个角色具有自己的目录,采用标准化的目录结构。例 :以下目录结构包含了定义motd角色的文件
[root@localhost ~]# tree roles/
roles/
└── motd
├── defaults
│ └── main.yml
├── files
├── handlers
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
└── templates
└── motd.j2
1.3 角色各目录说明
README.md提供人类可读的基本角色描述、有关如何使用该角色的文档和示例,以及其发挥作用所需要满足的任何非Ansible要求。
meta子目录包含一个main.yml文件,该文件指定有关模块的作者、许可证、兼容性和依赖项的信息。
files子目录包含固定内容的文件,而templates子目录则包含使用时可由角色部署的模板。
其他子目录中可以包含main.yml文件,它们定义默认的变量值、处理程序、任务、角色元数据或变量,具体取决于所处的子目录。
如果某一子目录存在但为空,如本例中的handlers,它将被忽略。如果某一角色不使用功能,则其子目录可以完全省略
2 创建角色框架
可以使用标准Linux命令创建新角色所需的所有子目录和文件。此外,也可以通过命令行实用程序来自动执行新角色创建过程。
ansible-galaxy命令行工具可用于管理Ansible角色,包括新角色的创建。用户可以运行ansible-galaxy init (init:初始化) 来创建新角色的目录结构。指定角色的名称作为命令的参数,该命令在当前工作目录中为新角色创建子目录。
实例:创建一个httpd角色
[root@ansible playbook]# ansible-galaxy init httpd
- Role httpd was created successfully
[root@ansible playbook]# ls
httpd playbook.yml
[root@ansible playbook]# tree httpd/
httpd/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
3 定义角色内容
3.1 创建角色内容及使用方式
实例
[root@ansible httpd]# tree
.
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
│ └── httpd.conf.j2
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
[root@ansible httpd]# cat tasks/main.yml
---
# tasks file for httpd
- name: install httpd
yum:
name: httpd
state: present
- name: config
template:
src: templates/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
notify: restart httpd
- name: service
service:
name: httpd
state: started
enabled: yes
[root@ansible httpd]# cat handlers/main.yml
---
# handlers file for httpd
- name: restart httpd
service:
name: httpd
state: restarted
[root@ansible httpd]# cat defaults/main.yml
---
# defaults file for httpd
PORT: 80
//在playbook中使用角色
[root@ansible playbook]# cat play.yml
---
- hosts: apache
roles:
- httpd
[root@ansible playbook]# ansible-playbook play.yml
PLAY [apache] ******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.136.225]
TASK [install httpd] ***********************************************************
ok: [192.168.136.225]
TASK [httpd : config] *********************************************************
4 角色内容开发
角色允许以模块化方式编写playbook。为了最大限度地提高新开发角色的效率,请考虑在角色开发中采用以下推荐做法:
-
在角色自己的版本控制存储库中维护每个角色。Ansible很适合使用基于git的存储库。
-
角色存储库中不应存储敏感信息,如密码或SSH密钥。敏感值应以变量的形式进行参数化,其默认值应不敏感。使用角色的playbook负责通过Ansible Vault变量文件、环境变量或其他ansible-playbook选项定义敏感变量。
-
使用ansible-galaxy init启动角色,然后删除不需要的任何目录和文件。
-
创建并维护README.md和meta/main.yml文件,以记录用户的角色的用途、作者和用法。
-
让角色侧重于特定的用途或功能。可以编写多个角色,而不是让一个角色承担许多任务。
-
经常重用和重构角色。避免为边缘配置创建新的角色。如果现有角色能够完成大部分的所需配置,请重构现有角色以集成新的配置方案。使用集成和回归测试技术来确保角色提供所需的新功能,并且不对现有的playbook造成问题。
编写良好的角色利用默认变量来改变角色行为,使之与相关的配置场景相符。这有助于让角色变得更为通用,可在各种不同的上下文中重复利用。
如果通过以下方式定义了相同的变量,则角色的defaults目录中定义的变量的值将被覆盖:
在清单文件中定义,作为主机变量或组变量
在playbook项目的group_vars或host_vars目录下的YAML文件中定义
作为变量嵌套在play的vars关键字中定义
在play的roles关键字中包含该角色时作为变量定义
将motd角色与system_owner角色变量的不同值搭配使用。角色应用到受管主机时,指定的值someone@host.example.com将取代变量引用
[root@localhost ~]# cat use-motd-role.yml
---
- name: use motd role playbook
hosts: remote.example.com
remote_user: devops
become: true
vars:
system_owner: someone@host.example.com
roles:
- role: motd
以这种方式定义时,system_owner变量将替换同一名称的默认变量的值。嵌套在vars关键字内的任何变量定义不会替换在角色的vars目录中定义的同一变量的值
将motd角色与system_owner角色变量的不同值搭配使用。指定的值someone@host.example.com将替换变量引用,不论是在角色的vars还是defaults目录中定义
[root@localhost ~]# cat use-motd-role.yml
---
- name: use motd role playbook
hosts: remote.example.com
remote_user: devops
become: true
roles:
- role: motd
system_owner: someone@host.example.com
几乎任何其他变量都会覆盖角色的默认变量,如清单变量、playvars变量,以及内嵌的角色参数等。
较少的变量可以覆盖角色的vars目录中定义的变量。事实、通过include_vars加载的变量、注册的变量和角色参数是其中一些具备这种能力的变量。清单变量和playvars无此能力。这非常重要,因为它有助于避免用户的play意外改变角色的内部功能。
作为角色参数内嵌声明的变量具有非常高的优先级。它们可以覆盖角色的vars目录中定义的变量。如果某一角色参数的名称与playvars或角色vars中设置的变量或者清单变量或playbook变量的名称相同,该角色参数将覆盖另一个变量。