首页 > 解决方案 > Ansible:如何在下一个任务中循环动态主机的注册输出

问题描述

我正在努力为results.containers动态清单中的所有主机循环注册。

这是代码。

$cat collect.yaml 
---
- hosts: "{{ env }}"
  become: True
  tasks:
    - name: Get dockerinfo
        docker_host_info:
        containers: yes
      register: result
  
    - name: Debug dockerInfo
      debug:
        var: result.containers 

    - name: dynamic grouping
      add_host:
        name: "{{ item[0] }}"  
        groups: "{{ item[1].Image | regex_replace('.*?/(.*?):.*', '\\1') }}"
        container_name: '{{ item[1].Names[0] | regex_replace("^/", "") }}'
      with_nested: 
        -  "{{ ansible_play_batch }}"
        -  "{{ result.containers }}"

这里是result.containers输出。

TASK [Debug dockerInfo]
ok: [vm1.nodekite.com] => {
"result.containers": [
{
    "Image": "ca.docker/webproxy:1.0.0",
    "Names": [
           "/customer1"
     ],
},
{
    "Image": "docker.local/egacustomer:1.0.1",
    "Names": [
           "/webproxy"
     ],
},
]}
ok: [vm2.nodekite.com ] => {
"result.containers": [
{
    "Image": "ca.docker/webproxy:1.0.0",
    "Names": [
           "/webproxyui"
     ],
},
{
    "Image": "cna-docker-local/lega-customer:1.0.1",
    "Names": [
           "/webproxy"
    ],
},
]}
ok: [vm3.nodekite.com ] => {
"result.containers": [
{
    "Image": "ca.docker/webproxy:1.0.0",
    "Names": [
           "/webproxy"
     ],
},
{
    "Image": "local.docker/saga-customer:1.0.1",
    "Names": [
           "/customerr
     ],
},
]}

现在item[1].Imageitem[1].Names[0]仅取自第一个主机的 (vm1.nodekite.com) results.containers 输出。我想为每个主机循环。这样,我可以为所有主机及其各自的容器创建动态组。使用我的代码,主机 vm1、vm2、vm3 都指代,vm1.nodekite.com's result.containers但我希望主机指代它们各自的容器。任何帮助将不胜感激。

我已更新动态分组任务输出以进行澄清。

changed: [vm1.nodekite.com] => {
"add_host": {
    "groups": [
        "webproxy"
    ],
    "host_name": "vm1.nodekite.com",
    "host_vars": {
    "container_name": "customer1" }
},
changed: [vm1.nodekite.com] => {
"add_host": {
    "groups": [
        "egacustomer"
    ],
    "host_name": "vm1.nodekite.com",
    "host_vars": {
    "container_name": "webproxy" }
},
changed: [vm2.nodekite.com] => {
"add_host": {
    "groups": [
        "webproxy"            >> this should be webproxy
    ],
    "host_name": "vm2.nodekite.com",
    "host_vars": {
    "container_name": "customer1" }     >> this should be webproxyui
},
changed: [vm2.nodekite.com] => {
"add_host": {
    "groups": [
        "egacustomer"           >> this should be lega-customer
    ],
    "host_name": "vm2.nodekite.com",
    "host_vars": {
    "container_name": "webproxy" }    >>  this should be webproxy
},

如果您看到 vm2 仍然指的是 vm1 的 result.containers 输出。

当我尝试这个...我得到项目未定义错误。

   - name: adding it to groups using images
    add_host:
      name: "{{ item[0] }}"
      groups: "{{ item[1].Image | regex_replace('.*?/(.*?):.*', '\\1') }}"
      container_name: '{{ item[1].Names[0] | regex_replace("^/", "") }}'
    loop:
      -  "{{ ansible_play_batch }}"
      -  "{{ myresult.containers }}"
    vars:
      myresult: "{{ hostvars[item].result }}"
    run_once: true

标签: loopsansiblenested-loopsansible-2.x

解决方案


问:“宿主应参考各自的容器。”

答:使用主机变量。例如

    - name: dynamic grouping
      debug:
        msg:
        - "name: {{ item }}"
        - "groups: {{ my_result.containers|
                      map(attribute='Image')|
                      map('regex_replace', '.*?/(.*?):.*', '\\1')|
                      list }}"
        - "container_names: {{ my_result.containers|
                      map(attribute='Names')|
                      map('regex_replace', '\/', '')|
                      list }}"
      loop: "{{ ansible_play_batch }}"
      vars:
        my_result: "{{ hostvars[item].result }}"
      run_once: true

ok: [vm1.nodekite.com] => (item=vm1.nodekite.com) => 
  msg:
  - 'name: vm1.nodekite.com'
  - 'groups: [''webproxy'', ''egacustomer'']'
  - 'container_names: ["[''customer1'']", "[''webproxy'']"]'
ok: [vm1.nodekite.com] => (item=vm2.nodekite.com) => 
  msg:
  - 'name: vm2.nodekite.com'
  - 'groups: [''webproxy'', ''lega-customer'']'
  - 'container_names: ["[''webproxyui'']", "[''webproxy'']"]'
ok: [vm1.nodekite.com] => (item=vm3.nodekite.com) => 
  msg:
  - 'name: vm3.nodekite.com'
  - 'groups: [''webproxy'', ''saga-customer'']'
  - 'container_names: ["[''webproxy'']", "[''customer'']"]'

(请随意根据您的需要调整代码。)


推荐阅读