10、roles
roles ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。 roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。 要使用roles只需要在playbook中使用include指令即可。 简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中, 并可以便捷地include它们的一种机制。 角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中复杂场景:建议使用roles,代码复用度高 变更指定主机或主机组 如命名不规范维护和传承成本大 某些功能需多个Playbook,通过includes即可实现
10.1、概述
角色(roles):角色集合roles/ mysql/ httpd/ nginx/ memcached/可以互相调用
10.1.1、Ansible Roles目录编排
10.1.2、roles目录结构
每个角色,以特定的层级目录结构进行组织roles目录结构:playbook.yml 调用角色roles/ project/ (角色名称) tasks/ files/ vars/ templates/ handlers/ default/ 不常用 meta/ 不常用
10.1.3、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文件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文件,用于定义此角色的特殊设定及其依赖关系; ansible1.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所有依赖将被正常登入
10.1.4、创建role步骤
创建role的步骤(1) 创建以roles命名的目录(2) 在roles目录中分别创建以各角色名称命名的目录,如webservers等(3) 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录; 用不到的目录可以创建为空目录,也可以不创建(4) 在playbook文件中,调用各角色
10.1.5、针对大型项目使用Roles进行编排
roles目录结构:playbook.ymlroles/ project/ tasks/ files/ vars/ templates/ handlers/ default/ # 不经常用 meta/ # 不经常用示例:nginx-role.ymlroles/└── nginx ├── files │ └── main.yml ├── tasks │ ├── groupadd.yml │ ├── install.yml │ ├── main.yml │ ├── restart.yml │ └── useradd.yml └── vars └── main.yml
10.1.6、目录示例
roles的示例如下所示:site.ymlwebservers.ymldbservers.ymlroles/ common/ files/ templates/ tasks/ handlers/ vars/ meta/ webservers/ files/ templates/ tasks/ handlers/ vars/ meta/
10.2、案例
10.2.1、案例:创建httpd角色
1> 创建roles目录 mkdir roles/{httpd,mysql,redis}/tasks -pv mkdir roles/httpd/{handlers,files}查看目录结构tree roles/ roles/ ├── httpd │ ├── files │ ├── handlers │ └── tasks ├── mysql │ └── tasks └── redis └── tasks2> 创建目标文件 cd roles/httpd/tasks/ touch install.yml config.yml service.yml3> vim install.yml - name: install httpd package yum: name=httpd vim config.yml - name: config file copy: src=httpd.conf dest=/etc/httpd/conf/ backup=yes vim service.yml - name: start service service: name=httpd state=started enabled=yes4> 创建main.yml主控文件,调用以上单独的yml文件, main.yml定义了谁先执行谁后执行的顺序 vim main.yml - include: install.yml - include: config.yml - include: service.yml5> 准备httpd.conf文件,放到httpd单独的文件目录下 cp /app/ansible/flies/httpd.conf ../files/6> 创建一个网页 vim flies/index.html <h1> welcome to weixiaodong home <\h1>7> 创建网页的yml文件 vim tasks/index.yml - name: index.html copy: src=index.html dest=/var/www/html 8> 将网页的yml文件写进mian.yml文件中 vim mian.yml - include: install.yml - include: config.yml - include: index.yml - include: service.yml9> 在handlers目录下创建handler文件mian.yml vim handlers/main.yml - name: restart service httpd service: name=httpd state=restarted10> 创建文件调用httpd角色 cd /app/ansidle/roles vim role_httpd.yml --- # httpd role - hosts: appsrvs remote_user: root roles: #调用角色 - role: httpd 11> 查看目录结构 tree . httpd ├── files │ ├── httpd.conf │ └── index.html ├── handlers │ └── main.yml └── tasks ├── config.yml ├── index.yml ├── install.yml ├── main.yml └── service.yml12> ansible-playbook role_httpd.yml
10.2.2、案例:创建一个nginx角色
建立nginx角色在多台主机上来部署nginx需要安装 创建账号1> 创建nginx角色目录 cd /app/ansible/role mkdir nginx{tesks,templates,hanslers} -pv2> 创建任务目录 cd tasks/ touch insatll.yml config.yml service.yml file.yml user.yml 创建main.yml文件定义任务执行顺序 vim main.yml - include: user.yml - include: insatll.yml - include: config.yml - include: file.yml - include: service.yml3> 准备配置文件(centos7、8) ll /app/ansible/role/nginx/templates/ nginx7.conf.j2 nginx8.conf.j24> 定义任务 vim tasks/install.yml - name: install yum: name=nginx vim tasks/config.yml - name: config file template: src=nginx7.conf.j2 dest=/etc/nginx/nginx.conf when: ansible_distribution_major_version=="7" notify: restrat - name: config file template: src=nginx8.conf.j2 dest=/etc/nginx/nginx.conf when: ansible_distribution_major_version=="8" notify: restrat vim tasks/file.yml 跨角色调用file.yum文件,实现文件复用 - name: index.html copy: src=roles/httpd/files/index.html dest=/usr/share/nginx/html/ vim tasks/service.yml - nmae: start service service: name=nginx state=started enabled=yes vim handlers/main.yml - name: restrat service: name=nginx state=restarted vim roles/role_nginix.yml --- #test rcle - hosts: appsrvs roles: - role: nginx5> 测试安装 ansible-playbook role_nginx.yml
10.2.3、案例: 创建角色memcached
memcacched 当做缓存用,会在内存中开启一块空间充当缓存cat /etc/sysconfig/memcached PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="64" # 缓存空间默认64M OPTIONS=""1> 创建对用目录 cd /app/ansible mkdir roles/memcached/{tasks,templates} -pv2> 拷贝memcached配置文件模板 cp /etc/sysconfig/memcached templates/memcached.j2 vim templates/memcached.j2 CACHESIZE="{{ansible_memtotal_mb//4}}" #物理内存的1/4用做缓存3> 创建对应yml文件,并做相应配置 cd tasks/ touch install.yml config.yml service.yml 创建main.yml文件定义任务执行顺序 vim main.yml - include: install.yml - include: config.yml - include: service.yml vim install.yml - name: install yum: name=memcached vim config.yml - name: config file template: src=memcached.j2 dets=/etc/sysconfig/memcached vim service.yml - name: service service: name=memcached state=started enabled=yes4> 创建调用角色文件 cd /app/ansible/roles/ vim role_memcached.yml --- - hosts: appsrvs roles: - role: memcached5> 安装 ansible-playbook role_memcached.yml memcached端口号11211
10.3、Roles使用
Roles目录编排

Playbook中调用
10.3.1、playbook调用角色
调用角色方法1:- hosts: websrvs remote_user: root roles: - mysql - memcached - nginx调用角色方法2:传递变量给角色- hosts: remote_user: roles: - mysql - { role: nginx, username: nginx } #不同的角色调用不同的变量 键role用于指定角色名称 后续的k/v用于传递变量给角色调用角色方法3:还可基于条件测试实现角色调用roles: - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' }
10.3.2、通过roles传递变量
通过roles传递变量当给一个主机应用角色的时候可以传递变量,然后在角色内使用这些变量示例:- hosts: webservers roles: - common - { role: foo_app_instance, dir: '/web/htdocs/a.com', port: 8080 }
10.3.3、向roles传递参数
而在playbook中,可以这样使用roles:---- hosts: webservers roles: - common - webservers也可以向roles传递参数示例:---- hosts: webservers roles: - common - { role: foo_app_instance, dir: '/opt/a', port: 5000 } - { role: foo_app_instance, dir: '/opt/b', port: 5001 }
10.3.4、条件式地使用roles
甚至也可以条件式地使用roles示例:---- hosts: webservers roles: - { role: some_role, when: "ansible_os_family == 'RedHat'" }
10.3.5、Roles条件及变量等案例
When条件 roles: - {role: nginx, when: "ansible_distribution_major_version == '7' " ,username: nginx }变量调用- hosts: zabbix-proxy sudo: yes roles: - { role: geerlingguy.php-mysql } - { role: dj-wasabi.zabbix-proxy, zabbix_server_host: 192.168.37.167 }
10.3.6、完整的roles架构
// nginx-role.yml 顶层任务调用yml文件---- hosts: testweb remote_user: root roles: - role: nginx - role: httpd 可执行多个rolecat roles/nginx/tasks/main.yml---- include: groupadd.yml- include: useradd.yml- include: install.yml- include: restart.yml- include: filecp.yml// roles/nginx/tasks/groupadd.yml---- name: add group nginx user: name=nginx state=presentcat roles/nginx/tasks/filecp.yml---- name: file copy copy: src=tom.conf dest=/tmp/tom.conf以下文件格式类似:useradd.yml,install.yml,restart.ymlls roles/nginx/files/tom.conf
10.3.7、roles playbook tags使用
roles playbook tags使用 ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml 对标签进行挑选执行// nginx-role.yml---- 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 }
10.4、其它功能
委任 delegate_to交互提示 prompt暂停 wait_forDebug debug: msg="This always executes."IncludeTemplate 多值合并Template 动态变量配置