Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[help] reference cycle when trying to create a VM and populating netbox at the same time. #613

Open
vhsantos opened this issue Jul 5, 2024 · 3 comments

Comments

@vhsantos
Copy link

vhsantos commented Jul 5, 2024

Hi there,

Actually, Im creating some VMs (vsphere) and when the VMs has a "static IP" it works well using it with the resource netbox_ip_address, netbox_virtual_machine and netbox_interface, for example:

resource "foreman_host" "hosts" {
  for_each = var.hosts
  name               = each.value.hostname
  ip = each.value.ip
}
resource "netbox_interface" "this" {
  for_each = foreman_host.hosts
  name        = each.value.interfaces_attributes[0].identifier
  enabled     = true
  mac_address = each.value.interfaces_attributes[0].mac
  mode        = "access"
  virtual_machine_id = netbox_virtual_machine.this[each.key].id
}
resource "netbox_virtual_machine" "this" {
  for_each = foreman_host.hosts
  cluster_id = data.netbox_cluster.cluster.id
  name       = each.value.fqdn
  disk_size_gb = each.value.disk[0].size
  memory_mb    = each.value.memory
  vcpus        = each.value.cpu
}
resource "netbox_ip_address" "this" {
  for_each                     = foreman_host.hosts
  ip_address                   = "${each.value.interfaces_attributes[0].ip}/24"
  status                       = "active"
  dns_name                     = each.value.fqdn
  virtual_machine_interface_id = netbox_interface.this[each.key].id
}

The issue come when I try to use the resource "netbox_available_ip_address", because in this case it always generate a reference cycle, for example:

locals {
  # Ensure valid IP addresses
  hosts_without_ip = { for k, v in var.hosts : k => v if !try(length(v.ip) > 0, false) }
}
resource "foreman_host" "hosts" {
  for_each = var.hosts
  name               = each.value.hostname
    ip = try(length(each.value.ip) > 0, false) ? each.value.ip : split("/", lookup(netbox_available_ip_address.this, each.key, null).ip_address)[0]
}
resource "netbox_available_ip_address" "this" {
  for_each  = local.hosts_without_ip
  prefix_id = data.netbox_prefix.auxiliar_systems.id
  status    = "active"
  # dns_name                     = each.value.fqdn
  virtual_machine_interface_id = netbox_interface.this[each.key].id
}
resource "netbox_interface" "this" {
  for_each = foreman_host.hosts
  name        = each.value.interfaces_attributes[0].identifier
  enabled     = true
  mac_address = each.value.interfaces_attributes[0].mac
  mode        = "access"
  virtual_machine_id = netbox_virtual_machine.this[each.key].id
}

I have tried to use the netbox_available_ip_address to get the free IP and create the VM, then use the netbox_ip_address to associate it with the virtual_machine_interface_id, but it complain that the IP is already been used. :-(

My goal is basically to use the free_ip to provising the VM and fill the netbox with as much info that come from the VM created.

any suggestion how continue here ?? Thanks in advance.

@vhsantos
Copy link
Author

vhsantos commented Jul 5, 2024

I saw the #602 with similar background, but not sure when (or if it will be merged).
Anyway, someone know why there is not data resource for the netbox_available_ip_address ??
In this case, should be easy to get the next free ip and kind of use it with the netbox_ip_address.

I know that it can maybe generate a race condition as well trying to create multiples objects at the same time, but maybe can works in some scenarios.

@skoppe
Copy link

skoppe commented Jul 15, 2024

@vhsantos good to see I am not the only one.

My PR has one last issue, namely that it interacts unfavorably with the underlying netbox_ip_address or netbox_available_ip_address resource.

Any assignment can be left undone after changes to either ip resource.

What needs to be done is to add an external_assignment boolean to both ip resources, so it knows to avoid updating/clearing any assignment.

@skoppe
Copy link

skoppe commented Sep 16, 2024

@vhsantos FYI I finally found some time to get the external_assignment into #602

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants