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

Configure NIC with static ip #493

Open
joppino opened this issue Dec 19, 2022 · 11 comments
Open

Configure NIC with static ip #493

joppino opened this issue Dec 19, 2022 · 11 comments
Assignees

Comments

@joppino
Copy link

joppino commented Dec 19, 2022

No description provided.

@joppino
Copy link
Author

joppino commented Dec 22, 2022

Hello, I opened this issue regarding network configuration using this provider on its current version, then closed it because I tried to read the whole documentation through, both for cloud-init and ovirt, but I seem not to be able getting a clue. The problem which I'm currently experiencing is related to the network configuration of a new VM built from a template using this provider. I cannot, in any way, provide a network configuration to the VM. Previously you could pass a nic_configuration structure to the vm resource, which in turn would configure the network for the VM and everything was good. Now that's gone, so (if I got it right) this must be done with cloud-init and a custom script. But a custom script doesn't let you specify network-data, which must be specified in a datasource, probably of the NoCloud type, which can be provided in an external configuration disk, etc.

Before going on that road, I'd need a confirmation that I've understood everything correctly. Static ip network configuration is a very basic configuration option and should be doable in a very simple way.

thanks

@joppino joppino reopened this Dec 22, 2022
@joppino joppino changed the title Configure NIC con VM Configure NIC with static ip Dec 22, 2022
@engelmi
Copy link
Collaborator

engelmi commented Dec 22, 2022

Hi @joppino,
in the new version of this provider the vm and nic creation were separated into two distinct resources. You can create a nic based on a vnic_profile to a vm like this:

resource "ovirt_vm" "test" {
	cluster_id  = "xxx"
	template_id = "xxx"
        name        = "test"
}

resource "ovirt_nic" "test" {
	vm_id           = ovirt_vm.test.id
	vnic_profile_id = "xxx"
	name            = "eth0"
}
// example based on https://github.com/oVirt/terraform-provider-ovirt/blob/main/internal/ovirt/resource_ovirt_nic_test.go#L27-L41

The vnic_profile has to exist and creating one via this provider (or the underlying go-ovirt-client) is currently not supported as far as I know.

@joppino
Copy link
Author

joppino commented Dec 22, 2022

Thanks @engelmi, I've read that example, but you cannot specify a static IP configuration in the ovirt vnic profile (ovirt 4.4).

@engelmi
Copy link
Collaborator

engelmi commented Dec 22, 2022

It seems like the usage of network (which was used to set the ip by the old provider, I think), was deprecated to create/update the nic and the support for it in the new provider dropped.
If you need the IP of a VM for other resources etc., you can use the wait_for_ip datasource. You can find a usage of it here and this issue comment describes how to use it in other resources.

@joppino
Copy link
Author

joppino commented Dec 22, 2022

Thanks for your answers, I understand that wait_for_ip is used to wait for the VM to have an IP. But what I need is to be able to assign a static IP address to the network configuration. Previously it was made in this way in the VM resource:


 initialization {
          dns_search  = "example.com"
          dns_servers = "8.8.8.8"
          host_name   = "temp01.example.com"
          timezone    = "Africa/Nairobi"

          nic_configuration {
              address    = "192.168.10.11"
              boot_proto = "static"
              gateway    = "192.168.10.254"
              label      = "eth0"
              netmask    = "255.255.255.0"
              on_boot    = true
            }
        }

So the question is how to replicate this behavior in the new provider. Currently from the documentation it seems that we can now just use initialization_hostname and initialization_custom_script (which is a cloud-init config).

I think the current situation is due to the switch to the go ovirt client (https://github.com/oVirt/go-ovirt-client/blob/v2.1.0/vm.go) which has the Initialization part allowing only the above two fields:

// Initialization defines to the virtual machine’s initialization configuration.
type Initialization interface {
	CustomScript() string
	HostName() string
}

@rcricardosantos1
Copy link

I have the same issue.

How to configure the VM to set up an ip addresses? There is any way using init scripts ?

@cello86
Copy link

cello86 commented Jun 30, 2023

Do you have some updates ? This is a blocking issue for the new version of this provider

@cello86
Copy link

cello86 commented Jul 31, 2023

@joppino I noticed the same issue and I tried to solve it via cloud-init. The problem on cloud-init is to pass vendor-data information on VM creation to use the network module to configure the static IP. I solved using the NM command:

data "ovirt_templates" "template" {
  name          = var.ovirt_template_name
  fail_on_empty = true
}

data "dns_a_record_set" "frontend_dc1" {
  count = var.vm_frontend_dc1_nodes_count
  host  = "${var.vm_frontend_dc1_hostname}${format("%02d", count.index + 1)}.${var.vm_domain}"
}

resource "ovirt_vm" "frontend_dc1" {
  count                        = var.vm_frontend_dc1_nodes_count
  name                         = "${var.vm_frontend_dc1_hostname}${format("%02d", count.index + 1)}.${var.vm_domain}"
  clone                        = true
  cluster_id                   = var.ovirt_cluster_id
  cpu_cores                    = var.vm_frontend_dc1_cpus
  cpu_sockets                  = 1
  cpu_threads                  = 1
  memory                       = var.vm_frontend_dc1_memory
  template_id                  = tolist(data.ovirt_templates.template.templates)[0].id
  initialization_hostname      = "${var.vm_frontend_dc1_hostname}${format("%02d", count.index + 1)}.${var.vm_domain}"
  serial_console               = true
  os_type                      = var.vm_os_type
  initialization_custom_script = local.cloud_init_templates_dc1[count.index]

  lifecycle {
    ignore_changes = [
      effective_template_id,
      placement_policy_affinity
    ]
  }
}

resource "ovirt_nic" "frontend_dc1" {
  count           = var.vm_frontend_dc1_nodes_count
  vnic_profile_id = var.vm_frontend_dc1_vnic_profile_id
  vm_id           = element(ovirt_vm.frontend_dc1.*.id, count.index)
  name            = "${var.vm_frontend_dc1_hostname}${format("%02d", count.index + 1)}.${var.vm_domain}-net1"
}

resource "ovirt_vm_start" "frontend_dc1" {
  count         = var.vm_frontend_dc1_nodes_count
  vm_id         = element(ovirt_vm.frontend_dc1.*.id, count.index)
  stop_behavior = "stop"
  force_stop    = true
  status        = "up"
  depends_on    = [ovirt_nic.frontend_dc1]
}

This is cloud-init script

cloud_init_modules:
- write-files
- set_hostname
- update_hostname
- bootcmd
cloud_config_modules:
- runcmd
cloud_final_modules:
- scripts-user
hostname: ${vm_hostname}${format("%02d", index + 1)}.${vm_domain}
fqdn: ${vm_hostname}${format("%02d", index +1)}.${vm_domain}
disable_root: false
network:
  version: 2
  config: disabled
runcmd:
- [ /usr/bin/systemctl, restart, rc-local.service ]
write_files:
- path: /root/scripts/netconfig.sh
  permissions: 0775
  owner: root
  content: |
    #!/bin/bash
    NM_STATUS=$(/usr/bin/nmcli c show | grep [l]oopback | wc -l)
    DEVICE=$(/usr/bin/nmcli d status | grep ethernet | egrep "connecting|disconnected" | awk '{print $1}')
    DEVICE_STATUS=$(/usr/bin/nmcli d status | grep $DEVICE | grep connected | wc -l)
    while [ $NM_STATUS != "1" ]; do 
      echo  "wait network manager"
      sleep 10  
    done
    if [ $NM_STATUS == 1 ]; then
      if [ $DEVICE_STATUS == 0 ]; then
        /usr/bin/nmcli c add type ethernet con-name "$DEVICE" ifname $DEVICE ipv4.addresses ${vm_ipv4_address}/${vm_ipv4_netmask} gw4 ${vm_ipv4_gateway} ipv4.dns ${vm_dns_server_list} ipv4.dns-search ${vm_dns_suffix_list} ipv4.method manual ipv4.ignore-auto-dns yes ipv4.dns-priority 999 ipv6.method disabled
        /usr/bin/nmcli con up "$DEVICE"
      fi
    fi
- path: /etc/rc.d/rc.local
  permissions: 0775
  owner: root
  append: true
  content: |
    /root/scripts/netconfig.sh

@engelmi
Copy link
Collaborator

engelmi commented Jul 31, 2023

Thank you @cello86 for this workaround!

As RHV has moved into maintenance, we have basically no capacity to work on this provider. However, if you or someone else have capacity to work on this, we are happy to review any contributions.
Just like @joppino pointed out, the go-ovirt-client needs to be extended first (see this issue). Luckily, I had a bit of time and was able to implement this here.
Note: Since I don't have any oVirt test instance to test this against, it is rather experimental, though.

As soon as this is merged (and maybe a new version is tagged), the tf provider can be extended to support assigning a static IP in the VM initialization. Would you be up for implementing it? @cello86 I can support you, of course.

@MikhailRyzhkin
Copy link

MikhailRyzhkin commented Dec 14, 2023

Good afternoon
As I understand it, there is still no way for a new provider to specify static IP addresses in the network interface settings? Will you have to come up with scripts and crutches? ))

https://registry.terraform.io/providers/oVirt/ovirt/latest/docs

terraform {
required_providers {
ovirt = {
source = "oVirt/ovirt"
version = "~> 2.1.5"
}
}
required_version = ">= 1.6.5"
backend "local" {
path = "./.trrraform/terraform.tfstate"
}
}

@cello86
Copy link

cello86 commented Dec 14, 2023

@MikhailRyzhkin you can find a workaround #493 (comment)

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

No branches or pull requests

5 participants