e-breuninger / terraform-provider-netbox

Terraform provider to interact with Netbox
https://registry.terraform.io/providers/e-breuninger/netbox/latest/docs
Mozilla Public License 2.0
178 stars 130 forks source link

New resource request: netbox_device_oob_ip #538

Open leijonatm opened 8 months ago

leijonatm commented 8 months ago

Issue Reporting Guide

Hello all,

the latest versions of netbox have a separate field for Out-Of-Band management IP and I would like to be able to set it via code. Thanks

tagur87 commented 8 months ago

This may be best as an option to add an IP address on to the device resource.

leijonatm commented 8 months ago

That idea works too. My suggestion was on the grounds of the primary IP

yoo commented 5 months ago

@tagur87 What is the motivation to handle this differently than a primary IP? I'm considering opening a PR, I just want to understand the reasoning.

tagur87 commented 4 months ago

I've found a lot of bugs when multiple resources touch the same object. Don't remember my exact reasons in this case, but might have been related to that.

yoo commented 4 months ago

I encountered the bugs with this too. What you are describing is a race condition in the update API call. For example when you assign the primary ipv4 and ipv6 at the same time.

When applying changes to netbox_device_primary_ip.ipv4,
│ provider "provider[\"registry.terraform.io/e-breuninger/netbox\"]" produced an unexpected new
│ value: Root object was present, but now absent.

I still would implement a new resource:

  1. This is a bug with NetBox and should be fixed in NetBox. The Terraform provider should not work around this.
  2. It would break with the current implementation of other IP assignments.
  3. It leads to dependency cycles in the resources them self. Lets consider the field is added to the device directly as oob_ip_id:
    
    resource "netbox_device" "this" {
    [...]
    oob_ip_id: # depends on the device_interface which depends on this device
    }

resource "netbox_device_interface" "this" { [...] device_id = netbox_device.this.id }

resource "netbox_ip_address" "oob" { [...] device_interface_id = netbox_device_interface.this.id ip_address = "192.168.1.1/24" }


If it's implemented as a string, same problem how to lookup a IP address that dose not jet exists?
The NetBox API expects a ID to a existing IP address.

4. Terraform can work around the bug. Deconflict the API requests by defining dependencies:
```terraform
resource "netbox_device" "this" {
  [...]
}

resource "netbox_device_interface" "this" {
  [...]
}

resource "netbox_ip_address" "ipv4" {
  [...]
}

resource "netbox_ip_address" "ipv6" {
  [...]
}

resource "netbox_ip_address" "oob" {
  [...]
}

resource "netbox_device_primary_ip" "ipv4" {
  device_id = netbox_device.this.id
  ip_address_id = netbox_ip_address.ipv4.id
  [...]
}

resource "netbox_device_primary_ip" "ipv6" {
  device_id = netbox_device.this.id
  ip_address_id = netbox_ip_address.ipv6.id
  [...]
  depends_on = [netbox_device_primary_ip.ipv4]
}

resource "netbox_device_oob_ip" "oob" {
  device_id = netbox_device.this.id
  ip_address_id = netbox_ip_address.oob.id
  [...]
  depends_on = [netbox_device_primary_ip.ipv6]
}

This is a feature of Terraform itself not the provider jumping through hoops. The depends_on can be removed once the bug is fixed.