You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用os_server模块与local连接时出现winrm send_input failed错误

问题分析与解决方案

你遇到的核心问题是同一个Play中混合了两种完全不同的连接模式——针对远程Windows主机的WinRM连接,和针对控制机的本地连接,而Ansible 2.4版本对任务级connection: local的处理逻辑存在优先级限制,导致执行os_server任务时仍然错误地尝试用WinRM连接目标主机(但这个任务根本不需要连接远程主机,它只是在控制机调用OpenStack API)。

正确的解决思路:拆分Playbook为两个独立Play

把实例创建和主机管理的任务分到两个不同的Play中,分别指定对应的目标主机和连接方式,彻底隔离两种连接逻辑,就不会再出现冲突了。

修改后的完整Playbook

# 第一个Play:在控制机执行OpenStack实例创建任务
- name: Provision Windows VM on OpenStack
  hosts: localhost
  connection: local
  gather_facts: false
  tasks:
    - name: Create Windows instance
      os_server:
        state: present
        region_name: "{{ os_region_name }}"
        auth: "{{ cloud.auth }}"
        name: "windows-{{ target_host }}"
        image: Windows 2012 R2 Datacenter
        key_name: mykey
        flavor: 1C-2GB-50GB
        floating_ips:
          - "{{ target_host }}"
        wait: yes  # 等待实例完全启动并分配IP,避免后续WinRM连接失败
        wait_timeout: 300

# 第二个Play:连接到已创建的Windows主机执行管理任务
- name: Manage Windows Instance
  hosts: target_hosts
  gather_facts: false
  tasks:
    - name: Verify WinRM connectivity
      win_ping:

配套的Inventory配置(示例为inventory.ini)

[target_hosts]
10.204.0.9

[localhost]
localhost ansible_connection=local

[all:vars]
cloud:
  auth:
    auth_url: https://cloud.internal:5000/v3/
    domain_name: Domain_01
    password: mypassword
    project_name: dev-project
    username: apiuser
os_region_name: Fra1
target_host: 10.204.0.9
ansible_user: Admin
ansible_port: 5986
ansible_password: myvmpassword
ansible_connection: winrm
ansible_winrm_server_cert_validation: ignore

执行命令

ansible-playbook site.yml --inventory=inventory.ini

为什么原来的写法会出错?

在你最初的Playbook中,整个Play的hosts是目标Windows主机,并且通过group_vars/all设置了ansible_connection: winrm——这相当于给整个Play默认了WinRM连接模式。虽然你给os_server任务加了connection: local,但在Ansible 2.4版本中,任务级的连接参数优先级低于Play级的全局配置,导致Ansible仍然尝试用WinRM连接目标主机来执行os_server任务,而这个任务只需要在控制机调用OpenStack API,完全不需要连接远程主机。

拆分Play后,第一个Play明确以localhost为目标,使用local连接,完全和远程主机的WinRM配置隔离;第二个Play专门针对Windows主机,使用预设的WinRM连接参数,两者互不干扰。

额外优化建议

  1. 如果不想维护单独的Inventory文件,也可以直接在命令行传递参数:
    ansible-playbook site.yml -i "localhost,10.204.0.9," -e "target_host=10.204.0.9"
    
  2. 考虑升级Ansible到2.5+版本,后续版本对任务级connection参数的处理逻辑更稳定,不过拆分Play的方案在所有Ansible版本中都是可靠的。

内容的提问来源于stack exchange,提问作者Jim Holden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:33:01