ansible基础-roles

一 简介

注:本文demo使用ansible2.7稳定版

在我看来,role是task文件、变量文件、handlers文件的集合体,这个集合体的显著特点是:可移植性和可重复执行性。

实践中,通常我们以部署某个服务为单元作为一个role ,然后将这些服务单元(role)放在一个roles目录下。主playbook文件通过调用roles目录下的role,来实现各种灵活多变的部署需求。

本节主要为大家介绍下roles的目录结构、引用方法及其他特性。

二 创建与目录结构

2.1 创建roles

通常创建一个role的方法有两种:

  • 命令mkdir和touch行手动创建
  • 使用ansible-galaxy自动初始化一个role

命令行手动创建方式就无需多说了,即需要哪个目录和文件就用「mkdir」和「touch」命令创建出来。

我个人比较喜欢使用「ansible-galaxy」命令创建,创建完后再删除我不需要的目录,这样可以避免因手误创建出错的问题。

例如,我想使用「ansible-galaxy init」命令创建一个名字为role_A 的role,可以这样写:

?  lab-ansible ansible-galaxy init role_A
- role_A was created successfully

创建后的目录结构如下:

?  lab-ansible tree role_A
role_A
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

8 directories, 8 files

使用「ansible-galaxy」命令自动创建的role是最全的目录结构,根据需求,可以删除不用的目录文件。

2.2 目录结构

我们以上面创建的「role_A」为例,介绍下各目录文件的作用:

  • tasks : 用于存放role_A的主要任务,也可以添加其他task文件,供main.yaml调用,从而实现更加复杂的部署功能。
  • handlers : 用于存放触发执行( hanlders )的任务。
  • defaults : 用于存放默认变量,优先级最低,变量优先级可参考《ansible基础-变量》。
  • vars : 用于存放变量文件,role_A中任务和模版里用到的变量可以在这里定义。
  • files :用于存放需要拷贝到目的主机的文件,例如,作为「copy」模块src参数的默认根目录。
  • template : 用于存放模版文件,格式为.j2,文件内容要符合Jinja2语法规则,通常使用「template」模块部署服务的配置文件。
  • meta : 用于存放role依赖列表,这个知识点后面会详细阐述。
  • tests : 用于存放测试role本身功能的playbook和主机定义文件,在开发测试阶段比较常用。

role中各个目录下的main.yaml文件很重要,这是ansible默认加载的YAML文件。

三 role的引用与执行

3.1 roles语句引用

比较常用的方法,我们可以使用「roles:」语句引用role :

---
- hosts: node1
  roles:
     - role_A

或者

---
- hosts: node1
  roles:
     - name: role_A
     - name: role_A

或者

---
- hosts: node1
  roles:
     - role: role_A
     - role: role_A

或者使用绝对路径:

---
# playbooks/test.yaml
- hosts: node1
  roles:
    - role: /root/lab-ansible/roles/role_A

引入的同时添加变量参数:

---
# playbooks/test.yaml
- hosts: node1
  roles:
    - role: role_A
      vars:
        name: Maurice
        age: 100

引入的同时添加tag参数:

---
# playbooks/test.yaml
- hosts: node1
  roles:
    - role: role_B
      tags:
        - tag_one
        - tag_two
    # 等价于上面
    - { role: role_B, tags:[‘tag_one‘,‘tag_two‘] }

根据需求,我们在playbook中引用不同的role,引用后的效果也很好理解:ansible会把role所包含的任务、变量、handlers、依赖等加载到playbook中,顺次执行。

检索路径

上面介绍了使用「roles」语句的引用方法,那么ansible去哪找这些role呢?

在不使用绝对路径的情况下,ansible检索role的默认路径有:

  • 执行ansible-playbook命令时所在的当前目录
  • playbook文件所在的目录及playbook文件所在目录的roles目录
  • 当前系统用户下的~/.ansible/roles目录
  • /usr/share/ansible/roles目录
  • ansible.cfg 中「roles_path」指定的目录,默认值为/etc/ansible/roles目录

注:上面的检索路径是在centos操作系统下测试出来的结果。

3.2 include和import引用

在后来版本(ansible>=2.4)中,ansible引入了「import_role」(静态)和「include_role」(动态)方法:

---
# playbooks/test.yaml
- hosts: node1
  tasks:
    - include_role:
        name: role_A
      vars:
        name: maurice
        age: 100
    - import_role:
        name: role_B

比较于「roles」语句,「import_role」和「include_role」的优点如下:

  • 可以在task之间穿插导入某些role,这点是「roles」没有的特性。
  • 更加灵活,可以使用「when」语句等判断是否导入。

关于include_role(动态)和import_role(静态)的区别,可以参考笔者之前的文章《ansible中include_tasks和import_tasks》。

也正是因为「include_task」是动态导入,当我们给「include_role」导入的role打tag时,实际并不会执行该role的task。

举个??,当我们使用include导入role_A,使用import导入role_B时:

---
# playbooks/test.yaml
- hosts: node1
  tasks:
    - include_role:
        name: role_A
      tags: maurice
    - import_role:
        name: role_B
      tags: maurice

role_A内容如下:

---
# tasks file for role_A

- debug:
    msg: "age"

- debug:
    msg: "maurice"

执行结果显示,role_A虽然被引用,但里面的task并没有执行:

PLAY [node1] *************************************************************

TASK [Gathering Facts] *************************************************************
ok: [node1]

TASK [include_role : role_A] *************************************************************

TASK [role_B : debug] *************************************************************
ok: [node1] => {
    "msg": "I‘m just role_B"
}

PLAY RECAP *************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0

3.3 重复引用

不添加其他变量、tag等的情况下,一个playbook中对同一个role引入多次时,实际ansible只会执行一次。

例如:

---
# playbooks/test.yaml
- hosts: node1
  roles:
    - role_A
    - role_A

当然,我们也可以让其运行多次,方法如下:

  • 引用role的同时定义不同的变量
  • 在meta/main.yaml中添加「allow_duplicates: true」(这个特性笔者实测未生效……)

两种情况示例分别如下:

---
- hosts: webservers
  roles:
  - role: foo
    vars:
         message: "first"
  - { role: foo, vars: { message: "second" } }
# playbook.yml
---
- hosts: webservers
  roles:
  - foo
  - foo

# roles/foo/meta/main.yml
---
allow_duplicates: true

3.4 执行顺序

笔者之前的文章《ansible基础-playbooks》「5.执行顺序」中提到,如果playbook中只有「tasks」和「roles」,ansible总是会先执行「roles」语句部分。此时可以使用「per_tasks」和「post_tasks」来规范执行顺序。

在使用「per_tasks」+「roles」+「tasks」+「post_tasks」结构下,task的执行顺序为:

  • per_task包含的play
  • per_task中handlers任务
  • roles语句中role列表依次执行,每个role优先执行依赖的play及任务
  • tasks语句中的所有play
  • 前两步所触发的handlers
  • post_tasks包含的play
  • post_tasks触发的handlers

四 role的依赖

role的依赖指role_A可以引入其他的role,例如role_B。

roles的依赖知识点总结如下:

  • 配置的路径在role_A的meta/main.yaml
  • 引入role列表的方式只能使用类似「roles」语句的方法,只需将「roles」换为「dependencies」语句,不能用新版本的include和import语句
  • 在meta/main.yaml文件内可以引入多个role,且必须以列表的形式引入
  • 在引入role的同时,可以添加变量,方法同「roles」语句

多层依赖

被引入的role总是优先执行,即便是同一个 role 被引入了多次(遵循3.3重复引用规则)。

举个??:

role「car」引入了role「wheel」:

---
# roles/car/meta/main.yml
dependencies:
- role: wheel
  vars:
     n: 1
- role: wheel
  vars:
     n: 2
- role: wheel
  vars:
     n: 3
- role: wheel
  vars:
     n: 4

同时,role「wheel」引入了role「tire」和「brake」:

---
# roles/wheel/meta/main.yml
dependencies:
- role: tire
- role: brake

最终的执行结果为:

tire(n=1)
brake(n=1)
wheel(n=1)
tire(n=2)
brake(n=2)
wheel(n=2)
...
car

五 插件和模块

我们可以为一个role自定义模块和插件,这部分属于高级特性,在以后的「ansible进阶」系列文章中会详细阐述,这里只简单介绍下。

模块

给某个role自定义模块,需要在这个role的目录下创建「library」目录,然后将自定义模块放在该目录下。

创建自定义模块目录结构示例:

roles/
   my_custom_modules/
       library/
          module1
          module2

引用的时候在「my_custom_modules」后被引用的role也可以使用该自定义模块:

- hosts: webservers
  roles:
    - my_custom_modules
    - some_other_role_using_my_custom_modules
    - yet_another_role_using_my_custom_modules

插件

自定义插件的方法与模块类似,需要创建的目录为「filter_plugins」。

创建自定义插件目录结构示例:

roles/
   my_custom_filter/
       filter_plugins
          filter1
          filter2

与模块一样,自定义插件可以在本身role的task和模版内使用,也可以在 role「my_custom_filter」之后被引用的role内使用。

六 Ansible Galaxy

Ansible Galaxy是一个免费的roles仓库,里面有很多社区里现成稳定的role,在生产中的部署项目中,可以直接下载下来使用。

Ansible Galaxy客户端是「ansible-galaxy」,「ansible-galaxy」命令行可以用来初始化一个role(本文2.1 创建roles有提),也可以用来从Ansible Galaxy下载role。

关于Ansible Galaxy的详细介绍,因篇幅原因,这里不再扩展,有兴趣的同学可以去官网<https://galaxy.ansible.com/docs/>加深学习下。

七 本节应该掌握的技能

  • 掌握role的目录结构及其含义
  • 掌握引用role的方法
  • 掌握role的依赖及执行顺序
  • 了解自定义模版和插件
  • 了解Ansible Galaxy

八 参考链接

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

欢迎大家关注我的公众号:

原文地址:https://www.cnblogs.com/mauricewei/p/10056458.html

时间: 2024-10-01 06:00:07

ansible基础-roles的相关文章

ansible基础-安装与配置

一 安装 1.1 ansible架构 ansible是一个非常简单的自动化部署项目,由python编写并且开源.用于提供自动化云配置.配置文件管理.应用部署.服务编排和很多其他的IT自动化需求. ansible实现的自动化部署是多层次的,通过描述系统之间的逻辑关系来构建业务所需要的基础架构模型,而不仅仅用于管理一个单独的系统:也就是说ansible不仅仅能部署一个或多个独立的服务,它还能对这些服务做关联.对部署顺序做编排等,一个完美的ansible部署项目应该是层次分明.顺序有秩的. 另外,an

Ansible的roles功能(五)

针对大型项目使用Roles进行编排,更便利 目录结构编排 一键安装httpd并提供服务 创建目录结构 [[email protected] ansible]# mkdir -p roles/httpd/{tasks,files,vars} [[email protected] ansible]# cd roles/httpd/tasks [[email protected] roles]#touch httpd/{files/main.yml,tasks/{groupadd.yml,instal

ansible基础

ansible 介绍:官网,百科之类的 ansible的部署 centos 6.5上的部署. 2.2.2.11 node1.king.com ansible 2.2.2.15 node3.king.com 2.2.2.12 node2.king.com tar xf ansible-1.5.4.tar.gz cd ansible-1.5.4 python setup.py build python setup.py install mkdir /etc/ansible cp -r example

关于ansible基础入门和功能实现教程的更新页面

最近发现MDT推出去的系统的有不同问题,其问题就不说了,主要是策略权限被域继承了.比如我们手动安装的很多东东都是未配置壮态,推的就默认为安全壮态了,今天细找了一下,原来把这个关了就可以了. 关于ansible基础入门和功能实现教程的更新页面

L13 ansible 基础应用与常见模块

ansible 基础应用与常见模块 ansible中文手册:http://www.simlinux.com/books/Ansible-notes.pdf 1,运维工具简介 运维工具: 系统安装(物理机.虚拟机)--> 程序安装.配置.服务启动 --> 批量操作(批量运行命令) --> 程序发布 --> 监控 ansible 能够实现:程序安装.配置.服务启动 --> 批量操作(批量运行命令) --> 程序发布 ansible的核心组件: ansible core ho

ansible之roles

软件lamp目录结构: files:存文件的,ansible默认就会到这里目录去找文件,对应task里面的copy模块 tasks:存放tasks的 handlers:存放handlers templates:存放模板,对应task里面的模块template vars:这里面定义的变量,只对当前role有作用 meta:定义role和role直接的依赖关系. [[email protected]_2 ~]# tree /root/lamp/ /root/lamp/ ├── hosts ├── r

自动化运维工具之ansible基础入门

自动化运维工具常用的有 ansible  saltstack  puppet等 ,前两者都是基于python开发,puppet基于ruby开发,今天我们简单介绍下ansible基础 一.基础知识: 1. 简介 ansible基于python开发,集合了众多运维工具的优点,实现了批量系统配置.批量程序部署.批量运行命令等功能.ansible是基于模块工作的 (1) host inventory: 指定操作的主机,是一个配置文件里面定义监控的主机        (2) 各种模块核心模块.comman

Ansible 之 roles使用

1  概述 角色(roles):把playbook根据功能,如handler,tasks等分门别类的放在在各自的子目录下,形成一个集合,就是角色,建议把角色放在固定的目录下,目录可以ansible的配置文件中的roles_path来定义. role模板查看链接:https://github.com/ansible/ansible-examples 2  配置介绍 以层级结构组织Playbook的核心元素,成为roles. 核心元素包括以下几点: Hosts:主机 Tasks:任务列表 Varia

ansible基础与部分模块应用

ansible基础与部分模块应用 1. ansible特性: ansible糅合了众多老牌运维工具的优点,基本上pubbet和saltstack能实现的功能全部能实现. 部署简单:不需要在被管控主机上安装任何客户端,操作客户端时直接运行命令. 基于python语言实现,有Paramiko, PyYAML和Jinja2三个关键模块. 模块化:调用特定模块完成特定任务.可使用任意语言开发模块,且支持自定义模块. 使用yaml语言定制剧本playbook. 基于SSH作 2. ansible的模块 c