Packer es un Herramienta de creación de imágenes de máquinas virtuales de código abierto desde Hashicorp.
¿Qué es packer?
Packer es una herramienta para crear imágenes de máquinas ya configuradas, de forma automática y repetible, para usarlas en cualquier entorno.
- Qué crea: AMI (AWS), imágenes de GCP, Azure, VMware, VirtualBox, Docker images, etc.
- Qué NO hace: no despliega infraestructura (eso es Terraform), no configura en tiempo real (eso es Ansible).
Conceptos
Estructura mínima de un proyecto Packer
En Windows (igual en Linux):
packer-gcp/
│
├── main.pkr.hcl
├── variables.pkr.hcl
└── ubuntu.pkr.hcl
👉 No es obligatorio separarlo, pero es buena práctica.
Templates (Plantillas)
Los templates son los archivos de configuración que definen cómo Packer debe construir las imágenes.
En ellos se especifican:
- Builders
- Provisioners
- Post-processors
- Variables y parámetros
Nota: Aunque originalmente se escribían en JSON, actualmente el formato recomendado es HCL (.pkr.hcl). Un template permite a Packer crear múltiples imágenes en paralelo de forma reproducible y declarativa.
Ejemplo de un archivo:
ubuntu-gcp.pkr.hcl
Bloques principales (HCL)
En Packer todo se define en bloques.
Define requisitos del propio Packer.
packer {
required_plugins {
googlecompute = {
source = "github.com/hashicorp/googlecompute"
version = ">= 1.0.0"
}
}
}
Conceptos clave:
required_plugins: plugins necesariossource: origen del pluginversion: versión mínima
Plugins
Packer necesita plugins para comunicarse con cada plataforma cloud (como GCP) y usar sus APIs para crear VMs temporales e imágenes.
Builders (ahora llamdo Sources)
El componente que define dónde y cómo se crea la imagen, usando una VM temporal en un proveedor específico (como GCP).
Cada builder:
- Lee una configuración
- Arranca una máquina temporal
- Genera una imagen lista para ser utilizada
Los builders se ejecutan dentro de una build y son responsables de producir los artefactos.
Ejemplos comunes:
amazon-ebsgooglecomputevirtualboxvmware
Ejemplo
source "googlecompute" "ubuntu" {
project_id = "mi-proyecto"
zone = "us-central1-a"
source_image = "ubuntu-2204-jammy-v20240110"
ssh_username = "packer"
}
Nomenclatura importante:
source "<tipo>" "<nombre_logico>"<tipo>: plugin/builder<nombre_logico>: alias interno
Builds (Compilaciones)
Una build es una ejecución completa e independiente que tiene como objetivo producir una imagen para una plataforma específica. Packer puede ejecutar múltiples builds en paralelo, cada una con sus propios pasos y configuraciones.
Cuando se ejecuta Packer, se lanzan una o varias builds que:
- Inician una máquina temporal
- Ejecutan configuraciones
- Generan la imagen final
build {
sources = [
"source.googlecompute.ubuntu"
]
}
📌 Sin build, no se construye nada.
Provisioners (Aprovisionadores)
Los provisioners son los componentes encargados de instalar y configurar software dentro de la máquina en ejecución, antes de que se convierta en una imagen final.
Su función principal es asegurar que la imagen resultante:
- Contenga el software requerido
- Esté configurada correctamente
Ejemplos de provisioners:
- shell
- chef
- puppet
- ansible
Gracias a los provisioners, se obtienen beneficios como:
- Mejor rendimiento (instalaciones costosas ya realizadas)
- Infraestructura inmutable y auto-configurable
Ejemplo:
provisioner "shell" {
inline = [
"sudo apt update",
"sudo apt install -y nginx"
]
}
Post-processors (Posprocesadores)
Los post-processors se ejecutan después de que el builder ha generado un artefacto. Su función es procesar, transformar o distribuir ese artefacto para generar uno nuevo o derivado.
Ejemplos:
- Comprimir imágenes (compress)
- Subir artefactos a un servidor (upload)
- Generar manifiestos (manifest)
Ejemplo:
post-processor "manifest" {
output = "manifest.json"
}
Variables
Son utilizadas para parametrizar configuraciones, permitiendo personalizar, reutilizar y flexibilizar las plantillas de compilación (templates) sin modificar el código fuente.
Ejemplo:
variable "region" {
type = string
default = "us-central1"
}
Uso:
zone = "${var.region}-a"
Variables de entorno
Packer puede leer variables del sistema:
export PACKER_VAR_project_id=mi-proyecto
Uso:
project_id = var.project_id
Funciones
Puede utilizar funciones en plantillas de Packer para transformar y combinar valores. Consulte la documentación oficial para mas información https://developer.hashicorp.com/packer/docs/templates/hcl_templates/functions o https://developer.hashicorp.com/packer/docs/templates/legacy_json_templates/engine#functions
- template_dir: devuelve el directorio del template.
- timestamp: muestra el tiempo actual, como un timestamp de Unix.
- isotime: muestra la fecha actual con el formado dado.
- uuid: es un ID aleatorio con el formato de UUID, lo que hace prácticamente imposible una colisión.
- user: sustituye por una variable de usuario.
- build_name: es el nombre del build que está ejecutándose.
- clean_ami_name: limpia el nombre de caracteres ilegales en AMI.
- lean_image_name: limpia el nombre de caracteres ilegales en Google Compute y otras nubes.
Ejemplo:
image_name = format("img-%s", timestamp())
Communicator
Cómo Packer se conecta a la VM.
Tipos:
ssh(Linux)winrm(Windows)none
Ejemplo:
communicator = "ssh"
Artifacts (Artefactos)
Los artefactos son el resultado final de una ejecución de Packer. Representan la imagen de máquina generada o los identificadores asociados a ella.
Cada builder produce un único artefacto.
Ejemplos:
- En Amazon EC2, el artefacto es un conjunto de AMI, uno por región, identificados por IDs únicos.
- En VMware, el artefacto es un directorio de archivos que contiene la máquina virtual creada.
En términos generales, los artefactos son las imágenes y salidas finales que Packer genera y que luego serán reutilizadas para desplegar infraestructura.
Instalar Packer
Explicaremos el paso a paso, nos guiaremos de la documentación oficial https://developer.hashicorp.com/packer/install.
Vamos a descargar el binario correspondiente la arquitectura del S.O. que tengamos.
Crearemos la siguiente estructura de trabajo:
c:/packer
|__packer.exe
Donde dejaremos el packer.exe dentro del directorio en donde podamos acceder de forma rapida
Por ultimo procedamos a registrar packer en en las variables de entorno para poder acceder desde la consola sin ingresar al directorio:
Procedamos a probar, abrimos una consola CMD y ejecutamos:
packer --version
Respuesta: Packer v1.15.0
Preparar el proyecto
Crea una carpeta (por ejemplo): packer-docker
Dentro crea un archivo: main.pkr.hcl
Contenido mínimo (solo plugins):
packer {
required_plugins {
docker = {
version = ">= 1.0.8"
source = "github.com/hashicorp/docker"
}
}
}
Primeros Comandos en Packer
Los comandos son los subcomandos de la interfaz de línea de comandos (CLI) de Packer que ejecutan acciones específicas.
Nota: si desea continuar con el siguiente ejercicio, recomiendo leer como preparar el proyecto.
packer init
Se utiliza para descargar e instalar complementos segun los requerimientos del bloque required_plugins
Recomendamos ejecutar el comando packer init como primer paso al trabajar con una plantilla nueva o existente.
Desde la carpeta del proyecto:
packer init .
Respuesta
Installed plugin github.com/hashicorp/googlecompute v1.2.5 in "C:/Users/ofernandezigeoerp/AppData/Roaming/packer.d/plugins/github.com/hashicorp/googlecompute/packer-plugin-googlecompute_v1.2.5_x5.0_windows_386.exe"
Qué hace:
- Lee el bloque packer
- Descarga el plugin de GCP
- Prepara el entorno
🔑 No crea nada en GCP.
Nota: Punto clave que debes recordar:
- Sin
packer init→packer buildfalla - Se ejecuta una vez por proyecto (o cuando cambian plugins)
packer validate
Verifica la sintaxis y la configuración de una plantilla de packer antes de ejecutar una compilación. Comprueba si el archivo .pkr.hcl o .json es sintácticamente correcto, si los tipos de variables son adecuados y si los componentes necesarios.
packer validate .
Resultados: Devuelve un código de salida 0 si es exitoso (válido) y un código distinto de cero si hay errores, mostrando los mensajes de error correspondientes.
Link documentación oficial: https://developer.hashicorp.com/packer/docs/commands/validate
packer build
El comando packer build ejecuta el proceso automatizado definido en una plantilla de Packer (archivo .pkr.hcl o .json) para crear imágenes de máquina idénticas (como AMIs de AWS, imágenes de Docker, máquinas virtuales VMware o Azure) para múltiples plataformas simultáneamente a partir de una configuración única.
- Aprovisionamiento Automatizado: Inicia una máquina virtual, ejecuta scripts (shell, Ansible, Chef, Puppet) para instalar y configurar software, y luego apaga la máquina.
- Creación de Artefactos: Genera imágenes de máquinas listas para usar, lo que acelera el despliegue de infraestructura inmutable.
- Paralelismo: Crea imágenes para diferentes proveedores de nube (ej. AWS y Azure) al mismo tiempo, garantizando consistencia.
- Estructura del proceso: Utiliza componentes de builders (creadores), provisioners (aprovisionadores) y post-processors (posprocesadores) definidos en la plantilla.
packer build .