一、 roles简介
- 为了实现playbook重用,可以使用role角色
- 角色role相当于把任务打散,放到不同的目录中。
- 再把一些固定的值,如用户名、软件包、服务等,用变量来表示。
- role角色定义好之后,可以在其他playbook中直接调用
二、 角色集合
roles/
mysql/
nginx/
httpd/
tasks目录:角色需要执行的主任务文件放置在此目录中,默认的主任务文件名为main.yml,当调用角色时,默认会执行main.yml文件中的任务,你也可以将其他需要执行的任务文件通过include的方式包含在tasks/main.yml文件中。
handlers目录:当角色需要调用handlers时,默认会在此目录中的main.yml文件中查找对应的handler
defaults目录:角色会使用到的变量可以写入到此目录中的main.yml文件中,通常,defaults/main.yml文件中的变量都用于设置默认值,以便在你没有设置对应变量值时,变量有默认的值可以使用,定义在defaults/main.yml文件中的变量的优先级是最低的。
vars目录:角色会使用到的变量可以写入到此目录中的main.yml文件中,看到这里你肯定会有疑问,vars/main.yml文件和defaults/main.yml文件的区别在哪里呢?区别就是,defaults/main.yml文件中的变量的优先级是最低的,而vars/main.yml文件中的变量的优先级非常高,如果你只是想提供一个默认的配置,那么你可以把对应的变量定义在defaults/main.yml中,如果你想要确保别人在调用角色时,使用的值就是你指定的值,则可以将变量定义在vars/main.yml中,因为定义在vars/main.yml文件中的变量的优先级非常高,所以其值比较难以覆盖。
meta目录:如果你想要赋予这个角色一些元数据,则可以将元数据写入到meta/main.yml文件中,这些元数据用于描述角色的相关属性,比如 作者信息、角色主要作用等等,你也可以在meta/main.yml文件中定义这个角色依赖于哪些其他角色,或者改变角色的默认调用设定,在之后会有一些实际的示例,此处不用纠结。
templates目录: 角色相关的模板文件可以放置在此目录中,当使用角色相关的模板时,如果没有指定路径,会默认从此目录中查找对应名称的模板文件。
files目录:角色可能会用到的一些其他文件可以放置在此目录中,比如,当你定义nginx角色时,需要配置https,那么相关的证书文件即可放置在此目录中。
三、 角色定制实例
1. 在roles目录下生成对应的目录结构,也可以使用剧本嵌套循环的方式创建
方法一:
# cd /etc/ansible/roles
# mkdir -pv ./{nginx,mysql,httpd}/{files,templates,vars,tasks,handlers,meta,defaults}
# tree
.
├── httpd
│ ├── defaults
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
├── mysql
│ ├── defaults
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
└── nginx
├── defaults
├── files
├── handlers
├── meta
├── tasks
├── templates
└── vars
方法二:
# vim /root/with_fileglob.yaml
---
- hosts: web1
tasks:
- name: mkdir
file:
path: "/etc/ansible/roles/{{item.0}}/{{item.1}}/"
state: directory
with_nested:
- [ nginx,mysql ]
- [ files,templates,vars,tasks,handlers,meta,defaults ]
connection: local
2、定义配置文件(以nginx为例)
tasks
---
- name: install package
yum:
name: "{{ item }}"
state: present
loop: "{{ package }}"
- name: start nginx
service:
name: "{{ item }}"
state: started
loop: "{{ package }}"
- name: copy nginx.conf
template:
src: nginx.conf
dest: /etc/nginx/
notify: restart nginx
- name: copy keepalived
template:
src: keepalived.conf
dest: /etc/keepalived/
notify: restart keepalived
- name: copy check.sh
copy:
src: check.sh
dest: /etc/keepalived/
mode: "0755"
- name:
copy:
content: ansible2
dest: /usr/share/nginx/html/index.html
when: ansible_hostname == "ansible2"
- name:
copy:
content: ansible3
dest: /usr/share/nginx/html/index.html
when: ansible_hostname == "ansible3"
handlers
# vim nginx/handlers/main.yml
---
- name: restart nginx
service:
name: nginx
state: restarted
- name: restart keepalived
service:
name: keepalived
state: restarted
templates
# vim nginx/templates/nginx.conf
http {
...
{% if usepass == "true" %}
upstream ansible_nginx {
server 192.168.100.102:80;
server 192.168.100.100:80;
}
{% endif %}
server {
listen 80 default_server;
server_name _;
include /etc/nginx/default.d/*.conf;
{% if usepass == "false" %}
location / {
root /usr/share/nginx/html;
index index.html;
}
{% endif%}
{% if usepass == "true" %}
location / {
proxy_pass http://ansible_nginx;
}
{% endif %}
}
}
# vim nginx/templates/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id {{ ansible_hostname }}
}
vrrp_script check_nginx {
script "/etc/keepalived/check.sh"
interval 2
}
vrrp_instance VI_1 {
{% if ansible_hostname == "ansible2" %}
state MASTER
interface ens33
priority 100
{% elif ansible_hostname == "ansible3" %}
state BACKUP
interface ens33
priority 80
{% endif %}
virtual_router_id 50
advert_int 1
authentication {
auth_type PASS
auth_pass pass
}
virtual_ipaddress {
192.168.100.99/24
}
track_script {
check_nginx
}
}
vars
# vim nginx/vars/main.yml
---
package: [ nginx , keepalived ]
defaults
# vim nginx/defaults/main.yml
---
usepass: "false"
files
# vim nginx/files/main.yml
# /bin/bash
curl -l localhost &> /dev/null
if [ $? -ne 0 ];then
sysetmctl stop keepalived
fi
roles
第一种:
# vim nginx.yml
---
- hosts: web3
remote_user: root
roles:
- nginx
tasks:
第二种:
需要在meta目录里面添加main.yaml文件添加参数才能重复调用角色,传入不同的变量
meta
# vim nginx/meta/main.yaml
---
allow_duplicates: true
# vim nginx.yml
---
- hosts: web3
roles:
- role: nginx
usepass: "true"
when: ansible_hostname == "ansible2"
- role: nginx
usepass: "false"
when: ansible_hostname == "ansible3"
tasks:
# ansible-playbook nginx.yml
各目录下的文件:
# tree nginx
nginx
├── defaults
│ └── main.yaml
├── files
│ └── check.sh
├── handlers
│ └── main.yaml
├── meta
│ └── main.yaml
├── tasks
│ └── main.yaml
├── templates
│ ├── keepalived.conf
│ └── nginx.conf
└── vars
└── main.yaml
tasks目录里面的main.yaml还可以进行拆分,通过include_tasks模块进行调用
tasks
nginx/tasks/main.yaml
---
- include_tasks: n1.yaml
- include_tasks: n2.yaml
- include_tasks: n3.yaml
nginx/tasks/n1.yaml
---
- name: install
yum:
name: "{{ item }}"
state: present
loop: "{{ package }}"
- name: start
service:
name: "{{ item }}"
state: started
loop: "{{ package }}"
nginx/tasks/n2.yaml
---
- name: nginx.conf
template:
src: nginx.conf
dest: /etc/nginx/
notify: restart nginx
- name: keepalived.conf
template:
src: keepalived.conf
dest: /etc/keepalived/
notify: restart keepalived
- name: copy check.sh
copy:
src: check.sh
dest: /etc/keepalived/
mode: "0755"
nginx/tasks/n3.yaml
- name: index.html
copy:
content: ansible1
dest: /usr/share/nginx/html/index.html
connection: local
- name: index.html
copy:
content: ansible2
dest: /usr/share/nginx/html/index.html
when: ansible_hostname == "ansible2"
- name: index.html
copy:
content: ansible3
dest: /usr/share/nginx/html/index.html
when: ansible_hostname == "ansible3"
各目录下的文件:
nginx
├── defaults
│ └── main.yaml
├── files
│ └── check.sh
├── handlers
│ └── main.yaml
├── meta
│ └── main.yaml
├── tasks
│ ├── main.yaml
│ ├── n1.yaml
│ ├── n2.yaml
│ └── n3.yaml
├── templates
│ ├── keepalived.conf
│ └── nginx.conf
└── vars
└── main.yaml
设置自己的角色搜索目录,编辑/etc/ansible/ansible.cfg配置文件,设置roles_path选项,此项默认是注释掉的,将注释符去掉,当你想要设置多个路径时,多个路径之间用冒号隔开,示例如下:
roles_path = /etc/ansible/roles:/tmp/roles:/roles
除了使用”-e”传入的变量的优先级,其他变量(包括主机变量)的优先级均低于vars/main.yml中变量的优先级。
其实说白了,role角色就是将编写的剧本进行拆分,更加高效有序的管理文件,学到这里,相信大家对Ansible拥有了整体的认识,再接再厉。