Roles of Ansible

Roles are a new feature introduced by Ansible since version 1.2, used to organize playbooks hierarchically and structured. Roles can automatically load variable files, tasks, and handlers according to the hierarchical structure. To use roles, you only need to use the include directive in the playbook.
Simply put, roles are a mechanism by which variables, files, tasks, templates, and processors are placed in separate directories, and they can be included conveniently. Roles are generally used in scenarios where services are built based on the host, but they can also be used in scenarios where operation and maintenance are complex in scenarios such as building daemons: roles are recommended for high code reuse.

Official documents:

https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html

roles: a collection directory of multiple roles. Multiple roles can be placed in independent subdirectories under the roles directory, as shown in the following example

roles/
   nginx/
   tomcat/
   mysql/
   redis/

Default roles storage path

/root/.ansible/roles
/usr/share/ansible/roles
/etc/ansible/roles

Ansible Roles catalog organization

Each role is organized in a specific hierarchical directory structure (here only Nginx is used as an example, others can also follow this idea)

Directory structure of roles:

playbook1.yml
playbook2.yml
  roles/
    project1/
       tasks/
       files/
       vars/
       templates/
       handlers/
       default/
       meta/
    project2/
       tasks/
       files/
       vars/
       templates/
       handlers/
       default/
        meta/

Roles of each directory

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的优先级低

Create role

Steps to create a role

1 创建role的目录结构.在以roles命名的目录下分别创建以各角色名称命名的目录,如mysql等,在每个角色命名的目录中分别创建相关的目录和文件,比如tasks、files、handlers、templates和vars等目录;用不到的目录可以创建为空目录,也可以不创建
2 编写和准备role的功能文件
3 编写playbook文件调用需要的角色应用于指定的主机

Use Roles for orchestration for large projects

playbook call role

Call role method 1:

---
- hosts: websrvs
  remote_user: root
  roles:
    - mysql
    - memcached
    - nginx

Call role method 2:

The key role is used to specify the role name, and the subsequent k/v is used to pass variables to the role

---
- hosts: all
  remote_user: root
  roles:
    - role: mysql
      username: mysql
    - { role: nginx, username: nginx }

Call role method 3:

Role invocation can also be implemented based on conditional testing

---
- hosts: all
  remote_user: root
  roles:
    - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' }

example:

---
- hosts: webservers
  roles:
    - { role: foo, vars: { message: "first" } }
    - { role: foo, vars: { message: "second" } }

Use of tags in roles

[[email protected] ~]# vi app-role.yml
---
#可以有多个play
- hosts: dbserver
  roles:
    - role: haproxy
    - role: keepalived
- hosts: appsrvs
  remote_user: root
  roles:
    - { role: nginx ,tags: [ 'nginx', 'web' ] ,when: ansible_distribution_major_version == "6" }
    - { role: httpd ,tags: [ 'httpd', 'web' ] }
    - { role: mysql ,tags: [ 'mysql', 'db' ] }
    - role: mariadb
      tags:
        - mariadb
        - db
  tags: app   #play的tag

[[email protected] ~]# ansible-playbook --tags="nginx,mysql" app-role.yml

Case: The directory structure of nginx_roles is as follows

[[email protected] /etc/ansible]# mkdir roles/nginx/{files,tasks,vars,handlers,templates} -pv
mkdir: created directory 'roles/nginx'
mkdir: created directory 'roles/nginx/files'
mkdir: created directory 'roles/nginx/tasks'
mkdir: created directory 'roles/nginx/vars'
mkdir: created directory 'roles/nginx/handlers'
mkdir: created directory 'roles/nginx/templates'

[[email protected] /etc/ansible]# tree roles/
roles/
└── nginx
    ├── defualt
    ├── files
    ├── handlers
    ├── tasks
    ├── templates
    └── vars

7 directories, 0 files

Prepare the working directory (the file name cannot be wrong, there is no way to execute it if it is wrong)

[[email protected] /etc/ansible]# cat roles/nginx/tasks/main.yml   ##必须是main.yml
- include: group.yml
- include: user.yml
- include: install.yml
- include: index.yml
- include: config.yml
- include: service.yml

[[email protected] /etc/ansible]# vim roles/nginx/tasks/group.yml
- name: create nginx group
  group: name=nginx system=yes gid=80

[[email protected] /etc/ansible]# vim roles/nginx/tasks/user.yml
- name: create nginx user
  user: name=nginx system=yes shell=/sbin/nologin uid=80 group=nginx

[[email protected] /etc/ansible]# vim roles/nginx/tasks/install.yml
- name: install nginx package
  yum: name=nginx state=present

[[email protected] /etc/ansible]# vim roles/nginx/tasks/config.yml
- name: nginx config file
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
  notify: restart nginx

[[email protected] /etc/ansible]# vim roles/nginx/tasks/service.yml
- name: service nginx start
  service: name=nginx state=started enabled=yes

[[email protected] /etc/ansible]# vim roles/nginx/tasks/index.yml
- name: data index.html
  copy: src=files/index.html dest=/usr/share/nginx/html/

[[email protected] /etc/ansible]# vim roles/nginx/handlers/main.yml
- name: restart nginx
  service: name=nginx state=restarted

[[email protected] /etc/ansible]# vim roles/nginx/vars/main.yml
user_name: nginx

Custom page:

[[email protected] /etc/ansible]# vim roles/nginx/files/index.html
<h1>web nginx N520</h>

Variable definitions:

[[email protected] /etc/ansible]# vim roles/nginx/vars/main.yml
user_name: nginx

Example: The template is changed to the following two places to verify

[[email protected] /etc/ansible]# vim roles/nginx/templates/nginx.conf.j2
# 自定义变量调用
user {{ user_name }};
# ansible自带变量调用
worker_processes {{ ansible_processor_vcpus*2 }};

The completed roles structure is as follows:

[23:06:14 [email protected] /etc/ansible]# tree roles/
roles/
└── nginx
    ├── files
    │   └── index.html
    ├── handlers
    │   └── main.yml
    ├── tasks
    │   ├── config.yml
    │   ├── data.yml
    │   ├── group.yml
    │   ├── install.yml
    │   ├── main.yml
    │   ├── service.yml
    │   └── user.yml
    ├── templates
    │   └── nginx.conf.j2
    └── vars
        └── main.yml

6 directories, 11 files

Make a playbook file at the same level as roles

[[email protected] /etc/ansible]# vim nginx_install.yml
- hosts: websrvs
  remote_user: root
  roles:
    - nginx

carried out

[[email protected] /etc/ansible]# ansible-playbook nginx_install.yml

The results are as follows:

[[email protected] /etc/ansible]# curl 172.31.0.38
<h1>web nginx N520</h>
[[email protected] /etc/ansible]# curl 172.31.0.48
<h1>web nginx N520</h>

Check whether the defined variables are working (CPU 2 core)

# 这是ansible远程安装修改的配置文件
[[email protected] ~]# cat /etc/nginx/nginx.conf
user nginx;
worker_processes 4;

[[email protected] ~]# ps -ef | grep nginx
root       8810      1  0 00:10 ?        00:00:00 nginx: master process /usr/sbin/nginx
nginx      8811   8810  0 00:10 ?        00:00:00 nginx: worker process
nginx      8812   8810  0 00:10 ?        00:00:00 nginx: worker process
nginx      8813   8810  0 00:10 ?        00:00:00 nginx: worker process
nginx      8814   8810  0 00:10 ?        00:00:00 nginx: worker process
root       8834   1412  0 00:12 pts/0    00:00:00 grep --color=auto nginx

# 这个是yum安装的默认配置文件
[[email protected] ~]# cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;

[[email protected] ~]# ps -ef | grep nginx
root      48254      1  0 00:13 ?        00:00:00 nginx: master process /usr/sbin/nginx
nginx     48255  48254  0 00:13 ?        00:00:00 nginx: worker process
nginx     48256  48254  0 00:13 ?        00:00:00 nginx: worker process
root      48259   1162  0 00:14 pts/0    00:00:00 grep --color=auto nginx

Error:

Unknown variable parameter

TASK [nginx config file] ***********************************************************************
fatal: [172.31.0.38]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'ansible_processes_vcpus' is undefined"}
fatal: [172.31.0.48]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'ansible_processes_vcpus' is undefined"}

Solution: The variable ansible_processes_vcpus is wrong, change it to the correct one: ansible_processor_vcpus, you can