错误是:“字典对象”没有属性“ ansible_facts”

Chr*_*_vr 0 ansible ansible-playbook

我正在遍历yml文件并过滤并将那些微服务元数据保留在传递的命令行参数中的列表中

ansible-playbook -i inventory/inventory sp-deployer.yml --ask-vault-pass --extra-vars '{"microservices_list":[iwan,csrservice]}'
Run Code Online (Sandbox Code Playgroud)

最后,根据上述标准,我需要从yml文件中获得这三个值。为此我创建了一个ansible sp-deployer.yml。我使用set_facts创建了动态列表。第一个列表可以正常工作,但是当我创建第二个列表时它失败。请帮助我。其他建议对我也很好。

name: "ms_service"
port: "830"
streams: "noti,jk-noti"
Run Code Online (Sandbox Code Playgroud)

vars.yml

    version: 1
    name: user
    jobs:
      ns1:
        ip: "1.1.1.1"
        ns_version: "4.2"
        f_packs:
          - f-pack-1:
            name: "pack1"
            microservices:
            - microservice-1:
              name: "ms_service"
              port: "830"
              streams: "noti,jk-noti"
            - microservice-2:
              name: "ms_service1"
              port: "830"
              streams: "noti1,jk-noti1"
          - f-pack-2:
            name: "pack4"
            microservices:
            - microservice-1:
              name: "ms_service3"
              port: "830"
              streams: "noti,jk-noti3"
            - microservice-2:
              name: "ms_service4"
              port: "830"
              streams: "noti,jk-noti4"
            - microservice-3:
              name: "ms_service5"
              port: "830"
              streams: "noti,jk-noti5"
Run Code Online (Sandbox Code Playgroud)

脚本:sp-deployer.yml

    ---
- hosts: localhost
  vars_files:
    - ./vars.yml
  sudo: yes
  tasks:

  - name: Reading vars.yml file and preparing list of microservice with its metadata
    set_fact: foo_item="{{ item.1 }}"
    register: result    
    with_subelements:
     - "{{ jobs.ns1.f_packs }}"   ###item.0
     - microservices       ###item.1

  - name: make first list
    set_fact: foo="{{ result.results | map(attribute='ansible_facts.foo_item') | list }}"

  - name: print register
    debug: msg="{{ item }}" verbosity=3
    with_items:    
      - "{{ foo }}"

  - name: Filtering micro service list with match found from command line input
    when: item[0].name == item[1]
    set_fact: foo_item1="{{ item.0 }}"
    register: result_final    
    with_nested:
      - "{{ foo }}"
      - "{{ microservices_list }}"
  - name: make a list
    set_fact: foo1="{{ result_final.results | map(attribute='ansible_facts.foo_item1') | list }}"
Run Code Online (Sandbox Code Playgroud)

错误

TASK [make a list] *************************************************************
fatal: [localhost]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'dict object' has no attribute 'ansible_facts'\n\nThe error appears to have been in '/home/user/ansible/sp-deployer1.yml': line 40, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n  - name: make a list\n    ^ here\n"}
    to retry, use: --limit @/home/user/ansible/sp-deployer1.retry

PLAY RECAP *********************************************************************
localhost                  : ok=4    changed=0    unreachable=0    failed=1   
Run Code Online (Sandbox Code Playgroud)

Kon*_*rov 5

友善的建议:debug如果发现此类错误,请务必检查已注册的变量。

您出错的原因是,如果跳过循环迭代,set_fact则不会产生ansible_factsdict。
我看到您when的循环中有陈述。

要克服此错误,您应该仅选择已ansible_facts定义dict的那些循环迭代:

- name: make a list
  set_fact: foo1="{{ result_final.results | selectattr('ansible_facts','defined') | map(attribute='ansible_facts.foo_item1') | list }}"
Run Code Online (Sandbox Code Playgroud)