解决方案 1:本地事实
此解决方案是 IMO 最简单的解决方案,但需要在每个目标服务器上放置一个文件。
假设您将以下可执行文件放入/etc/ansible/facts.d/kafka.fact
. 这只是一个虚拟示例,请根据您的确切需求进行调整。我正在使用 jq 输出正确的 json 字符串。echo
如果您信任关键内容不会导致问题,您可以直接使用。你也可以使用你喜欢的任何其他可执行文件(python、ruby、perl...),只要你输出一个 json 结构
#!/bin/bash
# replace here with some logic to read the value you need.
# I'll use a static value for this example
PARSED_KEY="I'm a key that should be parsed dynamically"
# echo the json result using jq
echo $(
jq -n \
--arg pk "$PARSED_KEY" \
'{masterkey: $pk}'
)
完成此操作后,您可以看到事实可用于给定主机。我将在这里仅演示 localhost ,但这将适用于具有此本地事实脚本的任何主机:
$ ansible localhost -m setup -a filter=ansible_local
localhost | SUCCESS => {
"ansible_facts": {
"ansible_local": {
"kafka": {
"masterkey": "I'm a key that should be parsed dynamically"
}
}
},
"changed": false
}
您现在可以在任何需要的地方使用这个事实。请注意,您当然必须收集事实才能使该值可用。在您的情况下,我们可以使用以下剧本进行测试:
---
- hosts: localhost
environment:
CONFLUENT_KEY: "{{ ansible_local.kafka.masterkey | default ('empty') }}"
tasks:
- name: echo our env var
command: echo $CONFLUENT_KEY
register: echo
- name: show the result
debug:
msg: "Our env is: {{ echo.stdout }}"
这使
PLAY [localhost] ***************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************
ok: [localhost]
TASK [echo our env var] ********************************************************************************************************************************************************
changed: [localhost]
TASK [show the result] *********************************************************************************************************************************************************
ok: [localhost] => {
"msg": "Our env is: I'm a key that should be parsed dynamically"
}
PLAY RECAP *********************************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
解决方案 2:自定义事实模块
此解决方案稍微复杂一些,但从长远来看可能具有更好的管理能力,并且不需要将文件放置在目标服务器上。
为了尽可能简单明了,我将演示事实模块放在library
与我的剧本相邻的文件夹中。将这样的模块放在集合或角色中对于生产项目来说是可取的,但超出了这个(已经很长的)答案。要获取有关所有这些主题的更多信息,您可以阅读(非详尽的参考文献列表):
创建一个library/kafka_facts.py
文件。您将不得不适应您的具体情况。在这种情况下,我决定将密钥放在一行中,/tmp/keyfile.txt
并在我的模块中对其进行硬编码。请注意,如果文件不存在,则不会返回事实。我按照上述文档链接中的示例中的建议添加了所有文档字符串。
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r'''
---
module: kafka_facts
short_description: This is a test module for example
version_added: "1.0.0"
description: This is a test module for example to answer a question on StackOverflow.
author:
- Olivier Clavel (@zeitounator)
'''
EXAMPLES = r'''
- name: Return ansible_facts
kafka_facts:
'''
RETURN = r'''
ansible_facts:
description: Kafka facts to add to ansible_facts.
returned: always
type: dict
contains:
kafka_masterkey:
description: Masterkey present on server.
type: str
returned: when /tmp/keyfile.txt exists on server
sample: 'f18bba7f-caf6-4897-95be-c7d3cc66f98a'
'''
from ansible.module_utils.basic import AnsibleModule
def run_module():
module_args = dict()
# Initialize result dict
result = dict(
changed=False,
ansible_facts=dict(),
)
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True
)
if module.check_mode:
module.exit_json(**result)
keyfile = "/tmp/keyfile.txt"
try:
with open(keyfile) as f:
result['ansible_facts'] = {
'kafka_masterkey': f.read(),
}
except FileNotFoundError:
pass
module.exit_json(**result)
def main():
run_module()
if __name__ == '__main__':
main()
与我之前的解决方案一样,以下演示将仅在 localhost 上完成,但可以在任何目标服务器上运行。
首先我们在预期的文件中创建一个密钥
echo $(uuidgen) > /tmp/keyfile.txt
我们现在可以使用该模块,如下面的剧本所示:
---
- name: Use custom facts
hosts: localhost
gather_facts: false
environment:
CONFLUENT_KEY: "{{ ansible_facts.kafka_masterkey | default('N/A') }}"
tasks:
- name: echo the env var
command: echo $CONFLUENT_KEY
register: echo_before
changed_when: false
- name: show our var is empty for now
debug:
msg: "CONFLUENT_KEY was returned as: {{ echo_before.stdout }}"
- name: Gather our custom facts related to kafka
kafka_facts:
- name: Echo the env var
command: echo $CONFLUENT_KEY
register: echo_after
changed_when: false
- name: show our var is empty for now
debug:
msg: "CONFLUENT_KEY was returned as: {{ echo_after.stdout }}"
这使:
PLAY [Use custom facts] ****************************************************************************************************************************************************************************************************************
TASK [echo the env var] ****************************************************************************************************************************************************************************************************************
ok: [localhost]
TASK [show our var is empty for now] ***************************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "CONFLUENT_KEY was returned as: N/A"
}
TASK [Gather our custom facts related to kafka] ****************************************************************************************************************************************************************************************
ok: [localhost]
TASK [Echo the env var] ****************************************************************************************************************************************************************************************************************
ok: [localhost]
TASK [show our var now has a value (if the file exists)] *******************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "CONFLUENT_KEY was returned as: d8fc525e-3fa9-4401-aca3-19ac915e5c0d"
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0