Help with json results in a loop

I am trying new things to try and push my learning with Ansible. I have been using Dynamic Inventories with my Proxmox Servers, but wanted to try out Netbox to record all of my VM’s

I have created a task to retrieve the VM’s & LXC’s that are on my Proxmox Server and want to use the results to register each VM/LXC onto Netbox via it’s REST API

Retrieving the data from Proxmox works fine:

  tasks:
    - name: Get Proxmox VMs & LXC's
      community.general.proxmox_vm_info:
        api_host: "{{ proxmox_api_host }}"
        api_user: "{{ proxmox_api_user }}"
        api_password: "{{ proxmox_api_password }}"
        node: pandora
        config: current
      register: proxmox_vms

Using a Debug, the results are as follows:

ok: [localhost] => {
    "msg": {
        "changed": false,
        "failed": false,
        "proxmox_vms": [
            {
                "config": {
                    "arch": "amd64",
                    "cores": 4,
                    "digest": "c83f9c1f1a62b08d064dcd73f12c4c5712858685",
                    "features": "nesting=1",
                    "hostname": "ob-debian",
                    "memory": 512,
                    "net0": "name=eth0,bridge=vmbr0,firewall=1,hwaddr=BC:24:11:44:65:A2,ip=dhcp,type=veth",
                    "onboot": 1,
                    "ostype": "debian",
                    "rootfs": "SSD256:101/vm-101-disk-0.raw,size=8G",
                    "swap": 0,
                    "unprivileged": 1
                },
                "cpu": 8.46781942582492e-06,
                "cpus": 4,
                "disk": 766754816,
                "diskread": 484483072,
                "diskwrite": 10412032,
                "id": "lxc/101",
                "maxcpu": 4,
                "maxdisk": 8350298112,
                "maxmem": 536870912,
                "maxswap": 0,
                "mem": 22491136,
                "name": "ob-debian",
                "netin": 65523102,
                "netout": 3146,
                "node": "oberon",
                "pid": 1295,
                "status": "running",
                "swap": 0,
                "template": false,
                "type": "lxc",
                "uptime": 65728,
                "vmid": 101
            },

... Data repeats as above

I want to then loop through the results and register each of the VM’s/LXC’s into Netbox via a POST method using its REST API:

    - name: Register VMs in NetBox
      uri:
        url: "{{ netbox_url }}/api/virtualization/virtual-machines/"
        method: POST
        headers:
          Authorization: Token {{ netbox_token }}
          Content-Type: application/json
        body_format: json
        body:
          name: "{{ item.name }}"
          cluster: "{{ item.node }}"
          vcpus: "{{ item.cpus }}"
          memory: "{{ item.maxmem }}"
          disk: "{{ item.maxdisk }}"
          status: active
          tags: "{{ item.tags }}"
        status_code: [201, 400]
      loop: "{{ proxmox_vms }}"

The error states it wants a list and instead got a load of JSON. I have looked up on how to try and resolve this online, but I must be missing something really simple as I can’t get it to work

fatal: [localhost]: FAILED! => {"msg": "Invalid data passed to 'loop', it requires a list, got this instead: {'changed': False, 'proxmox_vms': [{'diskread': 484483072, 'cpu': 2.13049656820896e-05,

Thanks :slight_smile:

Try this:
loop: "{{ proxmox_vms.proxmox_vms }}"

3 Likes

If you also want to add additional host facts to the netbox records, you could also do something like this:

- name: 'Register devices in Netbox'
  hosts: 'all'
  gather_facts: true
  tasks:
    - name: 'Register in Netbox'
      your_task:
        args: 'etc'
      delegate_to: 'localhost'

This way, the tasks run in the context of the host, but are executed on your control node (so no need to distribute credentials or even make it accessible to your complete population).

And, as a bonus feature, you can also register all other hosts that ansible has access to!

1 Like

Brilliant, that seems to have done the trick

I think I got confused as the Register is the same name as the output, so my brain didn’t want to put the name twice :slight_smile:

1 Like