En esta ocasión, nos centraremos en cómo automatizar despliegues de máquinas virtuales en una infraestructura on-premise operada con Proxmox. Usaremos Ansible tanto para comunicarnos con Proxmox como para hacer la configuración de la máquina después del despliegue.
Para poder poner en práctica la automatización, es deseable tener configurado un escenario que cuente con VLANs configuradas, un servidor de DHCP en cada una de las VLANs y una zona DNS con actualización dinámica por DHCP (RFC 2136).
En nuestro caso, tenemos configurado Pfsense como firewall y servidor DHCP de las dos VLANs:
Para mayor información sobre estas configuraciones, consultar los enlaces correspondientes:
Por último, debemos tener disponibles plantillas de máquinas virtuales. En nuestro caso, solo usaremos plantillas de Ubuntu y Debian. A partir de estas plantillas, el automatismo podrá generar las nuevas máquinas virtuales. Para más información, consultar el siguiente enlace.
Para esta automatización, hemos preparado el repositorio proxmox-ansible. Se trata de un role de Ansible que realiza acciones concretas en función de la variable action
. Concretamente, este role permite realizar dos acciones que nos interesan en este momento:
create_vm
: Clona de una máquina virtual a partir de una plantilla existente. Para más información, accede aquí.delete_vm
: Borra una máquina virtual. Para más información, accede aquí.Para usar este role, tenemos dos opciones:
~/.ansible/roles/
e instalar las dependencias que aparecen en el fichero requirements.txt
.atorrescogollo/proxmox-ansible:latest
.En este caso, usaremos la imagen de docker del siguiente modo:
create_vm.yml
indicando la acción create_vm
y los parámetros que requiere:
$ cat create_vm.yml - name: Create VM hosts: localhost roles: - role: proxmox-ansible vars: action: create_vm proxmox_host: 10.0.0.2:8006 proxmox_user: user@pam proxmox_pass: password vm_name: testvm01 cpu_sockets: 1 cpu_cores: 1 ram_mb: 2048 disk_gb: 20 datastore: ds01 vlan: 2 template_name: TEMPLATE-UBUNTU-SERVER-20-04 proxmox_node: proxmoxnode01
$ docker run --rm \ -v "$PWD/create_vm.yml:/playbook.yml" \ atorrescogollo/proxmox-ansible:latest
Por otro lado, el borrado de la máquina, se podría ejecutar de igual forma pero usando el playbook delete_vm.yml
:
$ cat delete_vm.yml - name: Delete VM hosts: localhost roles: - role: proxmox-ansible vars: action: delete_vm proxmox_host: 10.0.0.2:8006 proxmox_user: user@pam proxmox_pass: password vm_name: testvm01
$ docker run --rm \ -v "$PWD/delete_vm.yml:/playbook.yml" \ atorrescogollo/proxmox-ansible:latest
Una vez ya podemos crear máquinas de forma automatizada, necesitamos realizar algunas configuraciones. Por ejemplo, queremos adecuar los volumenes lógicos de LVM, actualizar el nombre del host según el nombre de la máquina virtual, actualizar los paquetes de la máquina, etc.
Todas las configuraciones para máquinas Linux forman parte de otro role de Ansible disponible en el repositorio linux-ansible y, de igual modo, podemos configurar la máquina que acabamos de desplegar. El procedimiento, en este caso, es ligeramente distinto ya que necesitamos un inventario:
post_deploy.yml
:
$ cat post_deploy.yml - name: Configure VM hosts: vms roles: - role: linux-ansible vars: action: post_deploy lvmap: "/tmp": "+500M" "/var/log": "2G" "/var": "+30%FREE" "/": "+100%FREE" install_packages: - vim - tmuxSimilar a lo que vimos anteriormente, estos parámetros se pueden consultar en este enlace. En esta documentación, además, se indica que la acción post_deploy simplemente es una agrupación de acciones, por lo que podemos personalizar nuestro despliegue en función de lo que necesitemos.
$ cat inventory.ini [vms] testvm01.example.org ansible_host=10.0.2.150 [vms:vars] ansible_user=adminuser ansible_ssh_extra_args='-o StrictHostKeyChecking=no'Es importante definir la IP ya que la plantilla aún no tiene el hostname correcto por lo que el DNS no ha registrado ese hostname. Además, el usuario con el que nos vamos a conectar necesita tener acceso con sudo sin contraseña para realizar las tareas que requieren ciertos privilegios.
atorrescogollo/linux-ansible:latest
:
$ ssh-add ~/.ssh/id_rsa # Cargar la clave privada en ssh-agent $ docker run -it --rm \ -v $SSH_AUTH_SOCK:/ssh-agent \ -e SSH_AUTH_SOCK=/ssh-agent \ -v $PWD/inventory.ini:/inventory \ -v $PWD/post_deploy.yml:/playbook.yml \ atorrescogollo/linux-ansible:latestCabe destacar que, en este caso, hemos tenido que compartir el
ssh-agent
con el contenedor a través de la variable de entorno SSH_AUTH_SOCK
para poder usar la clave privada cargada con ssh-add
. Para más información sobre esta característica, acceder a este enlace.Hemos logrado estandarizar el proceso de creación y configuración de máquinas virtuales. Esto nos permite definir políticas de bastionado, configuraciones comunes en todo el entorno, etc, que se aplicarán en todos los despliegues.
También, hemos propuesto un tratamiento distinto al modelo estándar de roles de Ansible. En este caso, cada role agrupa todas las automatizaciones realizacionadas con un ámbito concreto usando la variable action. Por ejemplo, proxmox-ansible
es el role que trata todos los procedimientos de interacción con nuestro hipervisor y linux-ansible
es el role que define todos los procedimientos de configuración de máquinas Linux.
Por otro lado, cabe mencionar que existen otros mecanismos para ejecutar la configuración de una máquina después del despliegue: cloud-init
suele ser la opción más usada. Esto no quiere decir que la fase de configuración de la máquina sea completamente reemplazable por cloud-init
. Habiendo implementado el role linux-ansible
tenemos dos posibilidades:
cloud-init
.Por tanto, Ansible nos aporta, principalmente, dos beneficios con respecto a otras opciones:
Sabiendo esto, ¿te atreves a automatizar tu infraestructura?
Álvaro Torres Cogollo.
Quieres contactar conmigo? Te dejo mis redes sociales a continuación.