文章

Ansible Roles角色

Roles角色

1、Roles角色简介

Roles角色是ansible在1.2版本引入的新特性,用于层次性、结构化地组织playbook剧本,roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。

Roles角色官方文档:https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html

1.1 为什么需要使用角色?

剧本存在的问题:
1.单纯使用剧本不够灵活,臃肿
2.将变量,任务,handlers等所有内容全部写在剧本中修改不方便
3.剧本文件,配置文件模板随意存放,不标准

roles角色如何解决上述问题:
1.拆分,原本所有内容都存放于剧本中,角色把剧本中的内容进行拆分单独存放
2.解耦,结构更清晰,调试更方便

1.2 角色的使用场景

复杂的运维场景建议使用roles,代码复用度高。

1.3 角色编写注意事项

1.不要直接书写角色,先写好剧本,然后将剧本拆分
2.不要想着一步到位,不用拆分的很细,尤其是变量部分

2、角色的目录编排

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

Roles目录结构:

site.yml            #整个项目剧本,可以调用多个角色
roles_name01.yml    #第一个角色剧本,用于调用第一个角色
roles_name02.yml    #第二个角色剧本,用于调用第二个角色
roles/              #存放所有角色的目录
    roles_name01/   #第一个角色目录名称,存放该角色所有内容
        tasks/      #存放角色执行的任务,至少包含一个名为main.yml的文件
        handlers/   #存放触发器语句handlers,包含一个名为main.yml的文件
        vars/       #定义用到的变量,包含一个main.yml文件
        files/      #存放由copy或script等模块调用的文件
        templates/  #templates模块会自动在此目录中寻找Jinja2模板文件
        library/    #存放可在此角色中使用的模块
        defaults/   #存放角色的默认变量;这些变量在所有可用变量中具有最低优先级,并且可以很容易地被任何其他变量(包括库存变量)覆盖,包含一个main.yml文件
        meta/       #定义此角色的特殊设定及其依赖关系,包含一个main.yml文件
    roles_name02/   #第二个角色目录名称,存放该角色所有内容
        tasks/
        defaults/
        meta/

#默认情况下,Ansible在角色中每个目录的main.yml(main.yaml)文件中查找相关内容

#所有角色的存放位置:默认存放于/etc/ansible/roles
[root@manager-18 ~]# grep "roles_path" /etc/ansible/ansible.cfg 
#roles_path    = /etc/ansible/roles

3、编写一个角色

3.1 编写思路

1.先写好剧本
2.创建角色目录
3.将需要使用的文件,放入指定的角色目录
4.拆分剧本

3.2 编写角色

# 1.先写好剧本,nginx服务部署剧本编写
[root@manager-18 ~]# vim nginx_config.yml
---
- name: nginx_config
  hosts: web
  vars: 
    nginx_vhosts:
      - listen: 80
      - listen: 8080

  tasks:
  - name: check_nginx_repo_exists
    stat:
      path: /etc/yum.repos.d/nginx.repo
    ignore_errors: true
    register: nginx_repo_file_status
  - name: yum_config
    copy:
      src: ./nginx.repo
      dest: /etc/yum.repos.d/nginx.repo
    when: nginx_repo_file_status.stat.exists == false
  - name: yum_install_nginx
    yum:
      name: nginx
      state: latest
  - name: copy_nginx_config
    template:
      src: ./nginx.conf.j2
      dest: /etc/nginx/nginx.conf
      backup: yes
    notify: restart_nginx

  handlers:
    - name: restart_nginx
      service:
        name: nginx
        state: restarted
        enabled: yes

# 2.创建角色目录
[root@manager-18 ~]# cd /etc/ansible/roles/
[root@manager-18 /etc/ansible/roles]# mkdir -p nginx_config/{tasks,handlers,vars,files,templates}

[root@manager-18 /etc/ansible/roles]# tree nginx_config/
nginx_config/
├── files
├── handlers
├── tasks
├── templates
└── vars

# 3.将需要使用的文件,放入指定的角色目录
[root@manager-18 /etc/ansible/roles]# cd nginx_config/
[root@manager-18 /etc/ansible/roles/nginx_config]# mv /root/nginx.repo ./files/
[root@manager-18 /etc/ansible/roles/nginx_config]# mv /root/nginx.conf.j2 ./templates/

# 4.拆分剧本
#拆分tasks剧本任务
[root@manager-18 /etc/ansible/roles/nginx_config]# vim tasks/main.yml
- name: check_nginx_repo_exists
  stat:
    path: /etc/yum.repos.d/nginx.repo
  ignore_errors: true
  register: nginx_repo_file_status
- name: yum_config
  copy:
    src: nginx.repo        #此处因为文件已经放在角色对应的文件目录,直接写文件名即可
    dest: /etc/yum.repos.d/nginx.repo
  when: nginx_repo_file_status.stat.exists == false
- name: yum_install_nginx
  yum:
    name: nginx
    state: latest
- name: copy_nginx_config
  template:
    src: nginx.conf.j2     #此处因为模板已经放在角色对应的模板目录,直接写模板文件名称即可
    dest: /etc/nginx/nginx.conf
    backup: yes
  notify: restart_nginx

#拆分handlers触发器语句
[root@manager-18 /etc/ansible/roles/nginx_config]# vim handlers/main.yml
- name: restart_nginx
  service:
    name: nginx
    state: restarted
    enabled: yes 

#拆分vars变量
[root@manager-18 /etc/ansible/roles/nginx_config]# vim vars/main.yml
nginx_vhosts:
  - listen: 80
  - listen: 8080

#此时一个简单的nginx服务部署的角色就编写完成

3.3 调用角色

调用角色需要先编写角色剧本,然后通过剧本调用角色。

[root@manager-18 /etc/ansible/roles/nginx_config]# mkdir /root/ansible_roles_playbooks
[root@manager-18 /etc/ansible/roles/nginx_config]# cd /root/ansible_roles_playbooks

[root@manager-18 ~/ansible_roles_playbooks]# vim nginx_config_roles.yml
---
- name: nginx_config
  hosts: web
  roles:                #该语句用于调用角色
    - nginx_config      #调用名称为nginx_config的角色,可调用多个角色

#测试,运行剧本,通过角色剧本调用角色
[root@manager-18 ~/ansible_roles_playbooks]# ansible-playbook nginx_config_roles.yml

调用角色的几种方法:

#方法1,调用多个角色
---
- name: test
  hosts: test
  roles:
    - nginx
    - mysql
    - memcached    #调用多个角色

#方法2,调用角色时传递变量
---
- name: test
  hosts: test
  roles:
    - { role: nginx,username: nginx }  #键role用于指定角色名称,后续的k/v表示传递变量给该角色
    - mysql
    - memcached

#方法3,基于条件判断调用角色
---
- name: test
  hosts: test
  roles:
    - { role: nginx,username: nginx,when: ansible_distribution == "CentOS" }  #基于条件判断调用角色
    - mysql
    - memcached

#方法4,给角色设置标签
---
- name: test
  hosts: test
  roles:
    - { role: nginx,tags: [ 'nginx','web' ] }
    - { role: httpd,tags: [ 'httpd','web' ] }
    - { role: mysql,tags: [ 'mysql','db' ] }
    - { role: mariadb,tags: [ 'mariadb','db' ] }   #在此给每个角色设定了两个标签

#运行剧本时指定标签,角色标签包含指定标签时角色才会被调用
ansible-playbook -t "nginx,mysql" 角色剧本          #此时只有角色标签中包含"nginx,mysql"标签的角色会被调用执行

4、ansible-galaxy工具

Ansible Galaxy是Ansible的官方社区中心,用于共享Ansible角色。简单说就是一个ansible角色仓库,将已经写好的角色上传至Galaxy社区,供所有人下载使用。

Ansible Galaxy社区地址:https://galaxy.ansible.com

ansible-galaxy工具使用:

#在当前目录初始化一个空白角色
[root@manager-18 ~]# ansible-galaxy init 角色名称

#查看本地已安装的角色
[root@manager-18 ~]# ansible-galaxy list
# /usr/share/ansible/roles
# /etc/ansible/roles

#安装一个角色,Galaxy社区会提供角色的安装指令
[root@manager-18 ~]# ansible-galaxy install username.role_name  #这里的username.role_name可以Galaxy社区地址查看

[root@manager-18 ~]# ansible-galaxy install nginxinc.nginx
- downloading role 'nginx', owned by nginxinc
- downloading role from https://github.com/nginxinc/ansible-role-nginx/archive/0.22.0.tar.gz
- extracting nginxinc.nginx to /root/.ansible/roles/nginxinc.nginx
- nginxinc.nginx (0.22.0) was installed successfully

#删除一个角色
[root@manager-18 ~]# ansible-galaxy remove username.role_name

[root@manager-18 ~]# ansible-galaxy remove nginxinc.nginx
- successfully removed nginxinc.nginx

#从文件安装多个角色
[root@manager-18 ~]# ansible-galaxy install -r requirements.txt

requirements.txt文件属性:
src         #角色的来源,如果从Galaxy下载,请使用username.role_name格式,否则提供指向基于git的SCM中的存储库的URL
scm         #指定SCM,在撰写本文时,只支持git或hg,默认为git
version     #git分支,提供发布标签值,默认为master
name        #将角色下载为指定名称,从Galaxy下载时默认为Galaxy名称,否则默认为存储库的名称

#requirements.txt案例:
# from galaxy
- src: yatesr.timezone

# from GitHub
- src: https://github.com/bennojoy/nginx

# from GitHub, overriding the name and specifying a specific tag
- src: https://github.com/bennojoy/nginx
  version: master
  name: nginx_role

# from a webserver, where the role is packaged in a tar.gz
- src: https://some.webserver.example.com/files/master.tar.gz
  name: http-role

# from Bitbucket
- src: git+http://bitbucket.org/willthames/git-ansible-galaxy
  version: v1.4

# from Bitbucket, alternative syntax and caveats
- src: http://bitbucket.org/willthames/hg-ansible-galaxy
  scm: hg

# from GitLab or other git-based scm
- src: git@gitlab.company.com:mygroup/ansible-base.git
  scm: git
  version: "0.1"

#调用ansible-galaxy安装的角色
[root@manager-18 ~]# cd ansible_roles_playbooks/
[root@manager-18 ~/ansible_roles_playbooks]# vim nginx_test_roles.yml
---
- name: nginx_test
  hosts: web
  roles:
    - nginxinc.nginx     #指定ansible-galaxy安装的角色的名称

[root@manager-18 ~/ansible_roles_playbooks]# ansible-playbook nginx_test_roles.yml      //运行剧本即可
License: