介绍

  • roles

    ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles 能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、 文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中

  • 复杂场景:建议使用roles,代码复用度高

    • 变更指定主机或主机组
    • 如命名不规范维护和传承成本大
    • 某些功能需多个Playbook,通过includes即可实现

目录

编排

image-20200504211825178

结构

  • 每个角色,以特定的层级目录结构进行组织

  • roles目录结构:

    playbook.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    roles/
    project/
    tasks/
    files/
    vars/
    templates/
    handlers/
    default/ 不常用
    meta/ 不常用

    作用

  • roles/appname 目录结构

    • tasks目录:至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表;此文件可以使用include包含其它的位于此目录中的task文件
    • files目录:存放由copy或script等模块调用的文件;
    • templates目录:template模块会自动在此目录中寻找Jinja2模板文件
    • handlers目录:此目录中应当包含一个main.yml文件,用于定义此角色用到的各handler;在 handler中使用include包含的其它的handler文件也应该位于此目录中;
    • vars目录:应当包含一个main.yml文件,用于定义此角色用到的变量;
    • meta目录:应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系;ansible 1.3及其以后的版本才支持;
    • default目录:为当前角色设定默认变量时使用此目录;应当包含一个main.yml文件
  • roles/example_role/files/ 所有文件,都将可存放在这里

  • roles/example_role/templates/ 所有模板都存放在这里

  • roles/example_role/tasks/main.yml:主函数,包括在其中的所有任务将被执行

  • roles/example_role/handlers/main.yml:所有包括其中的 handlers 将被执行

  • roles/example_role/vars/main.yml:所有包括在其中的变量将在roles中生效

  • roles/example_role/meta/main.yml:roles所有依赖将被正常登入

创建

  1. 创建以roles命名的目录
  2. 在roles目录中分别创建以各角色名称命名的目录,如webservers等
  3. 在每个角色命名的目录中分别创建files、handlers、meta、tasks、 templates和vars目录;用不到的目录可以创建为空目录,也可以不创建
  4. 在playbook文件中,调用各角色

示例

image-20200504213200695

image-20200504213243943

相关使用

playbook中调用角色

方法1

1
2
3
4
5
6
- hosts: websrvs 
remote_user: root
roles:
- mysql
- memcached
- nginx

方法2: 传递变量给角色

1
2
3
4
5
- hosts: 
remote_user:
roles:
- mysql
-{ role: nginx, username: nginx }

键role用于指定角色名称

后续的k/v用于传递变量给角色


**方法3:还可基于条件测试实现角色调用 **

1
2
roles:
-{ role: nginx, username: nginx, when: ansible_distribution_major_version == ‘7’ }

以下介绍

通过roles传递变量

当给一个主机应用角色的时候可以传递变量,然后在角色内使用这些变量

示例:

1
2
3
4
- hosts: webservers 
roles:
- common
- { role: foo_app_instance, dir: '/web/htdocs/a.com', port: 8080 }

向roles传递参数

  • 而在playbook中,可以这样使用roles:

    1
    2
    3
    4
    hosts: webservers
    roles:
    - common
    - webservers
  • 也可以向roles传递参数

    示例:

    1
    2
    3
    4
    5
    hosts: webservers 
    roles:
    - common
    - { role: foo_app_instance, dir: '/opt/a', port: 5000 }
    - { role: foo_app_instance, dir: '/opt/b', port: 5001 }

    条件式地使用roles

  • 甚至也可以条件式地使用roles

    示例:

    1
    2
    3
    hosts: webservers 
    roles:
    - { role: some_role, when: "ansible_os_family == 'RedHat'" }

    Roles条件及变量等案例

  • When条件

    1
    2
    roles:
    - {role: nginx, when: "ansible_distribution_major_version == '7' " ,username: nginx}
  • 变量调用

    1
    2
    3
    4
    5
    hosts: zabbix
    proxy sudo: yes
    roles:
    - { role: geerlingguy.php-mysql }
    - { role: dj-wasabi.zabbix-proxy, zabbix_server_host: 192.168.37.167 }

    完整的roles结构

image-20200504215010141

roles playbook tags使用

ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml

1
2
3
4
5
6
7
8
9
10
hosts: testweb  
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: marridb ,tags: [ 'mysql', 'db' ] }
- { role: php }

ansible-playbook --tags='nginx,httpd,mysql' nginx-role.yaml

实战案例

案例1:实现Httpd角色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
mkdir -pv /data/ansib1e/roles/httpd/{tasks ,handlers,files}
#创建角色相关的文件
cd /data/ansible/roles/httpd/

vim tasks/main.yml
- include: install.yml
- include: config.yml
- include: index.yml
- include: service.yml

vim tasks/install.yml
- name: install httpd package
yum: name=httpd

vim tasks/config.yml
- name: config file
copy: src=httpd.conf dest=/etc/httpd/conf/ backup=yes
notify: restart

vim tasks/index.yml
- name: index.html
copy: src=index.html dest=/var/www/html/

vim tasks/service.yml
- name: start service
service: name=httpd state=started enabled=yes

vim handlers/main.yml
- name: restart
service: name=httpd state=restarted

#在playbook中调用角色
vim /data/ansible/role_httpd.yml
# httpd role
- hosts: appsrvs
remote_user: root
roles:
- httpd
#运行playbook
ansible-playbook /data/ansib1e/role_httpd.yml

案例2:实现Nginx角色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
mkdir -pv /data/ansib1e/roles/nginx/ {tasks,handlers,templates ,vars}
#创建task文件
cd /data/ansib1e/ro1es/nginx/
vim tasks/main.yml
- include: install.yml
- include: config.yml
- include: file.yml
- include: service.yml
vim tasks/install.yml
- name: install
yum: name=nginx state=present
vim tasks/config.yml
- name: config file for centos7
template: src=nginx7.conf.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution major.version=="7"
notify: restart
- name: config file for centos8
template: src=nginx8.conf.j2 dest=/etc/nginx/nginx. conf
when: ansib1e_distribution major_ version=="8"
notify: restart
vim tasks/file.yml
- name : index.html
copy: src=roles/httpd/files/index.html dest=/usr/share/nginx/html/
vim tasks/service.yml
- name: start service
service: name=nginx state=started enabled=yes
#创建handler文件
cat handlers/main.yml
- name: restart
service: name=nginx state=restarted
#创建两个template文件
cat templates/nginx7.conf.j2
user {{user}};
worker_processes {{ansib1e_processor.vcpus**2}}; #修改此行
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
省略...
cat templates/nginx8.conf.j2
...省略...
user nginx;
worker_processes {{ansib1e_processor_vcpus+2}}; #修改此行
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
省略...

#创建变量文件
vim vars/main.yml
user : daemon

案例3:实现多角色的选择

1
2
3
4
5
6
7
8
vim /data/ansib1e/role_httpd_nginx.yml
---
- hosts: appsrvs
roles:
- {role: httpd,tags: [httpd ,web], when: ansib1e_distribution_major__version=="7" }
- {role: nginx, tags: [nginx,web], when: ansible_ distribution_major__version=="8" }

ansible-playbook -t nginx /data/ansib1e/role__httpd__nginx.yml

推荐资料