如何解决Ansible跨角色传递VM IP时add_host动态库存的属性报错
问题原因
你遇到的'hcloud_server' has no attribute报错,核心原因是*groups.new_servers列表中存储的是你通过add_host传入的纯IP字符串,并不是创建VM时返回的带hcloud_server属性的对象*,你遍历该列表时拿到的item本身就是IP,不需要再加后缀属性访问。
解决方案
1. 修复IP打印的代码
直接输出遍历到的item即可:
- name: Display IPs debug: msg: "{{ item }}" with_items: "{{ groups.new_servers }}"
2. 给第二个角色传递公网IP完成delegate_to配置
根据你的使用场景,有两种常用实现方式:
场景1:第二个角色的所有任务都要在新创建的3台VM上逐台执行
直接在第二个角色对应的play中指定hosts: new_servers即可,Ansible会自动将任务下发到对应IP的VM上执行,不需要手动配置delegate_to:
- name: 执行VM初始化配置 hosts: new_servers gather_facts: yes roles: - 你的第二个角色名称
场景2:任务需要跑在其他节点,仅指定delegate_to为某台新VM的公网IP
取指定位置的VM IP
比如你要取第一台新VM的公网IP直接写索引即可:
- name: Apply private IP to master hcloud_server_network: api_token: "{{ hcloud_token }}" network: priv_network server: master.domain.tld ip: 10.1.0.2 state: present delegate_to: "{{ groups.new_servers[0] }}"
根据主机名匹配对应公网IP
如果你需要精准匹配master节点对应的公网IP,可以在add_host时额外绑定主机名变量:
- name: Add new servers to dynamic inventory add_host: name: "{{ item.hcloud_server.ipv4_address }}" groups: new_servers # 假设你创建VM时设置的名称就是inventory中的域名 server_hostname: "{{ item.hcloud_server.name }}" with_items: "{{ hcloud_info.results }}"
之后在任务中通过筛选拿到对应IP:
- name: Apply private IP to master hcloud_server_network: api_token: "{{ hcloud_token }}" network: priv_network server: master.domain.tld ip: 10.1.0.2 state: present delegate_to: "{{ hostvars | dict2items | selectattr('value.server_hostname', 'equalto', 'master.domain.tld') | map(attribute='key') | first }}"
注意事项
add_host生成的内存库存是全局生效的,同一个playbook内后续所有play、角色都可以直接访问groups.new_servers和对应的主机变量,不需要手动在角色之间传递参数。
内容的提问来源于stack exchange,提问作者Roberto Jobet
相关产品推荐
相关产品推荐

