UPDATE: At the time I wrote this the Netbox Collection was still pretty immature, it isn’t anymore. If you’re trying to do a simple task then you probably just want to go and install the Netbox Collection from Ansible Galaxy and use the native Modules. You can find the Collection here!
Ansible Tower and Netbox are two of my favourite tools, and their integration is seemingly painless on the surface (and really it isn’t all that bad) but there is a little nuance to it.
Both application stacks provide a RESTful API so sending data between the two should be as simple as firing some JSON between them right? Even with Ansible being a YAML focused platform those data structures are easily parsable to JSON (in fact that happens under the hood on every execution) so where does the issue occur?
The Ansible Tower and Netbox APIs are very well documented (though the Netbox Swagger documentation is a little wonky when it comes to some specifics, it gets the job pretty well).
The method for interacting with RESTful services within Ansible is via the uri module, which specifies that we can send either an external JSON payload or an inline JSON structure (that being a full structure) without much issue, in this sense we should be able to send key value pairs:
uri: url: https://your_netbox_endpoint method: POST body_format: form-urlencoded headers: bearer-token: "{{ YOUR_TOKEN }}" body: "KEY": VALUE "KEY": VALUE status_code: 302
From everything we’ve SEEN of how Ansible handles YAML | JSON parsing, this should work….except it doesn’t, the fun of solving an API.
This one seems to require that the entire JSON payload be built as either a file for lookup (using the lookup plugin), but I’m no fan of that as it leaves a bunch of rogue files lying around that can easily be lost or left out of source control, best to keep everything in code.
So what we really need is a one line JSON structure, that leaves us with:
uri: url: https://your_netbox_endpoint method: POST body_format: form-urlencoded headers: bearer-token: "{{ YOUR_TOKEN }}" body: '{ "KEY": "VALUE", "KEY": "VALUE"}' status_code: 302
The more you know…