ansible_modules icon indicating copy to clipboard operation
ansible_modules copied to clipboard

[Bug]: Unable to use services in netbox inventory module

Open StoffelCPR opened this issue 6 months ago • 21 comments

Ansible NetBox Collection version

devel

Ansible version

ansible [core 2.17.11]
  config file = /home/stoffel/Projects/tenants/aac-lintert-homelab/ansible.cfg
  configured module search path = ['/home/stoffel/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/stoffel/.local/lib/python3.10/site-packages/ansible
  ansible collection location = /home/stoffel/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/stoffel/.local/bin/ansible
  python version = 3.10.12 (main, Feb  4 2025, 14:57:36) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.1.6
  libyaml = True

I had setup my ansible to use the dynamic inventory with services attached to VMs and Devices alike to roll out let's encrypt certificates, this randomly stopped working. After debugging for 2 hours I noticed that I didn't actually fuck up but the ansible-inventory doesn't return any services attached to either VMs or Devices. I hoped the latest netbox_service fixes would fix this but they don't

NetBox version

v4.3.2-Docker-3.3.0

Python version

3.10

Steps to Reproduce

Create a VM and attach a service to it of any kind.

Set your inventory to include service as follows:

plugin: netbox.netbox.nb_inventory
api_endpoint: http://your-netbox
token: your_valid_token
validate_certs: false
config_context: true
services: true
flatten_config_context: true
site_data: true
group_by:
  #- device_roles
  #- services
  - tags

defaults:
  groups:
    - all

You'd expect the service to be shown in your inventory but all you will see is an empty services list

                "services": [],                                                                                                                                                               

Expected Behavior

The services list to be filled with all the attached services

Observed Behavior

List was empty. Though services are attached to the VMs; curl on the API shows that services are properly returned and have a parent object and type

StoffelCPR avatar Jun 18 '25 20:06 StoffelCPR

Yep, seeing this in CI tests against 4.1 and 4.3. This was being masked by an issue we've had lately with version string parsing so something might have slipped in.

sc68cal avatar Jun 20 '25 17:06 sc68cal

bumping. Do you have an idea where to look? @sc68cal if you help me get started I am technically a software dev and could help. New to your project though.

StoffelCPR avatar Jul 02 '25 14:07 StoffelCPR

@StoffelCPR

So, at least in CI, our tests against NetBox API 4.1 are not creating the new service correctly since it appears the API changed, and we are not associating it with a device or virtual machine correctly. We are creating a device, but it appears that we are not correctly sending the API call in the way the server expects, so there needs to be a code change in the service module.

https://github.com/netbox-community/ansible_modules/actions/runs/15967236770/job/45030247613

TASK [v4.1 : 1 - Device with required information needs to add new service] **** changed: [testhost] => {"changed": true, "device": {"airflow": null, "asset_tag": null, "cluster": null, "comments": "", "config_context": {}, "config_template": null, "console_port_count": 0, "console_server_port_count": 0, "created": "2025-06-30T08:11:09.310491Z", "custom_fields": {}, "description": "", "device_bay_count": 0, "device_type": 1, "display": "FOR_SERVICE", "display_url": "http://localhost:32768/dcim/devices/13/", "face": null, "front_port_count": 0, "id": 13, "interface_count": 0, "inventory_item_count": 0, "last_updated": "2025-06-30T08:11:09.310508Z", "latitude": null, "local_context_data": null, "location": null, "longitude": null, "module_bay_count": 0, "name": "FOR_SERVICE", "oob_ip": null, "parent_device": null, "platform": null, "position": null, "power_outlet_count": 0, "power_port_count": 0, "primary_ip": null, "primary_ip4": null, "primary_ip6": null, "rack": null, "rear_port_count": 0, "role": 1, "serial": "", "site": 1, "status": "staged", "tags": [], "tenant": null, "url": "http://localhost:32768/api/dcim/devices/13/", "vc_position": null, "vc_priority": null, "virtual_chassis": null}, "msg": "device FOR_SERVICE created"}

TASK [v4.1 : NETBOX_SERVICE: Create new service] ******************************* fatal: [testhost]: FAILED! => {"changed": false, "msg": "{"all":["A service must be associated with either a device or a virtual machine."]}"}

sc68cal avatar Jul 04 '25 16:07 sc68cal

I believe the responsible code is here https://github.com/netbox-community/ansible_modules/blob/devel/plugins/module_utils/netbox_ipam.py#L219

sc68cal avatar Jul 04 '25 16:07 sc68cal

So, looks like #1421 got us closer to resolving this issue but it's not complete. It appears to be two situations:

  • For API 4.1 - we are not sending the correct parameters. This was something I highlighted in https://github.com/netbox-community/ansible_modules/pull/1421#pullrequestreview-2869346201 - but I mistakenly thought that #1427 did not suffer from the same issue since its approach was different.

  • For API 4.3 we appear to have a CI issue with the code, where our assert does not pass. The service does get created but I think our assert is outdated and needs changing for when the API is 4.3 - https://github.com/netbox-community/ansible_modules/actions/runs/15967236770/job/45030247618#step:12:3294

TASK [v4.3 : NETBOX_SERVICE: Create new service on virtual_machine] ************ changed: [testhost] => {"changed": true, "msg": "services node-exporter updated", "services": {"comments": "", "created": "2025-06-30T08:11:58.725610Z", "custom_fields": {}, "description": "", "display": "node-exporter (TCP/9100, 9200)", "display_url": "http://localhost:32768/ipam/services/1/", "id": 1, "ipaddresses": [], "last_updated": "2025-06-30T08:12:00.513092Z", "name": "node-exporter", "parent": 13, "parent_object_id": 1, "parent_object_type": "virtualization.virtualmachine", "ports": [9100], "protocol": "tcp", "tags": [4], "url": "http://localhost:32768/api/ipam/services/1/"}}

TASK [v4.3 : NETBOX_SERVICE ASSERT - Create] *********************************** fatal: [testhost]: FAILED! => {"msg": "The conditional check 'test_service_create_vm['diff']['after']['state'] == "present"' failed. The error was: error while evaluating conditional (test_service_create_vm['diff']['after']['state'] == "present"): 'dict object' has no attribute 'state'"}

sc68cal avatar Jul 04 '25 16:07 sc68cal

Ah. My request is for collecting services in the nb_inventory module. Not for creating services

But I'll have a look into the code in general

StoffelCPR avatar Jul 07 '25 19:07 StoffelCPR

Based on a quick run-through of the code and release notes I guess the current problem is the following Breaking Change:

The device and virtual_machine foreign keys on the Service model have been replaced with a generic parent relationship to support the assignment of services to FHRP groups as well.

https://github.com/netbox-community/netbox/releases/tag/v4.3.0

Which then results in the current code being the problem:

https://github.com/netbox-community/ansible_modules/blob/77e28f844150d61c61635cf69348d3ad6b2b4c8f/plugins/inventory/nb_inventory.py#L1352

https://github.com/netbox-community/ansible_modules/blob/77e28f844150d61c61635cf69348d3ad6b2b4c8f/plugins/inventory/nb_inventory.py#L1357

This Code block tries splitting the services into device and virtualmachine lists. Though these don't longer exist as the Object is now wrapped into parent parent_object_type and parent_object_id

StoffelCPR avatar Jul 07 '25 20:07 StoffelCPR

@sc68cal I do have a quick fix available. That fix would be a breaking change to anyone using Netbox with a version before the breaking change.

I dove in and simply fixed the issue itself. I'll now start reading into your documentation on how to properly integrate the fix into your code base. If you have the time to help me get there please do so ^^

StoffelCPR avatar Jul 07 '25 21:07 StoffelCPR

I believe the fix itself is done in my PR @sc68cal would be nice if someone can take a look

StoffelCPR avatar Jul 10 '25 08:07 StoffelCPR

Basically bumping. Any news? Anything I can do to get this through?

StoffelCPR avatar Jul 20 '25 13:07 StoffelCPR

hmpf. :S

StoffelCPR avatar Aug 10 '25 16:08 StoffelCPR

Is this an 'all Developers got hit by a Bus simultaneously' situation?

StoffelCPR avatar Aug 31 '25 19:08 StoffelCPR

@StoffelCPR Hi, the maintainers are volunteers so we give what time we have. You caught us during a period of time where we were not as active.

Thank you for your contributions

sc68cal avatar Sep 05 '25 12:09 sc68cal

Any updates on this? I would really appreciate to get a fix for this, soon.

Thank you!

melsen avatar Oct 13 '25 06:10 melsen

I suppose problem with netbox.netbox.nb_inventory and services is fixed on Netbox side: https://github.com/netbox-community/netbox/issues/20554

We're also using services with nb_inventory. After #20554 can't see any problem and nb_inventory returns services normaly.

    "role": "vm_wildfly",
    "serial": "",
    "services": [
        {
            "comments": "",
            "created": "2024-11-15T09:58:03.984523Z",
            "custom_fields": {
                "srv_fw_zones": [
                    "internal"
                ]
            },
            "description": "wildfly port http",
            "display": "wildfly_tcp_http (TCP/8080)",

Can you check it?


I hope short offtopic about netbox_service: https://github.com/netbox-community/ansible_modules/pull/1427#issuecomment-3408655024

Not really sure where to put this comment or if open new issue? Thank you for your help

cernymi avatar Oct 15 '25 23:10 cernymi

@cernymi I just updated my Netbox instance to the latest version. Services are still empty.

Netbox version: 4.4.4-Docker-3.4.1 netbox.netbox collection version: 3.21.0 Ansible version:

ansible [core 2.17.14]
  python version = 3.11.2 (main, Apr 28 2025, 14:11:48) [GCC 12.2.0] (/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True

melsen avatar Oct 17 '25 08:10 melsen

@melsen It seems strange for me. I have

Netbox version: NetBox Community v4.4.4 On-prem and also https://demo.netbox.dev - can't see any difference netbox.netbox collection version: 3.21.0 Ansible in python venv version:

ansible [core 2.18.9]
  python version = 3.13.7 (main, Aug 14 2025, 00:00:00) [GCC 15.2.1 20250808 (Red Hat 15.2.1-1)] (/opt/ansible/bin/python3)
  jinja version = 3.1.6
  libyaml = True

Using inventory file inventory/dev.yml:

---
plugin: netbox.netbox.nb_inventory
api_endpoint: https://demo.netbox.dev
token: "{{ lookup('env', 'NETBOX_API_KEY') | mandatory }}"
validate_certs: true

config_context: true
services: true
flatten_config_context: true
site_data: true
group_by:
  # - device_roles
  # - services
  - tags

defaults:
  groups:
    - all

Actual inventory graph:

  ansible-inventory -i inventory/dev.yml  --graph
@all:
  |--@ungrouped:
  |--@tags_alpha:
  |  |--test1

I've added web_tcp_https (TCP/443) service to test1 VM so I'm getting output like this.

 ansible-inventory -i inventory/dev.yml --host test1
{
    "ansible_python_interpreter": "python3",
    "cluster": "test",
    "cluster_group": "emea",
    "cluster_type": "test",
    "custom_fields": {},
    "device_roles": [
        "application-server"
    ],
    "is_virtual": true,
    "local_context_data": [
        null
    ],
    "locations": [],
    "netbox_validate_certs": true,
    "platforms": [
        "ubuntu-linux-18-04"
    ],
    "regions": [
        "FR",
        "EU"
    ],
    "serial": "",
    "services": [
        {
            "comments": "",
            "created": "2025-10-17T10:38:49.819110Z",
            "custom_fields": {},
            "description": "web_tcp_https",
            "display": "web_tcp_https (TCP/443)",
            "display_url": "https://demo.netbox.dev/ipam/services/1/",
            "id": 1,
            "ipaddresses": [],
            "last_updated": "2025-10-17T10:38:49.819127Z",
            "name": "web_tcp_https",
            "parent": {
                "description": "",
                "display": "test1",
                "id": 541,
                "name": "test1",
                "url": "https://demo.netbox.dev/api/virtualization/virtual-machines/541/"
            },
            "parent_object_id": 541,
            "parent_object_type": "virtualization.virtualmachine",
            "ports": [
                443
            ],
            "protocol": {
                "label": "TCP",
                "value": "tcp"
            },
            "tags": [
                {
                    "color": "111111",
                    "display": "Zulu",
                    "display_url": "https://demo.netbox.dev/extras/tags/26/",
                    "id": 26,
                    "name": "Zulu",
                    "slug": "zulu",
                    "url": "https://demo.netbox.dev/api/extras/tags/26/"
                }
            ],
            "url": "https://demo.netbox.dev/api/ipam/services/1/"
        }
    ],
    "site_groups": [
        "FR"
    ],
    "sites": [
        {
            "asns": [],
.
.
.
            "time_zone": "Europe/Rome",
            "url": "https://demo.netbox.dev/api/dcim/sites/30/",
            "virtualmachine_count": 1,
            "vlan_count": 0
        }
    ],
    "status": {
        "label": "Active",
        "value": "active"
    },
    "tags": [
        "alpha"
    ]
}


Playbook task_lookup-test.yml

- name: test
  hosts:
    - all
  gather_facts: false
  tasks:

  - name: "|{{ inventory_hostname }}| inventory_hostname services - debug"
    ansible.builtin.debug:
      msg: |
        "{{ hostvars[inventory_hostname].services }}"

Returns:

 ansible-playbook -i inventory/dev.yml task_lookup-test.yml 

PLAY [test] **********************************************************************************************************************************************************************************************************************************
[WARNING]: Found variable using reserved name: tags
[WARNING]: Found variable using reserved name: serial

TASK [|test1| inventory_hostname services - debug] *******************************************************************************************************************************************************************************************
Friday 17 October 2025  12:42:19 +0200 (0:00:00.017)       0:00:00.017 ******** 
ok: [test1] => 
    msg: |-
        "[{'id': 1, 'url': 'https://demo.netbox.dev/api/ipam/services/1/', 'display_url': 'https://demo.netbox.dev/ipam/services/1/', 'display': 'web_tcp_https (TCP/443)', 'parent_object_type': 'virtualization.virtualmachine', 'parent_object_id': 541, 'parent': {'id': 541, 'url': 'https://demo.netbox.dev/api/virtualization/virtual-machines/541/', 'display': 'test1', 'name': 'test1', 'description': ''}, 'name': 'web_tcp_https', 'protocol': {'value': 'tcp', 'label': 'TCP'}, 'ports': [443], 'ipaddresses': [], 'description': 'web_tcp_https', 'comments': '', 'tags': [{'id': 26, 'url': 'https://demo.netbox.dev/api/extras/tags/26/', 'display_url': 'https://demo.netbox.dev/extras/tags/26/', 'display': 'Zulu', 'name': 'Zulu', 'slug': 'zulu', 'color': '111111'}], 'custom_fields': {}, 'created': '2025-10-17T10:38:49.819110Z', 'last_updated': '2025-10-17T10:38:49.819127Z'}]"

cernymi avatar Oct 17 '25 11:10 cernymi

@cernymi this is really strange. I just tried to configure my Netbox inventory file exactly the same as yours and connected it to my local Netbox instance as well as to the demo instance. Both tests with the same result: services are still empty. I'm wondering, if there there are more differences between your setup and mine. For my understanding, the only relevant parts should be the Ansible Netbox collection version and the Netbox version.

Afterwards I 've installed a clean Debian 13 and installed Ansible from the Debian repository (version 2.19.0b6). The Netbox collection was pre-installed in the latest version 3.21.0.

Ansible version:

ansible [core 2.19.0b6]
  config file = None
  configured module search path = ['/home/test/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/test/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.13.5 (main, Jun 25 2025, 18:55:22) [GCC 14.2.0] (/usr/bin/python3)
  jinja version = 3.1.6
  pyyaml version = 6.0.2 (with libyaml v0.2.5)

Netbox inventory:

---
plugin: netbox.netbox.nb_inventory
api_endpoint: https://demo.netbox.dev
token: <redacted>
validate_certs: true

config_context: true
services: true
flatten_config_context: true
site_data: true
group_by:
  # - device_roles
  # - services
  - tags

defaults:
  groups:
    - all

Still no success using `ansible-inventory --host -i . Of course I've added a application service to a VM object in the concerning Netbox instance. Is there anything else in your installation, which is configured different/additional?

Thank you for your help!

melsen avatar Oct 21 '25 13:10 melsen

@melsen Oh, I see the difference now! Thanks for ansible collection location path We're using collection installed from ansible-galaxy

What I found is difference between collections - version included in ansible vs ansible-galaxy - both are "version": "3.21.0" but are not the same..

diff --git a/MANIFEST.json b/MANIFEST.json
index 433c9cf..455ad9f 100644
--- a/MANIFEST.json
+++ b/MANIFEST.json
@@ -27,7 +27,7 @@
   "name": "FILES.json",
   "ftype": "file",
   "chksum_type": "sha256",
-  "chksum_sha256": "c6fe5bbf0c1519a78417b5b8ea0439c108ba6dd91e930e5cd80ff89d878095c3",
+  "chksum_sha256": "8f36fe05f81ade3dff4fa70c653ea506b253687d955715fd89d95cecd4b6fed7",
   "format": 1
  },
  "format": 1

8f36fe05f81ade3dff4fa70c653ea506b253687d955715fd89d95cecd4b6fed7 - is from ansible-galaxy c6fe5bbf0c1519a78417b5b8ea0439c108ba6dd91e930e5cd80ff89d878095c3 - is included in ansible installation

  • ansible-galaxy - it seems like this one contains latest changes from devel branch - even after git tag v3.21.0
  • ansible installation - respects git tag v3.21.0 so changes after that commit are not included - so this version is missing important change for services:
commit 95fec4edc4237516e0c07a58aa17ef0db90a57c7
Author:     Romain Wisniewski <[email protected]>
AuthorDate: Thu Jun 12 10:53:27 2025 +0200
Commit:     Romain Wisniewski <[email protected]>
CommitDate: Thu Jun 12 10:53:27 2025 +0200

    fixes #1426 : broken netbox_service module

Try install collection from ansible-galaxy. The situation about version is quite confusing.. But I hope this will help and I also hope it could be possible to align ansible and ansible-galaxy "versions"

cernymi avatar Oct 21 '25 20:10 cernymi

@cernymi Wow, that solved the problem! I used ansible-galaxy collection install --force netbox.netbox to reinstall the latest "version" of the netbox.netbox collection and now services are displayed correctly.

I agree, that this is quite confusing, since version 3.21.0 != 3.21.0. Hopefully this will get fixed soon.

Thank you really much for your effort!

melsen avatar Oct 22 '25 08:10 melsen

Yes there appears to be an issue with what was released #1465

sc68cal avatar Oct 22 '25 13:10 sc68cal