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

Allow the VM resource's wait_for_ip functionality to validate it matches a particular prefix #300

Closed
ddelnano opened this issue Feb 22, 2024 · 2 comments

Comments

@ddelnano
Copy link
Collaborator

This discussion on the XO forum explains that the VM resource's wait_for_ip functionality has a race condition with DHCP. It's possible that a VM will use a link local address prior to receiving its DHCP lease. This causes incorrect behavior because it's expected that the link local address is temporary.

This issue tracks adding a mechanism for deferring finalizing VM creation until DHCP is complete. The following terraform config below would wait until the VM's NICs received an IP that matched the indicated cidr range (or error if it doesn't converge):

resource "xenorchestra_vm" "qa-vm1" {
    cpus = var.cpu
    memory_max = var.memMax
    name_label = var.vmDesc
    name_description = var.vmName
    hvm_boot_firmware = "uefi"
    wait_for_ip = true

    expected_ip_cidr = "10.0.0.0/16"  # wait_for_ip will continue to poll until the XO api shows that the VM has an IP in that range

}

One thing to note is that it's possible for a VM to have multiple network interfaces and each interface can have multiple ip addresses. I know how to account for this yet, but it seems that having a single cidr range like the example above will not be flexible enough or it could cause the network interface of interest to be ignored (if 2 network interfaces are expected to have the same cidr range and one resolves earlier).

@ddelnano
Copy link
Collaborator Author

Listed below are the solutions I've investigated with some brief details on their pros and cons:

  1. Define the expected cidr range inline with a network block
  • Pros:
    • Flexible enough for any number of network interfaces
    • Likely the easiest to implement of the other options

resource "xenorchestra_vm" "qa-vm1" {
    cpus = var.cpu
    memory_max = var.memMax
    name_label = var.vmDesc
    name_description = var.vmName
    hvm_boot_firmware = "uefi"
    wait_for_ip = true
    
    network {
        wait_for_cidr = "10.0.0.0/16"
    }

}
  1. Define a single expected ip address range as a top level argument
  • Cons:
    • Will not work nicely if a user needs to have multiple network interfaces converge to a range of ip addresses
    • Will make the matching logic difficult to implement correctly with multiple network interfaces.
resource "xenorchestra_vm" "qa-vm1" {
    cpus = var.cpu
    memory_max = var.memMax
    name_label = var.vmDesc
    name_description = var.vmName
    hvm_boot_firmware = "uefi"
    wait_for_ip = true
    
    wait_for_cidr = "10.0.0.0/16"
}
  1. Define a list of expected ip address ranges as top level argument
  • Cons:
    • Will require provider code to validate the schema (terraform's sdk doesn't provide primitives that work well with it)
    • Difficult to model omitting it for a subset of network interfaces (if network interfaces 1 and 3 need a cidr range defined but 2 doesn't).
resource "xenorchestra_vm" "qa-vm1" {
    cpus = var.cpu
    memory_max = var.memMax
    name_label = var.vmDesc
    name_description = var.vmName
    hvm_boot_firmware = "uefi"
    wait_for_ip = true

    network {
     }
     network {
     }
    
    # Have each of the cidr ranges apply to their respective network interface
    wait_for_ip_cidrs = [
        "10.0.0.0/16",
        "10.96.0.0/16",
     ]
}

Prior art in other terraform provider implementations:

  1. Vsphere provides wait_for_guest_{net_timeout,net_routable,ip_timeout}. These three options apply to the entire VM resource meaning that no network interface has an individual setting.
  2. Hyper-v provides a wait_for_ips attribute on its network_adapter block. This allows per network interface configuration.

I'm going to start with option 1 since it seems like the cleanest approach. While I think handling multiple network interfaces is likely uncommon, it also will support those use cases well.

@ddelnano
Copy link
Collaborator Author

This is completed and available in v0.29.0

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

1 participant