Packer para VMware (Parte 1): Creación de plantilla de Windows automatizada

En la entrada anterior hablamos sobre la creación de plantillas automatizada con Packer y de como podía ésta ayudarnos en la automatización de nuestros despliegues. En la entrada de hoy veremos el uso de Packer para VMware, con el que desplegaremos de forma totalmente automatizada una instalación de Windows Server 2016 en una infraestructura vSphere.

Packer para VMware - Creación de plantilla de Windows automatizada

Escogiendo builder de Packer para VMware

Como comenté en la entrada anterior, existen builders creados por Hashicorp para la gran mayoría de plataformas de virtualización y cloud del mercado. En el caso del plugin de vSphere existe VMware-iso, un builder que permite la creación de imágenes a través de una ISO de sistema operativo.

El handicap de VMware-iso es que se conecta a través de SSH para la interacción con la plataforma, y como sabemos no siempre es adecuado tener el acceso SSH abierto a nuestra infraestructura o incluso se puede dar el caso de que no dispongamos de los permisos necesarios para habilitarlo.

Es por eso que yo me decanto por utilizar vSphere-iso, un builder desarrollado por Jetbrains que utiliza la API nativa de vSphere para realizar todas las operaciones contra la plataforma, por lo que lo único que necesitaremos será un usuario de vSphere con suficientes privilegios para realizar las acciones que necesitemos.

Antes de empezar

La única infraestrucura necesaria para seguir con esta entrada será la siguiente:

  • Una infraestructura vSphere sobre la que realizar el deploy de la plantilla.
  • Una máquina con Packer instalado, tal como vimos en la anterior entrada (puede ser nuestra propia máquina sin problemas).
  • Un servidor DHCP en la VLAN en la que vayamos a desplegar la plantilla (Packer necesita que la plantilla tenga una IP para conectarse por WinRM después de la instalación).

En mi caso voy a ejecutar Packer desde una máquina con CentOS 7, pero el código debería funcionar independientemente de la plataforma que ejecute Packer.

Para hacer todo esto más fácil he creado un repositorio en GitHub con el código que vamos a utilizar en esta entrada, por lo que en algunos archivos solo resaltaré las partes más destacadas que tendremos que editar para hacerlo funcionar. Para que el ejemplo funcione deberemos respetar la estructura de carpetas del «proyecto»:

.
├── setup
│   ├── autounattend.xml
│   ├── setup.ps1
│   └── vmtools.cmd
├── template_ws2016.json
└── vars_ws2016.json

¡Empecemos!

Creando el archivo de variables

Como comenté en la entrada anterior, podemos utilizar variables en nuestras templates que nos ayudarán a crear archivos mucho más reusables y claros. Éstas variables pueden ser definidas tanto en la propia template como en un archivo externo al que llamaremos cuando vayamos a construir nuestra plantilla. Si decidís utilizar los archivos del repositorio como base para vuestra implementación éste es el archivo que más deberéis modificar.

Para esta entrada utilizaremos el archivo vars_ws2016.json que podemos encontrar en el repositorio de GitHub de la entrada.

{
    "vsphere_server": "vcsa.sobrebits.local",
    "vsphere_user": "packer@vsphere.local",
    "vsphere_password": "Vsphere.12345",
    "vsphere_template_name": "Template-Windows2016",
    "vsphere_folder": "Templates",
    "vsphere_dc_name": "SobrebitsDatacenter",
    "vsphere_compute_cluster": "SobrebitsCluster",
    "vsphere_host": "esxi01.sobrebits.local",
    "vsphere_portgroup_name": "VM Network",
    "vsphere_datastore": "Datastore1",
    "winadmin_password": "Template.12345",
    "cpu_num": "2",
    "mem_size": "4096",
    "disk_size": "32768",
    "os_iso_path": "[Datastore1]_ISOs/Windows2016.iso",
    "vmtools_iso_path":"[Datastore1]_ISOs/vmtools.iso"
}

He intentado que los nombres de las variables sean lo más autoexplicativos posibles, pero igualmente los repasaremos por si hay dudas:

  • vsphere_server: Servidor vSphere al que nos conectaremos para desplegar la plantilla.
  • vsphere_user: Usuario con el que conectaremos a vSphere.
  • vsphere_password: Password del usuario.
  • vsphere_template_name: Nombre que recibirá la plantilla que creemos.
  • vsphere_folder: Carpeta de vSphere en la que crearemos la plantilla.
  • vsphere_dc_name: Datacenter en el que se ubicará la plantilla.
  • vsphere_compute_cluster: Cluster en el que se ubicará la plantilla.
  • vsphere_host: Servidor que alojará la plantilla.
  • vsphere_portgroup_name: Red (tipo portgroup) que asociaremos a la plantilla.
  • cpu_num: Número de CPUs con los que se creará la plantilla.
  • mem_size: Cantidad de RAM en MB con la que se creará la plantilla.
  • disk_size: Cantidad de disco en MB con el que se creará la plantilla.
  • os_iso_path: Ubicación de la ISO que se montará en la plantilla para la instalación del sistema operativo (un datastore que pueda ver el servidor ESXi que ejecuta la plantilla).
  • vmtools_iso_path: Ubicación de la ISO con las VMware Tools (un datastore que pueda ver el servidor ESXi que ejecuta la plantilla).

Deberemos configurar el archivo de variables para adaptarse a nuestro entorno y a las configuraciones que deseemos para nuestra plantilla. Una vez tengamos las variables definidas ya podemos pasar a diseñar la plantilla de Packer que las utilizará.

Diseñando la plantilla de instalación

Para construir nuestra plantilla de sistema operativo, Packer utiliza un archivo de template en formato Json en el que tenemos que ajustar todas las configuraciones que querremos para la misma. Para esta parte nos centraremos en el archivo template_ws2016.json del repositorio de GitHub y veremos las distintas configuraciones a aplicar.

Vamos a repasar por partes el archivo:

  "variables": {
    "vsphere_server": "",
    "vsphere_user": "",
    "vsphere_password": "",
    "vsphere_template_name": "",
    "vsphere_folder": "",
    "vsphere_dc_name": "",
    "vsphere_compute_cluster": "",
    "vsphere_host": "",
    "vsphere_portgroup_name": "",
    "vsphere_datastore": "",
    "winadmin_password": "",
    "cpu_num": "",
    "mem_size": "",
    "disk_size": "",
    "os_iso_path": "",
    "vmtools_iso_path":""
  },
  "sensitive-variables": ["vsphere_password", "winadmin_password"],

En el primer bloque (variables) declaramos todas las variables que hemos definido en nuestro archivo y que serán necesarias para la ejecución de la plantilla. En el segundo bloque (sensitive-variables) indicamos que vsphere_password y winadmin_password tienen contenido sensible y que no queremos que se muestren sus valores por consola en el momento de la ejecución de Packer.

En la entrada anterior ya hablamos de los builders, que son los encargados de conectarse con nuestra infraestructura y desplegar las plantillas. Veamos como queda nuestro builder de vSphere:

  "builders": [
    {
      "type": "vsphere-iso",

      "vcenter_server":      "{{user `vsphere_server`}}",
      "username":            "{{user `vsphere_user`}}",
      "password":            "{{user `vsphere_password`}}",
      "insecure_connection": "true",

      "vm_name": "{{user `vsphere_template_name`}}",
      "folder" : "{{user `vsphere_folder`}}",
      "datacenter": "{{user `vsphere_dc_name`}}",
      "cluster":     "{{user `vsphere_compute_cluster`}}",
      "host": "{{user `vsphere_host`}}",
      "network": "{{user `vsphere_portgroup_name`}}",
      "datastore": "{{user `vsphere_datastore`}}",
      "convert_to_template": "true",
      "shutdown_command": "C:/Windows/System32/Sysprep/sysprep.exe /oobe /shutdown",

      "guest_os_type": "windows9Server64Guest",

En esta primera parte básicamente nos dedicamos a configurar todos los aspectos relacionados con la infraestructura vSphere que ya hemos explicado en variables. Algunas cosas nuevas son:

  • type: Aquí hemos definido nuestro builder, que para esta entrada como hemos explicado anteriormente será vsphere-iso.
  • insecure_connection: Indicamos que no valide el certificado SSL de nuestro vCenter (mi experiencia me dice que la gran mayoría de infraestructuras vSphere tienen certificado autofirmado).
  • convert_to_template: Definimos que queremos que al finalizar la construcción de la plantilla la marque como template en nuestro vCenter.
  • shutdown_command: Indicamos que para realizar el apagado del sistema operativo al finalizar la construcción de la plantilla se ejecute sysprep para sellar la misma.
  • guest_os_type: Establecemos el tipo de sistema operativo invitado que tendrá nuestra máquina virtual (en este caso Windows Server 2016).

Sigamos con el archivo:

      "communicator": "winrm",
      "winrm_username": "Administrador",
      "winrm_password": "{{user `winadmin_password`}}",

Una vez haya finalizado la instalación, Packer deberá conectarse a la máquina virtual para aplicar las configuraciones que le indiquemos. Aquí estamos definiendo que lo haga por WinRM (tal y como vimos con PowerShell Remoting) utilizando el usuario Administrador y el password definido en nuestro archivo de variables.

      "CPUs":             "{{user `cpu_num`}}",
      "RAM":              "{{user `mem_size`}}",
      "firmware": "bios",

      "disk_controller_type":  "lsilogic-sas",
      "disk_size":        "{{user `disk_size`}}",
      "disk_thin_provisioned": true,

      "network_card": "vmxnet3",

      "iso_paths": [
        "{{user `os_iso_path`}}",
        "{{user `vmtools_iso_path`}}"
      ],

Aquí definimos los recursos de la máquina así como algunas configuraciones de hardware como el tipo de tarjeta, la bios o el formato thin del disco.

Además indicamos las rutas de las iso que se montarán en la plantilla y que ya habíamos definido en el archivo de variables: la iso de Sistema Operativo y la iso de las VMware Tools.

Vamos con la última parte que veremos hoy:

      "floppy_files": [
        "/root/packer/test/setup/autounattend.xml",
        "/root/packer/test/setup/setup.ps1",
        "/root/packer/test/setup/vmtools.cmd"
      ]

Aquí definimos la ubicación de los achivos que pasaremos como floppy cuyo path deberemos editar para que cuadre con la ubicación de la carpeta de nuestro proyecto. Estos archivos serán los encargados de (ahí va spoiler de la próxima entrada):

  • Establecer los parámetros de configuración de la instalación de Windows.
  • Configuración de WinRM para la ejecución de Provisioners.
  • Instalar las VMware Tools.

Conclusión

Y hasta aquí la primera parte de nuestra guía de creación de plantilla de Windows automatizada con Packer. En la próxima entrada acabaremos de descubrir las distintas partes implicadas en la instalación y configuración de nuestra plantilla y descubriremos qué más cosas podremos realizar con ésta.

¡Espero veros por aquí!

Deja un comentario