Tarea 4: Introducción a OpenTofu + libvirt
-
Vamos a descargar las imágenes cloud con las que vamos a trabajar. Las vamos a copiar en el directorio correspondiente al pool
default:cd /var/lib/libvirt/images sudo wget https://cloud.debian.org/images/cloud/trixie/daily/latest/debian-13-genericcloud-amd64-daily.qcow2 -O debian13-base.qcow2 sudo wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img -O ubuntu2404-base.qcow2Las imágenes bases se llaman
debian13-base.qcow2yubuntu2404-base.qcow2.Estos discos son muy pequeños, por lo tanto antes de empezar a utilizarlos vamos a redimensionarlos:
sudo qemu-img resize debian13-base.qcow2 10G sudo qemu-img resize ubuntu2404-base.qcow2 10G -
Instala OpenTofu. Vamos a trabajar con el repositorio ejercicios_pi que ya tienes en tu equipo. Para cada ejemplo nos situamos en el directorio opentofu/ejemploX correspondiente.
Ejemplo 1: Máquina virtual conectada a la red “default”
En este ejemplo vamos a crear una máquina virtual conectada a la red default. OpenTofu trabaja con ficheros tf que se pueden llamar como queramos. Veamos los ficheros con los que vamos a trabajar:
-
provider.tf: Configura el providerdmacvicar/libvirty la URI de conexión (qemu:///system). El plugin del provider se instala en el directorio.terraformcuando ejecutamostofu init. Este comando normalmente sólo se ejecuta una vez. Este fichero no hay que modificarlo. -
variables.tf: Se declaran variables globales, que podemos usar en nuestras definiciones. En este caso se definen:var.libvirt_pool_name: nombre del pool de almacenamiento donde se crean los volúmenes. Su valor por defecto esdefault.var.base_image: nombre de la imagen base en el pool. Su valor por defecto esdebian13-base.qcow2.
-
cloud-init/user-data1.yaml: Fichero para configurar la máquina virtual con el mecanismo de cloud-init. En este ejemplo:- Se indica el hostname, zona horaria, locale y teclado.
- Se configura el usuario
debiancon acceso sudo sin contraseña, clave ssh y contraseña. - Se instala
qemu-guest-agenty se actualiza el sistema.
Debes modificar este fichero para añadir tu clave pública en el campo
ssh-authorized-keys. -
main.tf: Aquí está la definición de los recursos con los que queremos trabajar. En este fichero se definen los siguientes recursos:resource "libvirt_volume" "ej1-server1-disk": Un clon ligero sobre la imagen base indicada porvar.base_image, usandobase_volume_nameybase_volume_pool.resource "libvirt_cloudinit_disk" "ej1-server1-cloudinit": Un disco con formato ISO donde se guarda el ficherocloud-init/user-data1.yaml.resource "libvirt_domain" "ej1-server1": Una máquina virtual con 1024 MB de RAM, 2 vCPUs, conectada a la reddefaulty con consola serie habilitada.
-
output.tf: Se define la información que se mostrará al terminar de crear el escenario (nombre e IP de la máquina). Este fichero no hay que modificarlo.
Modifica cloud-init/user-data1.yaml para añadir tu clave pública y, si lo deseas, main.tf para cambiar la memoria o el número de CPUs.
Una vez hechos los cambios, los comandos se ejecutan en el directorio del proyecto:
- Ejecutamos una sola vez el comando
tofu initpara instalar el plugin del provider. - Ejecutamos el comando
tofu planpara ver las acciones que se van a realizar. - Para aplicar el escenario descrito ejecutamos
tofu apply. - Una vez creado el escenario nos saldrá la información definida en
output.tf. Esta información siempre se puede mostrar ejecutandotofu output. - Podemos ver el estado de los recursos ejecutando
tofu show. - Para eliminar todos los recursos creados, ejecutamos
tofu destroy.
Ejemplo 2: Máquina virtual con disco adicional
Nos situamos en el directorio opentofu/ejemplo2. Este ejemplo es similar al anterior, pero en esta ocasión la máquina virtual tiene un disco adicional de 1 GB. En el fichero main.tf se declaran 4 recursos:
libvirt_volume "ej2-server1-disk": el disco principal creado con clonación enlazada.libvirt_volume "ej2-server1-disk-extra1": un disco adicional vacío de 1 GB (el tamaño se indica en bytes:1 * 1024 * 1024 * 1024).libvirt_cloudinit_disk "ej2-server1-cloudinit": el disco ISO con la configuración cloud-init.libvirt_domain "ej2-server1": la máquina virtual, con dos entradasdiskpara el disco principal y el extra.
Ejemplo 3: Máquina virtual conectada a dos redes con DHCP
Nos situamos en el directorio opentofu/ejemplo3. En este ejemplo vamos a comenzar a trabajar con las redes. En los dos ejemplos anteriores habíamos conectado la máquina virtual a la red default, que no es gestionada por OpenTofu. En este ejemplo vamos a crear redes gestionadas por OpenTofu, que se crearán con tofu apply y se eliminarán con tofu destroy.
Se ha añadido el fichero network.tf donde se define la red:
resource "libvirt_network" "ej3-nat-dhcp": una red NAT con DHCP en el rango192.168.100.0/24. Estudia los parámetros que hemos indicado.
A continuación estudia la definición del recurso de la máquina virtual en el fichero main.tf y comprueba que la máquina está conectada a dos redes (como en el ejemplo 2, también tiene un disco adicional de 1 GB). Recuerda que cuando conectamos a una red con servidor DHCP indicamos el parámetro wait_for_lease = true.
- Cuando la red no es creada por OpenTofu, por ejemplo
default, indicamos el nombre con el parámetronetwork_name. - Cuando la red es gestionada por OpenTofu, indicamos su id con el parámetro
network_id, por ejemplo:network_id = libvirt_network.ej3-nat-dhcp.id.
El hecho de que conectemos una máquina virtual a dos redes no significa que netplan configure las dos interfaces. Tenemos que configurarlo nosotros, para ello:
- Se ha creado el fichero
cloud-init/network-config1.yaml, donde se guarda la configuración netplan de la máquina. - Este fichero se añade en la imagen ISO junto al fichero
cloud-init/user-data1.yaml. Esto se hace con el parámetronetwork_configdel recursolibvirt_cloudinit_disk "ej3-server1-cloudinit"en el ficheromain.tf.