如何在import_playbook时跳过已存在变量的vars_prompt?
解决Ansible父子剧本vars_prompt重复输入的问题
核心思路
子剧本的vars_prompt默认会强制触发输入,不管变量是否已存在。只要给子剧本的prompt加上条件判断,仅当变量未定义时才弹出输入,就能实现父剧本一次输入后,子剧本自动跳过提示。
具体实现步骤
1. 父剧本配置(针对localhost)
父剧本通过vars_prompt获取账号密码,直接导入子剧本即可,无需额外set_fact传递变量——Ansible会自动将父剧本的变量传递给导入的子剧本。
示例父剧本main.yml:
- name: 父剧本 - 统一执行交换机和防火墙基础任务 hosts: localhost gather_facts: no vars_prompt: - name: ansible_user prompt: "请输入设备账号" private: no - name: ansible_password prompt: "请输入设备密码" private: yes tasks: - name: 导入交换机基础任务剧本 import_playbook: switch_base.yml - name: 导入防火墙基础任务剧本 import_playbook: firewall_base.yml
2. 子剧本配置(交换机/防火墙)
修改子剧本的vars_prompt,给每个prompt添加when条件,判断变量是否已定义:
子1剧本switch_base.yml(多台交换机):
- name: 交换机基础任务 hosts: switches gather_facts: no vars_prompt: - name: ansible_user prompt: "请输入交换机账号" private: no when: ansible_user is not defined - name: ansible_password prompt: "请输入交换机密码" private: yes when: ansible_password is not defined tasks: - name: 执行交换机基础配置任务 # 这里写你的交换机任务,比如配置VLAN、接口等 debug: msg: "在交换机{{ inventory_hostname }}上执行基础任务,使用账号{{ ansible_user }}"
子2剧本firewall_base.yml(多台防火墙):
- name: 防火墙基础任务 hosts: firewalls gather_facts: no vars_prompt: - name: ansible_user prompt: "请输入防火墙账号" private: no when: ansible_user is not defined - name: ansible_password prompt: "请输入防火墙密码" private: yes when: ansible_password is not defined tasks: - name: 执行防火墙基础配置任务 # 这里写你的防火墙任务,比如配置安全策略、NAT等 debug: msg: "在防火墙{{ inventory_hostname }}上执行基础任务,使用账号{{ ansible_user }}"
场景验证
- 场景1:执行父剧本
ansible-playbook main.yml,仅需一次输入账号密码,子剧本会自动跳过vars_prompt,直接执行所有任务。 - 场景2:直接执行子1剧本
ansible-playbook switch_base.yml,此时ansible_user和ansible_password未定义,会弹出输入提示,完成交换机任务。 - 场景3:直接执行子2剧本
ansible-playbook firewall_base.yml,同理弹出输入提示,完成防火墙任务。
关键说明
- 确保父剧本和子剧本使用的变量名完全一致(这里是
ansible_user和ansible_password),Ansible才能自动传递变量。 vars_prompt的when条件是Ansible 2.2+支持的特性,确保你的Ansible版本符合要求。
内容的提问来源于stack exchange,提问作者Febry Citra Prawira Negara
相关产品推荐
相关产品推荐

