有没有办法在Ansible group_vars
文件或Ansible使用的Jinja2模板中将任意字符串解析为主机名?比方说,我想在global_vars/all
中定义一个变量,该变量将包含www.google.com
解析为的几个IP地址之一。在这个例子中,我使用www.google.com
作为可以解析为多个IP地址的字符串的示例,但我不能使用Ansible hostvars
作为地址,因为我不能ssh到它。
我尝试连接Pythonic socket.gethostbyname()
,但无法正确使用语法。最多,我的变量变成了一个文字“socket.gethostbyname('my-host-1')”。
我知道我可以回退到shell脚本并利用shell中提供的工具,但我想知道在Ansible中是否有一种优雅的方法来实现这一点。
问题的更多细节是我需要使用允许主机的IP地址填充Postgres HBA配置文件。我无法使用其主机名,因为目标部署没有基于主机名的HBA所需的反向DNS。
我真的希望Postgres解析配置文件中的名称并将其与客户端的IP地址进行匹配,而不是反向查找客户端的IP地址,然后匹配主机名字符串。但这太过于期待,而且等待的时间太长。我现在需要一个解决方法,我想留在Ansible中,而不必将其卸载到外部脚本中。
感谢您阅读此内容!
答案 0 :(得分:10)
您可以为此创建一个查找插件:
Ansible 1.x:
import ansible.utils as utils
import ansible.errors as errors
import socket
class LookupModule(object):
def __init__(self, basedir=None, **kwargs):
self.basedir = basedir
def run(self, terms, inject=None, **kwargs):
if not isinstance(terms, basestring):
raise errors.AnsibleError("ip lookup expects a string (hostname)")
return [socket.gethostbyname(terms)]
Ansible 2.x:
import ansible.utils as utils
import ansible.errors as errors
from ansible.plugins.lookup import LookupBase
import socket
class LookupModule(LookupBase):
def __init__(self, basedir=None, **kwargs):
self.basedir = basedir
def run(self, terms, variables=None, **kwargs):
hostname = terms[0]
if not isinstance(hostname, basestring):
raise errors.AnsibleError("ip lookup expects a string (hostname)")
return [socket.gethostbyname(hostname)]
将此相对于您的剧本保存为lookup_plugins/ip.py
。
然后将其用作{{ lookup('ip', 'www.google.com') }}
答案 1 :(得分:2)
查找插件udondan提到的是"对"这样做的方法(尽管API更改为2.0,因此请注意,如果你采用这种方式,你会定位哪个版本)。如果您只是想要快速和肮脏的东西,以下应该有效:
- hosts: yourhosts
tasks:
- local_action: shell dig +short host-to-lookup-here.com
changed_when: false
register: dig_output
- set_fact:
looked_up_ips: "{{ dig_output.stdout_lines }}"
- debug: msg="found ip {{ item }}"
with_items: looked_up_ips
事实上,looking_up_ips将是一个可从模板中访问的映射IP列表,或者您需要在...中使用它的任何内容...
答案 2 :(得分:2)
为了完整起见,显然我们已经在盒子里装了一个挖掘查找插件,因为大约1.9可以很好地包装它(h / t Duncan Hutty):
https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/lookup/dig.py
答案 3 :(得分:1)
正如@nitzmahone所建议的,dig
插件可以完全用于此目的。例如:
- name: Simple A record (IPV4 address) lookup for example.com
debug: msg="{{ lookup('dig', 'example.com.')}}"
打印
MSG:
93.184.216.34
注意:您必须先安装dnspython
才能使其正常运行。您可以使用
pip install dnspython