Roles角色文章目录Roles角色概述目录介绍一、Ansible-galaxy角色管理工具Ansible-galaxy简介获取Ansible-Galaxy帮助ansible-galaxy命令二、roles编写步骤1、编写roles 的步骤为2、roles的调用3、roles中使用变量4、多次调用同一个roles5、roles管理模板文件6、roles管理handlers文件7、roles 的依赖关系8、roles 的相互调用三、项目示例1、创建httpd服务的roles角色2、创建nginx服务的roles3、如果想触发 notify和handlers 这个角色可以修改配置文件4、实现条件判断5、使用标签实现playbook角色的调用四、总结概述​ 角色roles是ansible自1.2版本开始引入的新特性用于层次性结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单的说roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中、并可以便捷地include他们的一种机制。角色一般用于基于主机构建服务的场景中、但也可以是用于构建守护进程等场景中。目录介绍目录作用tasks目录角色需要执行的主任务文件放置在此目录中默认的主任务文件名为main.yml当调用角色时默认会执行main.yml文件中的任务你也可以将其他需要执行的任务文件通过include的方式包含在tasks/main.yml文件中。handlers目录当角色需要调用handlers时默认会在此目录中的main.yml文件中查找对应的handlerdefaults目录角色会使用到的变量可以写入到此目录中的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那么相关的证书文件即可放置在此目录中。一、Ansible-galaxy角色管理工具Ansible-galaxy简介Ansible Galaxy 是一个Ansible内容公共资源库这些内容由许许多多Ansible管理员和用户编写。它包含数千个Ansible角色具有可搜索的数据库可帮助Ansible用户确定或许有助于他们完成管理任务的角色。Ansible Galaxy含有面向新的Ansible用户和角色开发人员的文档和视频链接。获取Ansible-Galaxy帮助通过Ansible Galaxy网站主页上的Documenttaion标签可以进入描述如何使用Ansible Galaxy的页面。其中包含了介绍如何从Ansible Galaxy下载和使用角色的内容。该页面也提供关于如何开发角色并上传到Ansible Galaxy的说明。通过Ansible Galaxy网站主页上的Documenttaion标签可以进入描述如何使用Ansible Galaxy的页面。其中包含了介绍如何从Ansible Galaxy下载和使用角色的内容。该页面也提供关于如何开发角色并上传到Ansible Galaxy的说明。https://galaxy.ansible.com/homeansible-galaxy命令语法ansible-galaxy[选项]命令选项选项(不能用)作用-p 或 --roles-path指定角色安装的路径。-r 或 --role-repo指定角色仓库的 URL。-f 或 --force强制重新安装角色。-t 或 --skip-install跳过角色安装只下载角色文件。 -c 或 --collections-path–ignore-errors在安装过程中忽略错误。–debug启用调试输出。–module-name为 import-playbook 命令指定模块名称。–role-name为 import-playbook 命令指定角色名称。命令命令作用install安装角色。list列出已安装的角色。remove删除已安装的角色。import导入角色。init初始化一个新角色。update更新已安装的角色。import-playbook从角色导入 Playbook。search搜索角色info显示角色信息二、roles编写步骤1、编写roles 的步骤为创建roles的项目目录。编写roles的功能也就是tasks最后playbook引用roles编写好的tasks示例#1、先创建roles_test 项目目录结构并创建下面的子目录最基本的子目录需要有tasks目录。[rootansible ansible]# cd roles/[rootansible roles]# mkdir roles_test[rootansible roles]# cd roles_test/[rootansible roles_test]# mkdir tasks[rootansible roles_test]# cd tasks/[rootansible tasks]# pwd/etc/ansible/roles/roles_test/tasks#2、然后在tasks中编写相关的任务在tasks中必须有一个 main.yaml 文件。可以把编写的任务直接写到 main.yaml 文件中也可以写到其他文件中然后在main.yaml中通过 include 的方式引用这些文件。在 tasks 中 不需要写 play 部分只写tasks部分就行。[rootansible tasks]# vim main.yaml- name:testroles debug: msg:this is test roles#------或者----[rootansible tasks]# vim test.yaml- name:testroles debug: msg:this is test roles[rootansible tasks]# vim main.yaml- include: test.yaml#3、写好之后 编写playbook调用rolesplaybook剧本必须要与roles角色在同一目录[rootansible ansible]# vim roletest.yaml--- - hosts: web remote_user: root roles: - role: roles_test#4、测试[rootansible ansible]# ansible-playbook roletest.yamlok:[192.168.115.112]{msg:this is test roles}2、roles的调用在playbook调用roles时如何找到roles所在的目录呢有以下几种方式1、playbook文件会在同级目录中寻找与调用的角色同名的roles例如在上例中roletest.yaml这个playbook文件调用了roles_test这个角色会自动在同级目录中寻找roles_test这个目录并执行其中的tasks。[rootansible roles]# ll总用量2drwxr-xr-x3root root198月909:25 roles_test -rw-r--r--1root root688月910:08 roletest.yaml2、playbook文件也会寻找同级目录中的roles 目录执行roles目录中同名的角色项目[rootansible ansible]# tree├── roles │ └── roles_test │ └── tasks │ ├── main.yaml │ └── test.yaml ├── roletest.yaml3、也可以修改ansible配置文件中定义的roles的路径多个路径之间使用冒号 隔开roles_path/etc/ansible/roles:/data/ansible/roles:/opt4、在playbook文件中直接写roles的绝对路径也可以调用[rootansible ansible]# vim roletest.yaml--- - hosts: web remote_user: root roles: - role: /etc/ansible/roles/roles_test3、roles中使用变量修改roles文件引入变量#1、[rootansible ansible]# vim roles/roles_test/tasks/test.yaml- name:testroles debug: msg:{{ var }}#2、在调用这个角色时则需要传入对应的变量否则就会报错调用上例角色的示例如下[rootansible ansible]# vim roletest.yaml--- - hosts: web remote_user: root roles: - role: roles_test vars: - var:testvars#######[rootansible ansible]# ansible-playbook roletest.yamlok:[192.168.115.112]{msg:test vars}#-----或者---- 变量定义在vars文件中#3、也可以为变量设置默认值这样即使在调用角色时没有传入任何参数也有默认的值可以使用同时也不会在调用时因为没有传入对应变量而报错需要在roles_test目录中创建一个defaults目录/vars 目录并且创建defaults/main.yml文件/vars/main.yaml文件文件内容如下[rootansible roles_test]# mkdir vars[rootansible roles_test]# cd vars/[rootansible vars]# vim main.yamlvar:testabc#4、然后在运行playbook结果一样[rootansible ansible]# ansible-playbook roletest.yamlok:[192.168.115.112]{msg:test abc}#结论变量的优先级#ansible-playbook vars/main.yaml 其他变量定义的方式4、多次调用同一个roles默认情况下我们无法多次调用同一个角色也就是说如下playbook只会调用一测role角色[rootansible ansible]# cat roletest.yaml--- - hosts: web remote_user: root roles: - role: roles_test - role: roles_test#执行上边的playbook会发现roles_test 的debug 模块只输出了一次如果想多次调用同一个角色有两种方法#1、设置角色的 allow_duplicates 属性让其支持重复使用[rootansible roles_test]# mkdir meta[rootansible ansible]# cat roles/roles_test/meta/main.yamlallow_duplicates:true#2、调用角色时传入不同的参数#先把vars 文件中的main.yaml 定义的变量注释掉#然后在playbook中添加变量roles: - role: roles_test vars: var:123- role: roles_test vars: var:testvars[rootansible ansible]# ansible-playbook roletest.yamlTASK[roles_test:testroles]******************************************************************* ok:[192.168.115.112]{msg:123}TASK[roles_test:testroles]********************************************************************** ok:[192.168.115.112]{msg:test vars}5、roles管理模板文件前文中提到roles中把所有的模板文件放置到templates 目录中我么来测试下#1、新增template 目录建立模板文件[rootansible roles_test]# mkdir templates[rootansible templates]# vim temp.j2somethingintemplate;{{template_var}}#2、tasks/main.yaml 如下- name:testroles debug: msg:{{ var }}- name: copy template template: src: temp.j2 dest: /tmp/temp#3、变量文件如下var:testabc template_var: tempvar#4、playbook文件如下--- - hosts: web remote_user: root roles: - role: roles_test[rootansible ansible]# ansible-playbook roletest.yamlTASK[roles_test:testroles]************************************************************************** ok:[192.168.115.112]{msg:test abc}TASK[roles_test:copy template]*********************************************************************** changed:[192.168.115.112]6、roles管理handlers文件如果想要在角色中使用一些handlers 以便进行触发则可以直接将对应的handlers 任务写到 handlers/main.yaml文件中#1、创建handlers 目录[rootansible roles_test]# mkdir handlers[rootansible handlers]# vim main.yaml- name: test_handlers debug: msg:this is a test handler#2、编辑tasks任务[rootansible tasks]# vim main.yaml- name:testroles debug: msg:{{ var }}changed_when:truenotify: test_handlers#3、把之前测试template 的变量注释掉#4、运行playbook文件[rootansible ansible]# ansible-playbook -C roletest.yamlTASK[roles_test:testroles]******************************************************************************* changed:[192.168.115.112]{msg:test abc}RUNNING HANDLER[roles_test:test_handlers]******************************************************************************** ok:[192.168.115.112]{msg:this is a test handler}7、roles 的依赖关系roles 允许在使用时自动引入其他rolesrole 依赖关系存储在meta/main.yaml文件中示例#安装WordPress 项目时#1、需要先确保 nginx 与 php-fpm的role 都能正常运行#2、然后在WordPress的role中定义依赖关系#3、依赖的role 有nginx 以及 php-fpm#4、 在WordPress的role中新建meta 目录编写main.yaml文件[rootansible meta]# vim main.yamldependencies: -{role: nginx}-{role: php-fpm}#5、在WordPress的playbook中就不需要在安装 nginx 和php-fpm了只写一个 WordPress就可以了安装WordPress之前会自动先部署 nginx和php-fpm[rootansible ansible]# vim roletest.yaml--- - hosts: web remote_user: root roles: - role: WordPress8、roles 的相互调用roles 中的各项目之间的文件是可以跨项目相互调用的。跨项目调用时需要指明要调用的role的名称。示例#要同时部署nginx 和apache 两个项目这俩项目使用了相同的index.html主页文件这个主页文件已经在nginx项目中定义过了若此时需要在Apache项目中引用使用如下方式[rootlocalhost /data/roles]$vimapache/tasks/html.yml#页面配置- name: Copy Index File copy: srcroles/nginx/files/index.html#跨项目调用路径要写roles的名称dest /var/www/nginx/html/三、项目示例1、创建httpd服务的roles角色#1、创建项目目录httpd[rootansible roles]# mkdir httpd#2、创建roles相关目录[rootansible httpd]# mkdir tasks files vars[rootansible httpd]# cd tasks/#3、创建用户组[rootansible tasks]# vim group.yaml- name: create group group: name: apache state: present system:yesgid:80#4、创建用户[rootansible tasks]# vim user.yaml- name: create user user: name: apache group: apache state: present uid:80system:yesshell: /sbin/nologin home: /usr/share/httpd#5、安装httpd包[rootansible tasks]# vim install.yaml- name: yum httpd yum: name: httpd state: installed#6、在files目录下创建配置文件 httpd.conf文件。将httpd.conf配置文件的端口修改为9527:[rootansible files]# vim httpd.confListen9527#7、创建一个网页文件用于验证当前信息[rootansible files]# vim index.htmlh1welcome to beijing!/h1#8、将创建的配置文件复制到被管理端主机上[rootansible tasks]# vim copy.yaml- name: copyfilecopy: src: httpd.conf dest: /etc/httpd/conf backup:yes#9、将创建的index.html数据复制到/var/www/html目录下相当于是给页面准备一个文件[rootansible tasks]# vim data.yaml- name: copy datafilecopy: src: index.html dest: /var/www/html/#10、创建服务文件[rootansible tasks]# vim service.yaml- name: startedserviceservice: name: httpd state: started enabled:yes#11、将任务按顺序编排到main.yaml 文件中[rootansible tasks]# vim main.yaml- include: group.yaml - include: user.yaml - include: install.yaml - include: copy.yaml - include: service.yaml - include: data.yaml#12、编写playbook用来调用httpd整个目录下的内容。注意需要与roles 是同级目录[rootansible ansible]# vim httpd_roles.yaml--- - hosts: web remote_user: root roles: - role: httpd#13、当前项目目录结构[rootansible ansible]# tree roles/httpd/roles/httpd/ ├── files │ ├── httpd.conf // 配置文件 │ └── index.html // html 文件 ├── tasks │ ├── copy.yaml │ ├── data.yaml │ ├── group.yaml │ ├── install.yaml │ ├── main.yaml │ ├── service.yaml │ └── user.yaml └── vars#14、执行playbook[rootansible ansible]# ansible-playbook -C httpd_roles.yamlPLAY[web]**************************************************************************** TASK[Gathering Facts]**************************************************************** ok:[192.168.115.112]TASK[httpd:create group]*********************************************************** changed:[192.168.115.112]TASK[httpd:create user]************************************************************** changed:[192.168.115.112]TASK[yum httpd]***************************************************************** changed:[192.168.115.112]TASK[httpd:copy file]******************************************************************* changed:[192.168.115.112]TASK[httpd:started service]**************************************************************** changed:[192.168.115.112]TASK[httpd:copy data file]******************************************************************** changed:[192.168.115.112]PLAY RECAP *********************************************************************************192.168.115.112:ok7changed6unreachable0failed0skipped0rescued0ignored0[rootansible ansible]#2、创建nginx服务的roles#1、将之前httpd的子目录都复制一份到nginx目录下[rootansible roles]# cp -r httpd ./nginx#2、修改main.yaml 文件[rootansible tasks]# vim main.yaml- include: install.yaml - include: copy.yaml - include: service.yaml - include: data.yaml#3、删除不需要的文件[rootansible tasks]# rm -rf group.yaml user.yaml#4、将安装的文件和启动的文件 name修改成nginx#5、修改copy.yaml文件改成使用template 模板的方式修改[rootansible tasks]# vim copy.yaml- name: copyfiletemplate: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf#6、在本地下载一个nginx 并将配置文件拷贝到 templates目录下[rootansible nginx]# mkdir tamplates[rootansible nginx]# yum -y install nginx[rootansible templates]# cp /etc/nginx/nginx.conf ./nginx.conf.j2#7、修改nginx.conf.j2配置文件的CPU内核user nginx;worker_processes{{ansible_processor_count*3}};#8、跨角色调用httpd服务的文件内容[rootansible tasks]# vim data.yaml- name: copy datafilecopy: src: roles/httpd/files/index.html dest: /usr/share/nginx/html/#9、编写playbook文件[rootansible ansible]# vim nginx_roles.yaml--- - hosts: web remote_user: root roles: - role: nginx#10、执行playbook[rootansible ansible]# ansible-playbook nginx_roles.yamlPLAY[web]*********************************************** TASK[Gathering Facts]*********************************** ok:[192.168.115.112]TASK[nginx:yum nginx]********************************* changed:[192.168.115.112]TASK[nginx:copy file]******************************** changed:[192.168.115.112]TASK[nginx:started service]************************* changed:[192.168.115.112]TASK[nginx:copy data file]************************** changed:[192.168.115.112]PLAY RECAP *********************************************192.168.115.112:ok5changed4unreachable0failed0skipped0rescued0ignored0#11、查看进程[rootansible ansible]# ansible web -m shell -a ps -ef |grep nginx192.168.115.112|CHANGED|rc0root136231014:41 ? 00:00:00 nginx: master process /usr/sbin/nginx nginx1362413623014:41 ? 00:00:00 nginx: worker process nginx1362513623014:41 ? 00:00:00 nginx: worker process nginx1362613623014:41 ? 00:00:00 nginx: worker process#12、查看端口[rootansible ansible]# ansible web -m shell -a ss -nlt#13、浏览器访问http://192.168.115.112:803、如果想触发 notify和handlers 这个角色可以修改配置文件#1、修改copy任务的配置文件添加notify如果文件有更改就触发[rootansible tasks]# vim copy.yaml- name: copyfiletemplate: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf notify: restart_nginx#2、创建handlers文件并添加main.yaml文件[rootansible nginx]# mkdir handlers[rootansible nginx]# vim main.yaml- name: restart_nginx service: name: nginx state: restarted#3、为了验证效果 我们把配置文件端口改成8080并且将nginx配置文件的名称以变量的方式传递[rootansible templates]# vim nginx.conf.j2user{{username}};server{listen8080;listen[::]:8080;#4、创建变量目录和main.yaml文件[rootansible vars]# vim main.yamlusername: daemon#5、执行playbook并查看端口 已改为8080查看用户一改为 daemon[rootansible ansible]# ansible-playbook nginx_roles.yaml[rootansible ansible]# ansible web -m shell -a ss -lnt[rootansible ansible]# ansible web -m shell -a ps -aux |grep nginx4、实现条件判断when5、使用标签实现playbook角色的调用#1、修改playbook文件[rootansible ansible]# vim nginx_roles.yaml--- - hosts: web remote_user: root roles: -{role: nginx,tags:[nginx,test1]}-{role: mysql,tags: db}#2、执行剧本[rootansible ansible]# ansible-playbook -t nginx nginx_roles.yaml#3、最后 卸载nginx[rootansible ansible]# ansible web -m yum -a namenginx stateabsent四、总结编写任务tasks时候里面不需要写需要执行的主机单纯的写某个任务是干什么的即可装软件就写装软件的启动就写启动的单独做某一件事即可最后通过main.yaml将这些单独的任务按照执行顺序 include 进来即可。这样方便维护且一目了然。定义变量时直接按照 K: V 的格式在vars/main.yaml文件写即可然后tasks或者template直接调用就行会自动去vars/main.yaml文件里找。定义handlers时直接在handlers/main.yaml文件中写需要做的事情即可多的话可以写在该文件里也可向像tasks那样写多个文件然后include 引入。在task调用notify时两者名字必须一致模板文件放在templates目录下tasks调用直接写文件名就行会自动去template 目录下找。注意如果一个角色调用另一个角色的任务的时候那么tasks中有些模板或者文件就得些绝对路径了。roles:{role: nginx,tags: [“nginx”,“test1”]}{role: mysql,tags: db}#2、执行剧本[rootansible ansible]# ansible-playbook -t nginx nginx_roles.yaml#3、最后 卸载nginx[rootansible ansible]# ansible web -m yum -a ‘namenginx stateabsent’# 四、总结 - 编写任务tasks时候里面不需要写需要执行的主机单纯的写某个任务是干什么的即可装软件就写装软件的启动就写启动的单独做某一件事即可最后通过main.yaml将这些单独的任务按照执行顺序 include 进来即可。这样方便维护且一目了然。 - 定义变量时直接按照 K: V 的格式在vars/main.yaml文件写即可然后tasks或者template直接调用就行会自动去vars/main.yaml文件里找。 - 定义handlers时直接在handlers/main.yaml文件中写需要做的事情即可多的话可以写在该文件里也可向像tasks那样写多个文件然后include 引入。在task调用notify时两者名字必须一致 - 模板文件放在templates目录下tasks调用直接写文件名就行会自动去template 目录下找。注意如果一个角色调用另一个角色的任务的时候那么tasks中有些模板或者文件就得些绝对路径了。