Ansible收集事实前从HashiCorp Vault获取变量的实现方法
方案1:直接在变量加载层用hashi_vault lookup拉取凭证(零playbook修改,推荐)
你之前自定义角色的问题在于角色属于任务执行阶段,运行时机晚于默认的事实收集步骤,所以拿不到变量。Ansible在执行任何连接操作(包括gather_facts阶段的主机连接)前,会先完成所有静态变量、lookup插件的解析,直接把ansible_ssh_pass的定义挪到group_vars/、host_vars/这类全局/主机层级的变量文件里,用官方hashi_vault lookup拉取HashiCorp Vault里的值即可,完全不需要关闭gather_facts,也不需要修改现有playbook、角色,更不用手动调用setup模块。
示例配置(直接写在对应主机的host_vars文件,或group_vars/all.yml做全局配置即可):
# 适配KV v2引擎的写法,认证参数优先读控制节点环境变量,避免硬编码 ansible_ssh_pass: "{{ lookup('hashi_vault', 'secret=secret/data/ansible/ssh_creds/{{ inventory_hostname }}:ssh_pass', url=lookup('env', 'VAULT_ADDR'), auth_method='token', token=lookup('env', 'VAULT_TOKEN') ) }}"
如果用AppRole、JWT等其他认证方式,直接在lookup参数里传对应认证字段即可,官方lookup插件原生支持所有HashiCorp Vault认证方式。
前置依赖:控制节点安装hvac库即可,执行pip install hvac。
方案2:保留现有角色逻辑,通过全局pre_tasks前置执行
如果你已经写好的角色里除了拉取ansible_ssh_pass还有其他自定义逻辑,不想重构,可以利用Ansible play的执行顺序特性:pre_tasks的执行时机早于默认gather_facts。
不需要逐个修改现有playbook,只需要改造项目顶层入口playbook:
- 新建顶层入口文件(比如
main.yml),第一个play针对所有主机,在pre_tasks里调用你写好的凭证拉取角色,注意拉取操作要委托给控制节点执行:
- name: 前置拉取连接凭证 hosts: all gather_facts: no pre_tasks: - name: 执行凭证拉取角色 include_role: name: your_vault_cred_role delegate_to: localhost run_once: false
- 在这个play后面直接import你所有原有的业务playbook即可:
- import_playbook: original_site.yml
后续统一用ansible-playbook main.yml执行即可,原有业务playbook不需要做任何修改,gather_facts会在pre_tasks拉完凭证后正常执行。
注意事项
- 所有拉取Vault的操作都要在控制节点执行(加
delegate_to: localhost),不要在目标节点执行,避免目标节点需要额外依赖。 - 不要把Vault认证凭证硬编码在变量文件里,优先通过环境变量、本地配置文件注入控制节点,降低泄露风险。
- 方案1的变量解析时机早于所有任务执行,稳定性最高,是Ansible官方推荐的第三方密钥存储集成方式。
内容的提问来源于stack exchange,提问作者Hella

