角色是ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。运维复杂的场景,建议使用 roles,代码复用度高。
roles:多个角色的集合目录, 可以将多个的role,分别放至roles目录下的独立子目录中,如下所示
roles/
mysql/
nginx/
tomcat/
redis/
默认roles存放路径
/root/.ansible/roles
/usr/share/ansible/roles
/etc/ansible/roles
官方文档
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html
Ansible Roles目录编排
每个角色,以特定的层级目录结构进行组织。
roles的目录结构:
playbook1.yml
playbook2.yml
roles/
project1/
tasks/
files/
vars/
templates/
handlers/
default/
meta/
project2/
tasks/
files/
vars/
templates/
handlers/
default/
meta/
Roles各目录作用:
roles/project/ : 项目名称,有以下子目录
- files/ :存放由copy或script模块等调用的文件
- templates/:template模块查找所需要模板文件的目录
- tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
- handlers/:至少应该包含一个名为main.yml的文件;此目录下的其它的文件需要在此文件中通过include进行包含
- vars/:定义变量,至少应该包含一个名为main.yml的文件;此目录下的其它的变量文件需要在此文件中通过include进行包含
- meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含
- default/:设定默认变量时使用此目录中的main.yml文件,比vars的优先级低
创建 role
创建role的步骤
- 创建role的目录结构。在以roles命名的目录下分别创建以各角色名称命名的目录,如mysql等。在每个角色命名的目录中分别创建相关的目录和文件,比如tasks、files、handlers、templates和vars等目录;用不到的目录可以创建为空目录,也可以不创建。
- 编写和准备role的功能文件。
- 编写playbook文件调用需要的角色应用于指定的主机。
可以利用ansible-galaxy自动创建角色的目录结构
ansible-galaxy init testrole
playbook 调用角色
调用角色方法1:
---
- hosts: webservers
roles:
- mysql
- memcached
- nginx
调用角色方法2:
键role用于指定角色名称,后续的k/v用于传递变量给角色
---
- hosts: webservers
roles:
- role: mysql
username: mysql
- { role: nginx, username: nginx }
调用角色方法3:
还可基于条件测试实现角色调用
---
- hosts: webservers
roles:
- { role: nginx, username: nginx, when: ansible_distribution_major_version == '8' }
范例:
---
- hosts: webservers
roles:
- common
- role: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
tags: typeA
- role: foo_app_instance
vars:
dir: '/opt/b'
app_port: 5001
tags: typeB
范例:
---
- hosts: webservers
roles:
- { role: foo, vars: { message: "first" } }
- { role: foo, vars: { message: "second" } }
实现 nginx 角色
创建角色目录
cd /data/ansible/roles #目录设置仅供参考
ansible-galaxy init nginx
创建task文件
cd nginx
vim tasks/main.yml
vim tasks/group.yml
vim tasks/user.yml
vim tasks/install.yml
vim tasks/service.yml
main.yml
---
# tasks file for nginx
- include: group.yml
- include: user.yml
- include: install.yml
- include: config.yml
- include: service.yml
group.yml
---
- name: create nginx group
group: name=nginx system=yes
user.yml
---
- name: create user group
user:
name: nginx
group: nginx
system: yes
create_home: no
shell: /sbin/nologin
install.yml
---
- name: install nginx
yum: name=nginx state=present
when: ansible_os_family=="RedHat"
- name: install nginx
apt: name=nginx state=present
when: ansible_os_family=="Debian"
config.yml
---
- name: config file
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart
service.yml
---
- name: enable nginx service
service: name=nginx state=started enabled=yes
创建Jinjia2模板文件
vim templates/nginx.conf.j2
nginx.conf.j2
user {{ user }};
worker_processes {{ ansible_processor_vcpus }};
#并发连接数
worker_rlimit_nofile 65536;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 65536;
use epoll;
accept_mutex on;
multi_accept on;
}
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;
#tcp_nopush on;
keepalive_timeout 65;
#隐藏nginx的版本
server_tokens off;
#启用压缩功能
gzip on;
gzip_vary on;
#上传文件大小限制
client_max_body_size 20M;
#缓存打开过的文件信息
open_file_cache max=10000 inactive=60s; #最大缓存10000个文件,非活动数据超时时长60s
open_file_cache_valid 60s; #每间隔60s检查一下缓存数据有效性
open_file_cache_min_uses 5; #60秒内至少被命中访问5次才被标记为活动数据
open_file_cache_errors on; #缓存错误信息
include /etc/nginx/conf.d/*.conf;
}
创建变量文件
vim vars/main.yml
vars/main.yml
---
# vars file for nginx
user: nginx
创建handler
vim handlers/main.yml
handlers/main.yml
---
# handlers file for nginx
- name: restart
service: name=nginx state=restarted
创建playbook调用角色,和roles/在同一级目录下
cd /data/ansible
vim nginxrole.yml
nginxrole.yml
---
- hosts: 149.28.89.198
roles:
- role: nginx
运行playbook
ansible-playbook nginxrole.yml
在浏览器输入目标主机的地址,发现已经部署成功了
用来做实验的云服务器是vultr的VPS,按时计费,做完就可以删机。