ansible - 如何在 Ansible 中循环库存并分配值(value)

标签 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

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

更新 上述任务已更新,以反射(reflect)答案中提到的更改:

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

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

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 。听起来您想要并行迭代两个列表,将 list 中主机列表中的项目与主机名列表中的项目配对。在 Ansible 的早期版本中,建议使用 with_together 循环,而在较新版本的 Ansible 中,建议使用 zip 过滤器(文档 here 中有一个示例) .

为了针对您的用例演示这一点,我从具有三个主机的 list 文件开始:

[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"
            ]
        }
    }
}

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

更新

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

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

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

关于ansible - 如何在 Ansible 中循环库存并分配值(value),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53860671/

相关文章:

jenkins - Jenkins Ansible插件中的Ansible,忽略SSH配置

java - Spring Boot特定配置文件yaml未加载

ansible - 循环遍历 Ansible playbook 嵌套数组

Ansible 嵌套 host_vars 文件夹

json - Ansible 中的自定义动态库存脚本/插件

python - Ansible:从字符串构建 Mac 地址

ansible - 从列表中排除 AnsibleUndefined

grails - 使用SpringBoot的Grails应用程序针对不同的环境使用不同的yml文件

ansible - 引用 Ansible 库存条目的 value 部分

Ansible:在剧本中指定库存文件