我有一个 Python 应用程序,可以帮助我构建一个包含多个剧本的工作。如下所示,在作业执行时,ansible 将一一播放远程主机中的剧本:
工作:
这些剧本中的每一个都需要远程主机信息,例如操作系统发布主要版本(例如 RHEL7.9 为 7)。
如何一次性收集所需的主机信息并将其用于所有剧本,而不是每次运行时都收集。
我知道我可以在执行任务之前在每个剧本中设置 gather_facts: true
,但这有点慢,因为当我在上面的示例中运行所有 4 个剧本时,我必须总共收集 4 次事实.
我曾尝试在此 guide 之后使用 register
模块,但没有奏效,因为我无法使用 import_playbook
或 include
。
假设我的所有剧本都如下所示,并使用一些主机信息运行命令,我如何重用第一个剧本中收集的事实?
---
- hosts: "{{ host }}"
gather_facts: true
tasks:
- name: "Run command in remote server"
shell: {{some_ansible_fact_variable}}...
或
如何在第一个剧本中使用已注册的变量并在后续剧本中重复使用?
# playbook_01
---
- hosts: "{{ host }}"
gather_facts: false
tasks:
- name: "Getting facter os.release.major"
shell: facter os.release.major
register: OSMajorVersion
- name: "Run command in remote server"
shell: {{OSMajorVersion.stdout}}...
# playbook_02
---
- hosts: "{{ host }}"
gather_facts: false
tasks:
- name: "Run command in remote server"
shell: {{OSMajorVersion.stdout}}...
#编辑 每个剧本都被添加到一个 AnsibleTask 类中,并作为 python 进程执行和运行
class AnsibleTask(object):
def run(self):
split_cmd = shlex.split(self.cmd)
# Set log file
self.process_env['ANSIBLE_LOG_PATH'] = '{}/{}.log'.format(
config['ansible']['ansible_logs_dir'],
self.props['hostname'])
logger.info("running command: %s" % self.cmd)
p = subprocess.Popen(
split_cmd,
cwd=self.playbooks_path,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=self.process_env)
output, error = p.communicate()
p.wait()
def execute(self):
self.process_env['ANSIBLE_STDOUT_CALLBACK'] = 'json'
(ret, out, err) = self.run()
host = self.props['host']
try:
out_dict = json.loads(out)
except ValueError as e:
logger.error('error parsing json: %s' % str(e))
raise AnsibleTaskError(AnsibleTaskError.E_PARSE_JSON)
if ret > 0:
...
else:
return out_dict