如何在 Ansible 中循环遍历库存并分配价值

How to loop through inventory and assign value in Ansible

我的 Ansible 剧本中有一个任务,我想遍历我拥有的组中的每个主机,并且我想为每个主机分配一个名称,该名称来自我在变量文件夹。

我已经熟悉通过编写循环遍历清单:“{{ groups['mygroup'] }}”并且我有一个主机名列表,我想在 [=25] 中分配每个 IP =] 在主机文件中。

# In tasks file - roles/company/tasks/main.yml
- name: change hostname
  win_hostname:
    name: "{{ item }}"
  loop: "{{ hostname }}"
  register: res

# In the Inventory file
[company]
10.0.10.128
10.0.10.166
10.0.10.200

# In vars - roles/company/vars/main.yml
hostname:
  - GL-WKS-18
  - GL-WKS-19
  - GL-WKS-20

# site.yml file located under /etc/ansible
- hosts: company
  roles:
    - common
    - company #This is where the loop exists mentioned above.

# Command to run playbook
ansible-playbook -i hosts company.yml

我似乎已经记下或了解了各个部分,但是我如何结合对清单组中的主机进行迭代并分配我已经在已创建的列表(在角色 vars 文件夹中)中的名称?

更新 上述任务已更新以反映答案中提到的更改:

- name: change hostname
  win_hostname:
    name: "{{ item.1 }}"
  loop: {{ groups.company|zip(hostname)|list }}"
  register: res

但是我得到的输出是不正确的,这不应该 运行 9 次,而应该只有 3 次,清单中 [company] 组中的每个 IP 一次。此外,列表中只有三个主机名需要分配给清单中的每个主机 sheet。

changed: [10.0.10.128] => (item=[u'10.0.10.128', u'GL-WKS-18'])
changed: [10.0.10.166] => (item=[u'10.0.10.128', u'GL-WKS-18'])
changed: [10.0.10.200] => (item=[u'10.0.10.128', u'GL-WKS-18'])
changed: [10.0.10.128] => (item=[u'10.0.10.166', u'GL-WKS-19'])
changed: [10.0.10.166] => (item=[u'10.0.10.166', u'GL-WKS-19'])
changed: [10.0.10.200] => (item=[u'10.0.10.166', u'GL-WKS-19'])
ok: [10.0.10.128] => (item=[u'10.0.10.200', u'GL-WKS-20'])
ok: [10.0.10.166] => (item=[u'10.0.10.200', u'GL-WKS-20'])
ok: [10.0.10.200] => (item=[u'10.0.10.200', u'GL-WKS-20'])

每当我对 Ansible 中的循环有疑问时,我也会去访问 Loops documentation. It sounds like you want to iterate over two lists in parallel, pairing an item from the list of hosts in your inventory with an item from the list of hostnames. In previous versions of Ansible that would suggest using the with_together loop, while with more recent versions of Ansible that suggests the zip filter (there's an example in the docs here)。

为了在您的用例中演示这一点,我从一个包含三个主机的清单文件开始:

[mygroup]
hostA ansible_host=localhost
hostB ansible_host=localhost
hostC ansible_host=localhost

以及以下剧本:

---
- hosts: all

- hosts: localhost
  gather_facts: false
  vars:
    hostnames:
      - hostname01
      - hostname02
      - hostname03
  tasks:
    - name: change hostname
      debug:
        msg:
          win_hostname:
            name: "{{ item }}"
      loop: "{{ groups.mygroup|zip(hostnames)|list }}"

这里我使用的是 debug 任务,而不是 运行 win_hostname 任务。 运行的输出:

ansible-playbook -i hosts playbook.yml

看起来像:

TASK [change hostname] ********************************************************************************************************************************
ok: [localhost] => (item=[u'hostA', u'hostname01']) => {
    "msg": {
        "win_hostname": {
            "name": [
                "hostA", 
                "hostname01"
            ]
        }
    }
}
ok: [localhost] => (item=[u'hostB', u'hostname02']) => {
    "msg": {
        "win_hostname": {
            "name": [
                "hostB", 
                "hostname02"
            ]
        }
    }
}
ok: [localhost] => (item=[u'hostC', u'hostname03']) => {
    "msg": {
        "win_hostname": {
            "name": [
                "hostC", 
                "hostname03"
            ]
        }
    }
}

如您所见,它将清单中的每个主机与 hostnames 列表中的主机名配对。

更新

根据你提供的额外信息,我认为你 其实想要的是这样的:

    - name: change hostname
      win_hostname:
        name: "{{ hostnames[group.company.index(inventory_hostname) }}"

这会将 hostname 中的一个值分配给您的每个主机 存货。我们正在查找当前的位置 inventory_hostname 在你的组中,然后用它来索引 hostnames 列表。