terraform-provider-ovirt
terraform-provider-ovirt copied to clipboard
Configure NIC with static ip
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
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.
Thanks @engelmi, I've read that example, but you cannot specify a static IP configuration in the ovirt vnic profile (ovirt 4.4).
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.
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
}
I have the same issue.
How to configure the VM to set up an ip addresses? There is any way using init scripts ?
Do you have some updates ? This is a blocking issue for the new version of this provider
@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
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.
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" } }
@MikhailRyzhkin you can find a workaround https://github.com/oVirt/terraform-provider-ovirt/issues/493#issuecomment-1657836723