1

这与我尝试过的以下链接问题以及来自larsks的答案直接相关,但它不起作用:“如何循环遍历库存并在 ansible 中分配值

我试图做同样的事情,并且我测试了重命名由 Ansible 控制的 2 个 VM,但是当我尝试运行 Playbook ( ansible-playbook -i hosts test_iterate_win.yml -vvv) 时出现类似下一个的错误,我会说它实际上是按名称 ' System.Object[]' 代替例如,wCloud2

failed: [oldVM2] (item=[u'oldVM2', u'wCloud2']) => {
    "ansible_loop_var": "item", 
    "changed": false, 
    "item": [
        "oldVM2", 
        "wCloud2"
    ], 
    "msg": "Failed to rename computer to 'System.Object[]': Skip computer 'oldVM2' with new name 'System.Object[]' because the new name is not valid. The new computer name entered is not properly formatted. Standard names may contain letters (a-z, A-Z), numbers (0-9), and hyphens (-), but no spaces or periods (.). The name may not consist entirely of digits, and may not be longer than 63 characters.", 
    "old_name": "oldVM2", 
    "reboot_required": false
}

在我的库存文件中:

[windows]
oldVM1 ansible_host=192.168.122.6
oldVM2 ansible_host=192.168.122.139

我的剧本:

---
- hosts: windows
  gather_facts: false
  vars:
    hostnames:
      - wCloud1
      - wCloud2
  tasks:
    - name: change hostname
      win_hostname:
        name: "{{ item }}"
      loop: "{{ groups.windows|zip(hostnames)|list }}"

我做错了什么?

4

1 回答 1

1

TL;博士;

我会说,当可能有一个简单的解决方案时,你正在为自己制作这个超级复杂的东西。

只需在清单中使用主机变量即可轻松解决您的任务:

[windows]
oldVM1 ansible_host=192.168.122.6 newName=wCloud1
oldVM2 ansible_host=192.168.122.139 newName=wCloud2

那么你的剧本就很简单了:

---
- hosts: windows
  gather_facts: false

  tasks:
    - name: change hostname
      win_hostname:
        name: "{{ newName }}"

现在,我想说的是,您的尝试没有成功的原因实际上是您对 Ansible 在多个主机上运行的任务有一点误解。

也就是说,当 Ansible 有一个任务(或一组任务)要在多个主机上运行时,需要定义一个且只有一个任务。

基于上述任务,当库存主机实际上是一组主机时,该任务将在host 1,然后host 2,... 上运行,直到host n,然后再运行下一个任务(如果有)。

注意:仍然,不要认为这是理所当然的,已经知道 Ansible 不会遵循清单中主机的定义顺序的问题(请参阅:https ://github.com/ansible/ansible/issues/34861 ),所以它最终可能是host 2, host n, host 1.

考虑这个带有上述清单的剧本:

---
- hosts: windows
  gather_facts: false

  tasks:
    - name: change hostname
      debug:
        msg: '{{ newName }}'

    - name: another task
      debug:
        msg: 'some example'

它的输出将是

$ansible-playbook test.yml

PLAY [windows] *****************************************************************

TASK [change hostname] *********************************************************
ok: [oldVM1] => {
    "msg": "wCloud1"
}
ok: [oldVM2] => {
    "msg": "wCloud2"
}

TASK [another task] ************************************************************
ok: [oldVM1] => {
    "msg": "some example"
}
ok: [oldVM2] => {
    "msg": "some example"
}

PLAY RECAP *********************************************************************
oldVM1                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
oldVM2                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

您可以清楚地看到第一个任务(命名,更改主机名)在 Ansible 可以继续执行游戏中的其他任务之前在所有主机上处理。


实际上,您的System.Object[]错误意味着您正在尝试在win_hostname模块的中提供一个对象(即列表),该对象name试图以某种方式将其转换为字符串并且严重失败,因为这是您的item变量包含的列表:

[
    "oldVM1",
    "wCloud1"
]
于 2019-09-18T20:31:36.463 回答