当前位置: 首页 > news >正文

Ansible的role

环境

  • 控制节点:Ubuntu 22.04
  • Ansible 2.10.8
  • 管理节点:CentOS 8

role

目录结构

role的文件结构中,包含了8个标准目录:

  • tasks
  • handlers
  • templates
  • files
  • vars
  • defaults
  • meta
  • library

例如,下面是 common 这个role的目录结构:

roles/common/               # this hierarchy represents a "role"tasks/            #main.yml      #  <-- tasks file can include smaller files if warrantedhandlers/         #main.yml      #  <-- handlers filetemplates/        #  <-- files for use with the template resourcentp.conf.j2   #  <------- templates end in .j2files/            #bar.txt       #  <-- files for use with the copy resourcefoo.sh        #  <-- script files for use with the script resourcevars/             #main.yml      #  <-- variables associated with this roledefaults/         #main.yml      #  <-- default lower priority variables for this rolemeta/             #main.yml      #  <-- role dependencieslibrary/          # roles can also include custom modules

Ansible默认会在每个目录下查找 main.yml (或者 main.yaml / main )文件。

例:创建目录结构如下:

➜  testRole1 tree
.
├── roles
│   ├── role1
│   │   └── tasks
│   │       └── main.yml
│   ├── role2
│   │   └── tasks
│   │       └── main.yml
│   └── role3
│       └── tasks
│           └── main.yml
└── test.yml

其中, test.yml 内容如下:

---
- hosts: allroles:- role1- role2

注:此处也可以写为:

---
- hosts: allroles:- role: role1- role: role2

两种方式甚至可以混用。

本例中,指定为只包含 role1role2 的内容。

roles/role1/tasks/main.yml 的内容如下(role2和role3类似):

---
- name: role1 task1debug:msg: "I am role1 task1"
- name: role1 task2debug:msg: "I am role1 task2"

运行结果如下:

➜  testRole1 ansible-playbook testRole_1.ymlPLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [role1 : role1 task1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role1 task1"
}TASK [role1 : role1 task2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role1 task2"
}TASK [role2 : role2 task1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role2 task1"
}TASK [role2 : role2 task2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role2 task2"
}PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

可见,ansible只运行了指定的role。本例中,运行了role1和role2的所有task。

Ansible有以下几种方式来查找role:

  • 在collections里
  • roles 目录下,即本例所示
  • 配置 roles_path ,其缺省的查找路径为 ~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
  • 在playbook文件同级,即省略 roles 目录,对于本例,可变为:
➜  testRole2 tree
.
├── role1
│   └── tasks
│       └── main.yml
├── role2
│   └── tasks
│       └── main.yml
├── role3
│   └── tasks
│       └── main.yml
└── test.yml

虽然可以省略 roles 目录,但显然加上这一级目录会更清晰一些。

  • 直接在playbook中指定role路径,比如:
---
- hosts: allroles:- role: '/path/to/my/roles/common'

使用role

可通过以下几种方式使用role:

  • 在play级别使用 roles :经典用法,静态引入
  • 在task级别使用 include_role :动态引入
  • 在task级别使用 import_role :静态引入

在play级别使用role

比如:

---
- hosts: webserversroles:- common- webservers

可以给 roles 添加 tagsvars 等选项。

修改role1,role2,role3的 tasks/main.yml ,打印 {{ var1 }} 变量。role1修改如下(role2,role3类似):

---
- name: role1 task1debug:msg: "I am role1 task1 {{ var1 }}"
- name: role1 task2debug:msg: "I am role1 task2"

创建 test.yml 如下:

---
- hosts: allroles:- role1- role: role2vars:var1: "hello"tags: tag1

运行结果如下:

➜  testRole3 ansible-playbook test.yml            PLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [role1 : role1 task1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role1 task1 hello"
}TASK [role1 : role1 task2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role1 task2"
}TASK [role2 : role2 task1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role2 task1 hello"
}TASK [role2 : role2 task2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role2 task2"
}PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

可见,在 role2 中定义的变量 var1 ,在 role1 中也可用(可通过 DEFAULT_PRIVATE_ROLE_VARS 来定制其行为)。

但是,请注意 role2 中添加的tag tag1 ,只针对role2中的每个task都有效:

➜  testRole3 ansible-playbook test.yml --tags tag1PLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [role2 : role2 task1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role2 task1 hello"
}TASK [role2 : role2 task2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role2 task2"
}PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

在task级别include_role

修改role1,role2,role3的 tasks/main.yml ,去掉变量var1。修改 test.yml 如下:

---
- hosts: alltasks:- name: task1debug:msg: "I am task1"- name: task2include_role:name: role3- name: task3debug:msg: "I am task3"

运行结果如下:

➜  testRole4 ansible-playbook test.ymlPLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "I am task1"
}TASK [task2] ***************************************************************************************TASK [role3 : role3 task1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role3 task1"
}TASK [role3 : role3 task2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role3 task2"
}TASK [task3] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "I am task3"
}PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

include_role 可以添加 tagsvarswhen 等选项。

例如:

......- name: task2include_role:name: role3when: "ansible_facts['os_family'] == 'RedHataa'"
......

则只有满足 when 的条件时,才会生效。

这里格外需要注意 tagsinclude_role 的tag只针对 include_role 自身有效。

如果运行playbook时,指定了 --tags 选项,则:

  • 不满足tag条件的 include_role 都不会运行
  • 满足tag条件的 include_role 中,只有满足tag条件的task会运行

例如,创建 test.yml 如下:

---
- hosts: alltasks:- name: task1debug:msg: "I am task1"- name: task2include_role:name: role1tags: tag1- name: task3include_role:name: role3tags: tag2- name: task4debug:msg: "I am task4"

role1/task/main.yml 如下:

---
- name: role1 task1debug:msg: "I am role1 task1"
- name: role1 task2debug:msg: "I am role1 task2"

role3/task/main.yml 如下:

---
- name: role3 task1debug:msg: "I am role3 task1"tags: tag1
- name: role3 task2debug:msg: "I am role3 task2"tags: tag2

运行playbook时,如果不指定 --tags ,则所有task都会运行。

运行playbook时,如果指定 --tags tag1 ,则只有task2(即role1)满足tag条件,但是role1里的task都不满足tag条件,所以也都不会运行:

➜  testRole4 ansible-playbook test.yml --tags tag1PLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task2] ***************************************************************************************PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

运行playbook时,如果指定 --tags tag2 ,则只有task3(即role3)满足tag条件,而role3的task中,只有“role3 task2”同时满足tag条件,所以只有“role3 task2”会运行:

➜  testRole4 ansible-playbook test.yml --tags tag2PLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task3] ***************************************************************************************TASK [role3 : role3 task2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role3 task2"
}PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

在task级别import_role

其行为和 roles 选项是一样的。

这里格外需要注意 tagsimport_role 的tag针对role里的所有task都有效。

如果运行playbook时,指定了 --tags ,则:

  • 不满足tag条件的 import_role 中,满足tag条件的task会运行
  • 满足tag条件的 import_role 中,所有task都会运行

例如,修改上例中的 test.yml ,把 include_role 改为 import_role ,如下:

---
- hosts: alltasks:- name: task1debug:msg: "I am task1"- name: task2import_role:name: role1tags: tag1- name: task3import_role:name: role3tags: tag2- name: task4debug:msg: "I am task4"

role1和role3同上例。

运行playbook时,如果不指定 --tags ,则所有task都会运行。

运行playbook时,如果指定 --tags tag1 ,则task2(即role1)满足tag条件,则role1里的所有task都会运行。同时task3(即role3)虽然不满足tag条件,但role3里满足tag条件的task会运行:

➜  testRole5 ansible-playbook test.yml --tags tag1PLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [role1 : role1 task1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role1 task1"
}TASK [role1 : role1 task2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role1 task2"
}TASK [role3 : role3 task1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role3 task1"
}PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

同理,如果运行playbook时,指定 --tags tag2 ,则task2(即role2)不满足tag条件,且role2里的所有task也都不满足tag条件,所以都不会运行。同时,task3(即role3)满足tag条件,则role3里所有的task都会运行:

➜  testRole5 ansible-playbook test.yml --tags tag2PLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [role3 : role3 task1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role3 task1"
}TASK [role3 : role3 task2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role3 task2"
}PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

include_role和import_role的tag

二者区别总结如下:

include_role 满足tag条件include_role 不满足tag条件
task满足tag条件YN
task不满足tag条件NN
import_role 满足tag条件import_role 不满足tag条件
task满足tag条件YY
task不满足tag条件YN

roles 的tag行为和import_role 一致(都是静态引入)。

动态引入和静态引入的区别

include_role是动态引入,import_role是静态引入。

动态引入, include_task 本身也是一个task,例如:

---
- hosts: alltasks:- name: task1include_role:name: role1
➜  testRole6 ansible-playbook test.yml            PLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task1] ***************************************************************************************TASK [role1 : role1 task1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role1 task1"
}TASK [role1 : role1 task2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role1 task2"
}PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

include_role 改为 import_role ,再次运行,如下:

➜  testRole6 ansible-playbook test.ymlPLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [role1 : role1 task1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role1 task1"
}TASK [role1 : role1 task2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am role1 task2"
}PLAY RECAP *****************************************************************************************
192.168.1.55               : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

可见,前者的输出结果中,有一行 TASK [task1] ,而后者没有这一行输出。

这是因为,静态引入,是在预编译期,已经把task1所代表的role1的task静态的引入进来了,在运行期也就没有task1了。而动态引入,在运行期保留了task1,运行到此处时,才把role1引入进来。

这也能解释tag的行为为何会有不同,因为对于静态引入,运行期已经没有task1了,所以tag在预编译期已经被应用到role1实际的task上去了。而对于动态引入,tag确实是应用于task1上的。

参考

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

相关文章:

  • 0基础学习PyFlink——使用datagen生成流式数据
  • 【架构图解】API架构图解:如何以图表形式展现复杂系统
  • XPATH 注入漏洞
  • 数据可视化:动态柱状图
  • 关于SNAP的Biophysical Processor模块的计算准确率以及大厂10月种植情况
  • 网络安全进阶学习第二十一课——XXE
  • Docker数据卷使用过程中想到的几个问题
  • linux下使用vscode对C++项目进行编译
  • vue的rules验证失效,部分可以部分又失效的原因
  • Linux之管道
  • 下载安装各种版本的Vscode以及解决VScode官网下载慢的问题
  • MySQL 为什么在 8.0 版本中移除了查询缓存功能?
  • 【AI视野·今日Robot 机器人论文速览 第六十一期】Tue, 24 Oct 2023
  • diffusers-Load adapters
  • 系统设计中的缓存技术:完整指南
  • 网络传输文件的问题
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • Android组件 - 收藏集 - 掘金
  • Java 23种设计模式 之单例模式 7种实现方式
  • javascript 哈希表
  • JavaScript 基础知识 - 入门篇(一)
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • MQ框架的比较
  • PHP 小技巧
  • Python socket服务器端、客户端传送信息
  • Python3爬取英雄联盟英雄皮肤大图
  • Python语法速览与机器学习开发环境搭建
  • Redis的resp协议
  • TCP拥塞控制
  • vue--为什么data属性必须是一个函数
  • webpack+react项目初体验——记录我的webpack环境配置
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 关于List、List?、ListObject的区别
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 移动端唤起键盘时取消position:fixed定位
  • ​queue --- 一个同步的队列类​
  • # Apache SeaTunnel 究竟是什么?
  • # 安徽锐锋科技IDMS系统简介
  • #微信小程序:微信小程序常见的配置传旨
  • $ git push -u origin master 推送到远程库出错
  • (3)(3.5) 遥测无线电区域条例
  • (AngularJS)Angular 控制器之间通信初探
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (pojstep1.1.2)2654(直叙式模拟)
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (力扣题库)跳跃游戏II(c++)
  • (五)Python 垃圾回收机制
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • (转)程序员疫苗:代码注入
  • ./configure,make,make install的作用
  • .net core开源商城系统源码,支持可视化布局小程序
  • .NET delegate 委托 、 Event 事件
  • .Net Remoting常用部署结构
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...