如何在 Ansible 中遍历库存并分配价值 [英] How to loop through inventory and assign value in Ansible

查看:23
本文介绍了如何在 Ansible 中遍历库存并分配价值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a task in my Ansible playbook that I'm wanting iterate over each host in the group that I have and for each host I would like to assign a name from the hostname list that I've created in the vars folder.

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

I'm familiar with looping through inventory already by writing loop: "{{ groups['mygroup'] }}" and I have a list of hostnames I would like to assign each IP in 'mygroup' within the host file.

# 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 文件夹中)中的名称?

I seem to have the individual pieces down or know about it, but how can I combine iterating over hosts from an inventory group and assign names that I have in an already created list (in roles vars folder) already?

更新上面提到的任务已经更新,以反映回答中提到的变化:

UPDATE the task mentioned above has been updated to reflect changes mentioned in answer:

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

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

However the output I'm getting is incorrect, this should not run 9 times rather only three times, once per IP in the [company] group in the inventory. Also there are only three hostnames in a list that need to be assigned to each of the hosts in the inventory 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 中的循环有疑问时,我也会访问 循环文档.听起来您想并行迭代两个列表,将清单中主机列表中的一个项目与主机名列表中的一个项目配对.在 Ansible 的早期版本中,建议使用 with_together 循环,而在较新版本的 Ansible 中,建议使用 zip 过滤器(文档中有一个示例 此处).

Whenever I have a question about looping in Ansible I also go visit the 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).

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

To demonstrate this for your use case, I started with an inventory file that has three hosts:

[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 任务.运行输出:

Here I'm using a debug task instead of actually running the win_hostname task. The output of running:

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 列表中的主机名配对.

As you can see, it's paired each host from the inventory with a hostname from the hostnames list.

更新

根据您提供的其他信息,我认为您其实想要的是这个:

Based on the additional information you've provided, I think what you actually want is this:

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

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

This will assign one value from hostname to each host in your inventory. We're looking up the position of the current inventory_hostname in your group, and then using that to index into the hostnames list.

这篇关于如何在 Ansible 中遍历库存并分配价值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆