ansible——playbook lookups从插件加载变量
之前说过playbook的变量引用,这是传参的一种方式。
playbook还支持很多插件从外部读取数据,比如从文件中读取、从数据库中读取。
lookups的所有操作都是在中控机上进行。目前有58个插件
官网文档:https://docs.ansible.com/ansible/latest/plugins/lookup.html#plugin-list
下面介绍几个常用的。
1.lookups file
通过file插件可以读取文件。其内部是使用python打开文件然后把结果返回给变量。
[root@centos3 yaml_test]# cat file_lookup.yaml --- - hosts: all gather_facts: False vars: contents: "{{ lookup('file','/etc/hostname') }}" tasks: - name: debug lookups debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
执行结果:
file这个插件读取的是中控机本地的文件,然后拿到数据以供任务使用.
这里使用的是jinjia2的语法.
2.lookups password
passwd这个插件会对传入的内容进行加密处理.
定义:pass_lookup.yaml
--- - hosts: all vars: contents: "{{ lookup('password', 'ansible_book') }}" tasks: - name: debug lookups debug: msg="The contents is {{ contents }}"
执行结果:
上面的例子就是将ansible_book加密,然后以作他用.
3.lookups pipe
pipe插件运行命令并返回结果。
--- - hosts: all vars: contents: "{{ lookup('pipe', 'date +%Y-%m-%d') }}" tasks: - name: debug lookups debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}
执行结果:
pipe看起和shell一样,也是用来执行命令,但是shell是在管理节点上执行,而pipe是在中控机上执行。
pipe这个插件底层使用的是subprocess这个python库来实现的
subprocess是用来生成新的进程,连接它们的输入输出。Popen类是用来创建和管理进程。
虽然增加一个进程不一定能够解决ansible进程和pipe进程的拥堵问题,但是一般情况还是适用的。
4.lookups redis_kv
redis_kv是用来从本地redis中读取数据。
ansible默认支持的是python2,因此你需要在python2中添加redis这个python包。
定义: redis_lookup.yaml
--- - hosts: all vars: contents: "{{ lookup('redis_kv', 'redis://127.0.0.1:6379,ansible') }}" tasks: - name: debug lookups debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
执行结果:
查看源码:
#ansible/lib/ansible/plugins/lookup/_redis_kv.py # (c) 2012, Jan-Piet Mens <jpmens(at)gmail.com> # (c) 2017 Ansible Project # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import (absolute_import, division, print_function) #程序检测 __metaclass__ = type import os import re HAVE_REDIS = False try: import redis #python是否已经安装了python模块 HAVE_REDIS = True except ImportError: pass from ansible.errors import AnsibleError from ansible.plugins.lookup import LookupBase class LookupModule(LookupBase): def run(self, terms, variables, **kwargs): #term是连接参数 if not HAVE_REDIS: #redis模块检测 raise AnsibleError("Can't LOOKUP(redis_kv): module redis is not installed") ret = [] for term in terms: #返回连接路径 (url, key) = term.split(',') if url == "": url = 'redis://localhost:6379' # urlsplit on Python 2.6.1 is broken. Hmm. Probably also the reason # Redis' from_url() doesn't work here. p = '(?P<scheme>[^:]+)://?(?P<host>[^:/ ]+).?(?P<port>[0-9]*).*' try: #正则匹配来获取主机信息和端口号 m = re.search(p, url) host = m.group('host') port = int(m.group('port')) except AttributeError: raise AnsibleError("Bad URI in redis lookup") try: conn = redis.Redis(host=host, port=port) #连接获取对应的值 res = conn.get(key) if res is None: res = "" ret.append(res) except Exception: ret.append("") # connection failed or key not found return ret #将值返回
整个过程并不复杂,解析参数、获取连接然后取值。
与callback类型的插件一样,都是自定义一个类,名字名字应该是固定格式,LookupModule,
这个类必须继承LookupBase这个基础类,往前继承AnsiblePlugin这个基础类。
如果你要自定义一个lookup插件,自定义LookupModule这个类就行了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理