Ansible-如何将dict提供给dict类型的模块参数?

时间:2019-11-22 20:32:12

标签: dictionary module ansible ovf

目标:使代码自动化,使其与ovf无关。构建一个剧本,以允许在不更改YAML剧本的情况下部署具有任何自定义ovf属性和网络接口名称的任何OVF模板。

环境:    Ansible 2.8.7    python版本= 3.6.8

代码示例:

  **Dicts: cust-ovf-answer.yml**

       custovfnetworkanswers: 
            Management: "vmportgroup"

       custovfanswers: 
            fqdn: "s0u1tst.dmn.local"
            dns1: "10.100.0.14"
            dns2: "10.100.0.17"
            ntp1: "ntp1.dmn.local"
            ntp2: "ntp2.dmn.local"
            ipv4.how: "Manual"
            ipv4.addr: "10.100.0.135"
            ipv4.mask: "255.255.255.224"
            ipv4.gw: "10.100.0.158"


**Playbook: Deploy_OVF_to_System.yml**

    ... MAGIC STUFF GOING ON UP HERE ...

    - name: Get Unqiue OVF Answers
      include_vars:
         file: ".../cust-ovf-answers.yml"

    - name: Deploy Appliance OVF
      vmware_deploy_ovf:  
      hostname: "{{ inventory_hostname }}"
      username: "{{ vcenter_username }}"
      password: "{{ vcenter_password }}"
      validate_certs: no
      name: "r{{ custVMName }}"  
      datacenter: "TEST"
      folder: "/test/vm/aas"
      datastore: "{{ targetDatastore }}"
      allow_duplicates: no
      disk_provisioning: "thick" 
      networks:
        args: "{{ custovfnetworkanswers | to_json }}"
        # "Management": "{{ vmportgroup }}"
      power_on: no 
      wait: no
      ovf: "{{ custOvfFile.files[0].path }}"
      fail_on_spec_warnings: no
      inject_ovf_env: yes
      properties: 
        args: "{{ custovfanswers | to_json }}"
        # fqdn: "{{ item.value.fdqn }}" 
        # dns1: "{{ item.value.dns1 }}"
        # dns2: "{{ item.value.dns2 }}"
        # ntp1: "ntp1.dmn.local"
        # ntp2: "ntp2.dmn.local"
        # ipv4.how: "Manual"
        # ipv4.addr: "10.100.0.135"
        # ipv4.mask: "255.255.255.224"
        # ipv4.gw: "10.100.0.158"
  delegate_to: localhost
  when: 
    #- custovfanswers is defined
    #- custovfnetworkanswers is defined

**输出1:**

使用args:“ {{ custom_dict | to_json}}”定义网络和属性时的错误。

{
    "hosts": {
        "vCenter Host": {
            "_ansible_no_log": false,
            "action": "set_fact",
            "ansible_facts": {
                "buildvmCustomConfigFileLoc": ".../cust-ovf-answer.yml"
            },
            "changed": false
        }
    },
    "task": {
        "duration": {
            "end": "2019-11-22T18:05:50.616891Z",
            "start": "2019-11-22T18:05:50.544148Z"
        },
        "id": "005056a7-5f58-135f-6306-000000000a39",
        "name": "set_fact"
    }
},
{
    "hosts": {
        "vCenter Host": {
            "_ansible_no_log": false,
            "action": "include_vars",
            "ansible_facts": {
                "custovfanswers": {
                    "dns1": "10.100.0.14",
                    "dns2": "10.100.0.17",
                    "fqdn": "s0u1tst.dmn.local",
                    "ipv4.addr": "10.100.0.135",
                    "ipv4.gw": "10.100.0.158",
                    "ipv4.how": "Manual",
                    "ipv4.mask": "255.255.255.224",
                    "ntp1": "ntp1.dmn.local",
                    "ntp2": "ntp2.dmn.local",
                },
                "custovfnetworkanswers": {
                    "Management": "VMTraffic_test"
                }
            },
            "ansible_included_var_files": [
                ".../cust-ovf-answer.yml"
            ],
            "changed": false
        }
    },
    "task": {
        "duration": {
            "end": "2019-11-22T18:05:50.741706Z",
            "start": "2019-11-22T18:05:50.653958Z"
        },
        "id": "005056a7-5f58-135f-6306-000000000a3a",
        "name": "Get Unqiue OVF Answers"
    }
},
{
    "hosts": {
        "vCenter Host": {
            "_ansible_delegated_vars": {
                "ansible_host": "localhost"
            },
            "_ansible_no_log": false,
            "action": "vmware_deploy_ovf",
            "changed": false,
            "exception": "Traceback (most recent call last):\n  File \"/home/swelsch/.ansible/tmp/ansible-tmp-1574445950.872407-14317549312709/AnsiballZ_vmware_deploy_ovf.py\", line 114, in <module>\n    _ansiballz_main()\n  File \"/home/swelsch/.ansible/tmp/ansible-tmp-1574445950.872407-14317549312709/AnsiballZ_vmware_deploy_ovf.py\", line 106, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/swelsch/.ansible/tmp/ansible-tmp-1574445950.872407-14317549312709/AnsiballZ_vmware_deploy_ovf.py\", line 49, in invoke_module\n    imp.load_module('__main__', mod, module, MOD_DESC)\n  File \"/usr/lib/python3.6/imp.py\", line 235, in load_module\n    return load_source(name, filename, file)\n  File \"/usr/lib/python3.6/imp.py\", line 170, in load_source\n    module = _exec(spec, sys.modules[name])\n  File \"<frozen importlib._bootstrap>\", line 618, in _exec\n  File \"<frozen importlib._bootstrap_external>\", line 678, in exec_module\n  File \"<frozen importlib._bootstrap>\", line 219, in _call_with_frames_removed\n  File \"/tmp/ansible_vmware_deploy_ovf_payload_9pywu9rd/__main__.py\", line 685, in <module>\n  File \"/tmp/ansible_vmware_deploy_ovf_payload_9pywu9rd/__main__.py\", line 677, in main\n  File \"/tmp/ansible_vmware_deploy_ovf_payload_9pywu9rd/__main__.py\", line 465, in upload\n  File \"/tmp/ansible_vmware_deploy_ovf_payload_9pywu9rd/__main__.py\", line 372, in get_lease\n  File \"/tmp/ansible_vmware_deploy_ovf_payload_9pywu9rd/__main__.py\", line 344, in get_objects\nKeyError: 'network'\n",
            "failed": true,
            "module_stderr": "Traceback (most recent call last):\n  File \"/home/swelsch/.ansible/tmp/ansible-tmp-1574445950.872407-14317549312709/AnsiballZ_vmware_deploy_ovf.py\", line 114, in <module>\n    _ansiballz_main()\n  File \"/home/swelsch/.ansible/tmp/ansible-tmp-1574445950.872407-14317549312709/AnsiballZ_vmware_deploy_ovf.py\", line 106, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/swelsch/.ansible/tmp/ansible-tmp-1574445950.872407-14317549312709/AnsiballZ_vmware_deploy_ovf.py\", line 49, in invoke_module\n    imp.load_module('__main__', mod, module, MOD_DESC)\n  File \"/usr/lib/python3.6/imp.py\", line 235, in load_module\n    return load_source(name, filename, file)\n  File \"/usr/lib/python3.6/imp.py\", line 170, in load_source\n    module = _exec(spec, sys.modules[name])\n  File \"<frozen importlib._bootstrap>\", line 618, in _exec\n  File \"<frozen importlib._bootstrap_external>\", line 678, in exec_module\n  File \"<frozen importlib._bootstrap>\", line 219, in _call_with_frames_removed\n  File \"/tmp/ansible_vmware_deploy_ovf_payload_9pywu9rd/__main__.py\", line 685, in <module>\n  File \"/tmp/ansible_vmware_deploy_ovf_payload_9pywu9rd/__main__.py\", line 677, in main\n  File \"/tmp/ansible_vmware_deploy_ovf_payload_9pywu9rd/__main__.py\", line 465, in upload\n  File \"/tmp/ansible_vmware_deploy_ovf_payload_9pywu9rd/__main__.py\", line 372, in get_lease\n  File \"/tmp/ansible_vmware_deploy_ovf_payload_9pywu9rd/__main__.py\", line 344, in get_objects\nKeyError: 'network'\n",
            "module_stdout": "",
            "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
            "rc": 1
        }
    },
    "task": {
        "duration": {
            "end": "2019-11-22T18:05:53.288639Z",
            "start": "2019-11-22T18:05:50.791547Z"
        },
        "id": "005056a7-5f58-135f-6306-000000000a3b",
        "name": "Deploy Appliance OVF"
    }
}

**输出2:** 在使用args定义属性:时出错:“ {{ custom_dict | to_json}}”。网络:通过对其进行硬编码来定义。

{
    "hosts": {
        "vCenter Host": {
            "_ansible_no_log": false,
            "action": "include_vars",
            "ansible_facts": {
                "custovfanswers": {
                    "dns1": "10.100.0.14",
                    "dns2": "10.100.0.17",
                    "fqdn": "s0u1tst.dmn.local",
                    "ipv4.addr": "10.100.0.135",
                    "ipv4.gw": "10.100.0.158",
                    "ipv4.how": "Manual",
                    "ipv4.mask": "255.255.255.224",
                    "ntp1": "ntp1.dmn.local",
                    "ntp2": "ntp2.dmn.local",
                },
                "custovfnetworkanswers": {
                    "Management": "vmportgroup"
                }
            },
            "ansible_included_var_files": [
                ".../cust-ovf-answer.yml"
            ],
            "changed": false
        }
    },
    "task": {
        "duration": {
            "end": "2019-11-22T18:42:33.098663Z",
            "start": "2019-11-22T18:42:33.001653Z"
        },
        "id": "005056a7-5f58-c3eb-25e1-000000000a3a",
        "name": "Get Unqiue OVF Answers"
    }
    },
    {
    "hosts": {
        "vCenter Host": {
            "_ansible_delegated_vars": {
                "ansible_host": "localhost"
            },
            "_ansible_no_log": false,
            "action": "vmware_deploy_ovf",
            "changed": true,
            "instance": {
                "annotation": "xxxx",
                "current_snapshot": null,
                "customvalues": {},
                "guest_consolidation_needed": false,
                "guest_question": null,
                "guest_tools_status": "guestToolsNotRunning",
                "guest_tools_version": "0",
                "hw_cluster": null,
                "hw_cores_per_socket": 1,
                "hw_datastores": [
                    "s0u1aas-nlsas"
                ],
                "hw_esxi_host": "s0u1aas.dmn.local",
                "hw_eth0": {
                    "addresstype": "assigned",
                    "ipaddresses": null,
                    "label": "Network adapter 1",
                    "macaddress": "00:50:56:a7:ae:20",
                    "macaddress_dash": "00-50-56-a7-ae-20",
                    "portgroup_key": null,
                    "portgroup_portkey": null,
                    "summary": "vmportgroup"
                },
                "hw_files": [
                    "[s0u1aas-nlsas] r10s0u1tst/r10s0u1tst.vmx",
                    "[s0u1aas-nlsas] r10s0u1tst/r10s0u1tst.vmsd",
                    "[s0u1aas-nlsas] r10s0u1tst/r10s0u1tst.vmdk"
                ],
                "hw_folder": "/test/vm/AAS",
                "hw_guest_full_name": null,
                "hw_guest_ha_state": null,
                "hw_guest_id": null,
                "hw_interfaces": [
                    "eth0"
                ],
                "hw_is_template": false,
                "hw_memtotal_mb": 32768,
                "hw_name": "r10s0u1tst",
                "hw_power_status": "poweredOff",
                "hw_processor_count": 4,
                "hw_product_uuid": "4227ef4b-0d98-e254-f9e7-b798bbee43fc",
                "hw_version": "vmx-13",
                "instance_uuid": "50271468-256d-9c69-7154-cfbdd26fc900",
                "ipv4": null,
                "ipv6": null,
                "module_hw": true,
                "snapshots": [],
                "vnc": {}
            },
            "invocation": {
                "module_args": {
                    "allow_duplicates": false,
                    "cluster": null,
                    "datacenter": "TEST",
                    "datastore": "s0u1aas-nlsas",
                    "deployment_option": null,
                    "disk_provisioning": "thin",
                    "fail_on_spec_warnings": false,
                    "folder": "/test/vm/aas",
                    "hostname": "vCenter Host",
                    "inject_ovf_env": true,
                    "name": "r10s0u1tst",
                    "networks": {
                        "Management": "vmportgroup "
                    },
                    "ovf": "xxx.ovf",
                    "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                    "port": 443,
                    "power_on": false,
                    "properties": {
                        "args": "{\"fqdn\": \"s0u1tst.dmn.local\", \"dns1\": \"10.100.0.14\", \"dns2\": \"10.100.0.17\", \"ntp1\": \"ntp1.dmn.local\", \"ntp2\": \"ntp2.dmn.local\", \"ipv4.how\": \"Manual\", \"ipv4.addr\": \"10.100.0.135\", \"ipv4.mask\": \"255.255.255.224\", \"ipv4.gw\": \"10.100.0.158\"}"
                    },
                    "resource_pool": "Resources",
                    "username": "xxxx",
                    "validate_certs": false,
                    "wait": false,
                    "wait_for_ip_address": false
                }
            }
        }
    },
    "task": {
        "duration": {
            "end": "2019-11-22T18:43:35.923602Z",
            "start": "2019-11-22T18:42:33.148318Z"
        },
        "id": "005056a7-5f58-c3eb-25e1-000000000a3b",
        "name": "Deploy Appliance OVF"
    }

如果我全部硬编码,则所有内容都会按预期导入。

1 个答案:

答案 0 :(得分:0)

我认为您的问题是 args:。您可以直接注入 dict 变量。顺便说一句,您不需要使用 to_json 转换过滤器,因为 Ansible 会处理它。

  […]
      disk_provisioning: "thick" 
      networks: "{{ custovfnetworkanswers }}"
      power_on: no 
  […]
      inject_ovf_env: yes
      properties: "{{ custovfanswers }}"
  delegate_to: localhost
  […]

奖金

在某些情况下,您必须提供的键需要是动态的(不可预测的键名或列表长度)。要解决这个问题,您可以使用 jinja2 将变量伪造为 json 字符串。

dict 样本动态列表:

vars:
  custom_networks: >
    [ {% for nic in nics %}
        { 'name':'{{ nic.id }}',
          'mac':'{{ nic.mac }}',
          'ip': '{{ nic.ip }}'
        }{% if not loop.last %},{% endif %}
      {% endfor %}
    ]

动态键名:

vars:
  custom_ovf_input: "{ '{{ network_name }}': '{{ network_address }}' }"

然后你可以直接使用那个伪造的变量(不需要使用任何过滤器将其转换为 yaml Ansible 会处理它)。