Vagrant+Ansible场景下,如何获取vm1的IP配置到其他两台VM?
如何在Ansible中获取Vagrant创建的vm1的IP并配置到其他机器?
问题描述
我通过Vagrant创建了3台虚拟机,并用Ansible进行管理(清单由Vagrant自动生成)。现在需要把vm1的IP地址配置到vm2和vm3的配置文件中,但尝试使用hostvars['vm1']变量时,无法获取到vm1的IP地址。
我的Vagrant配置文件如下:
Vagrant.configure("2") do |config| config.vm.network "private_network", type: "dhcp" config.vm.provider "virtualbox" do |v| v.memory = 512 end config.vm.synced_folder ".", "/vagrant" config.vm.box_check_update = false config.vm.define "vm1" do |vm1| vm1.vm.box = "hashicorp/bionic64" end config.vm.define "vm2" do |vm2| vm2.vm.box = "hashicorp/bionic64" end config.vm.define "vm3" do |vm3| vm3.vm.box = "hashicorp/bionic64" end config.vm.provision "ansible" do |ansible| ansible.playbook = "playbook.yml" #ansible.ask_become_pass = true ansible.groups = { "node_master" => ["vm1"], "node_replicas" => ["vm2", "vm3"], "node:children" => ["node_master", "node_replicas"] } end end
解决方案
这个问题本质是Ansible默认并行执行任务导致的:当vm2和vm3的配置任务启动时,Ansible可能还没完成vm1的facts(包括IP地址这类主机信息)收集工作,所以hostvars里还没有vm1的相关数据。下面提供几种靠谱的解决方法:
方法1:先全量收集所有主机的facts,再执行配置任务
在你的playbook开头添加一个专门收集所有主机facts的play,确保所有主机的信息都被提前获取:
# playbook.yml - name: 提前收集所有主机的系统信息(facts) hosts: all gather_facts: true # 这里不需要额外任务,只需要触发facts收集 tasks: [] - name: 配置vm2和vm3使用vm1的IP hosts: node_replicas tasks: - name: 将vm1的IP写入目标配置文件 lineinfile: path: /etc/your-app/config.conf # 替换成你的实际配置文件路径 line: "master_server_ip = {{ hostvars['vm1']['ansible_default_ipv4']['address'] }}" state: present create: true # 如果文件不存在就创建
方法2:针对vm1单独收集facts(更轻量)
如果不想收集所有主机的facts,可以在配置vm2/3的任务前,专门收集vm1的信息:
# playbook.yml - name: 配置vm2和vm3使用vm1的IP hosts: node_replicas tasks: - name: 手动收集vm1的系统信息 setup: delegate_to: vm1 # 任务在vm1上执行 delegate_facts: true # 把收集到的facts关联到vm1的hostvars中 - name: 将vm1的IP写入配置文件 lineinfile: path: /etc/your-app/config.conf line: "master_server_ip = {{ hostvars['vm1']['ansible_default_ipv4']['address'] }}" state: present
小提示:确认IP变量的正确性
不同的Vagrant box可能使用不同的网络接口名称,如果你发现ansible_default_ipv4.address不对,可以先在本地执行vagrant ssh vm1 -c "ip addr"查看实际的私有网络接口,或者用Ansible命令查看vm1的所有facts:
vagrant ansible vm1 -m setup
找到对应私有网络的IP变量(比如ansible_eth1.address),替换到playbook中即可。
内容的提问来源于stack exchange,提问作者Yashar
相关产品推荐
相关产品推荐

