Ansible:在循环迭代时设置事实变量被覆盖

问题描述

我正在尝试根据条件从字典中创建一个列表。但是当我通过循环传递它时,循环的最后一个值会覆盖事实而不是创建列表

input.yml

execution:
 pre-deploy:
   
 post-deploy:
   shell-files:
      name: abc,def,gef
      type: deploy
      target_host:  server1
      check:  enabled
   xml-files:
      name: xyz,uvw
      type: deploy
      target_host:  server2
      check:  enabled
  shell-files:
      name: pqr
      type: migrate
      target_host:  server1
      check:  enabled

我的代码:

  Hosts: local
  vars_file:
     - input.yml
  vars:
    post_list:"{{ lookup( 'dict',operations.post-deploy,wantList=Ture ) }}"
  tasks:
  - set_fact:
       get_deploy_list: "{{ item.key }}: {{ item.value.name.split(',') | list }}"
       get_host_list: "{{ item.value.target_host }}"
    when: ( item.value.type == "deploy" and item.value.check == "enabled")
    loop:"{{ post_list | items2dict }}"
  
  - debug: msg="{{ get_deploy_list }}"

预期输出:

  debug:
    [ {
      shell-files: abc,shell-files: def,shell-files: ghi
       }
     {
      xml-files: xyz,xml-files: uvw
     }  ]

实际输出:

    [{
      xml-files: xyz,xml-files: uvw
     }  ]

列表的最后一个值覆盖了事实。

解决方法

这种情况与任何具有循环的编程语言相同:如果您不引用现有列表,那么它只是重复地重新分配一个变量,当循环退出时,您将最终获得世界的最后状态

我看到的传统解决方法是通过 | default| combine

- set_fact:
    get_deploy_list: >-
      {{ (get_deploy_list|default([]))
      | combine({item.key: item.value.name.split(',') | list})
      }}
  loop: "{{ post_list | items2dict }}"

尽管在我的剧本中,我认为该模式是一个错误,因为 jinja 完全能够使用其循环语法构建字典,而无需重复调用 set_fact(根据定义,这将打开到每个主机的连接多次盘点)

请注意,我没有通过该代码片段获得您确切的输出格式,因为您的剧本已经有太多错误;这个答案只是“为什么作业总是覆盖事实”

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...