如何在Ansible中遍历库存和分配价值

时间:2018-12-19 23:41:31

标签: ansible yaml ansible-inventory

我的Ansible剧本中有一个任务,我想遍历我拥有的组中的每个主机,并且我想为每个主机从我在vars文件夹中创建的主机名列表中分配一个名称。

我熟悉通过编写循环:“ {{groups ['mygroup']}}”来遍历清单,并且我有一个主机名列表,我想在主机文件中为“ mygroup”中的每个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一次。另外,列表中只有三个主机名需要分配给清单工作表中的每个主机。

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'])

1 个答案:

答案 0 :(得分:1)

每当我有关于在Ansible中循环播放的问题时,我也会去访问Loops documentation。听起来您想并行地遍历两个列表,将清单中主机列表中的一项与主机名列表中的一项配对。在先前版本的Ansible中,建议使用with_together循环,而在较新版本的Ansible中,建议使用zip过滤器(文档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列表。