Ansible如何将sparkmaster.yml中的private_dns_name变量传递到sparkslaves.yml使用
Ansible跨playbook共享Spark master私有DNS变量的解决方案
问题本质
你在sparkmaster.yml中通过set_fact存储的private_dns_name是绑定到执行任务的主机(此处为localhost)的临时主机事实,默认仅在当前play运行上下文有效,跨独立playbook调用时无法直接读取。
可行方案
方案1:同一次运行下顺序调用两个playbook(最推荐)
如果两个playbook可以在同一次ansible执行流程中运行,写一个总入口playbook统一调用,直接通过hostvars读取变量即可:
- 新建总入口
site.yml:
- import_playbook: sparkmaster.yml - import_playbook: sparkslaves.yml
- 修正
sparkslaves.yml的变量引用,直接从localhost的主机事实中取值:
- name: Add scripts/start-slave.sh ansible.builtin.blockinfile: path: /home/ubuntu/scripts/start-slave.sh create: yes block: | #/bin/sh SPARK_MASTER_URL=spark://{{ hostvars['localhost']['private_dns_name'] }}:7077 insertbefore: BOF
运行时直接执行ansible-playbook site.yml即可。
方案2:独立运行两个playbook,通过中间文件传递变量
如果两个playbook需要分开执行,在sparkmaster.yml末尾添加任务将变量写入持久化文件,在sparkslaves.yml开头读取该文件即可:
- 在
sparkmaster.yml的play末尾添加写入变量的任务:
- name: 保存Spark master私有DNS到变量文件 copy: content: "private_dns_name: {{ private_dns_name }}" dest: ./spark_master_vars.yml delegate_to: localhost
- 在
sparkslaves.yml的play开头添加读取变量的任务:
- name: 读取Spark master配置变量 include_vars: file: ./spark_master_vars.yml
原来的start-slave.sh生成逻辑不需要修改,先运行sparkmaster.yml再运行sparkslaves.yml即可。
方案3:开启Ansible事实持久化缓存
修改ansible配置开启事实缓存,跨playbook运行时自动读取缓存中的变量:
- 修改
ansible.cfg添加以下配置:
[defaults] fact_caching = jsonfile fact_caching_connection = ./ansible_fact_cache fact_caching_timeout = 86400 # 缓存有效期1天,可按需调整
- 创建缓存目录:
mkdir ./ansible_fact_cache sparkslaves.yml中变量引用和方案1一致,用hostvars['localhost']['private_dns_name']即可,两个playbook可以独立分开运行。
原有代码优化建议
- 你当前
sparkmaster.yml中Set private ipv4 dns任务的set_fact缩进错误,需要和上层任务名对齐 - 如果仅启动单台Spark master实例,不需要用loop遍历实例,直接取第一个实例的值更稳妥,避免多实例场景下变量被覆盖:
- name: Set private ipv4 dns set_fact: private_dns_name: "{{ ec2.instances[0].private_dns_name }}"
内容的提问来源于stack exchange,提问作者Prats
相关产品推荐
相关产品推荐

