Skip to content

353.2 Packer (weight: 2)

Description: Candidates should be able to use Packer to create system images. This includes running Packer in various public and private cloud environments as well as building container images for LXC/LXD.

Key Knowledge Areas:

Understand the functionality and features of Packer
Create and maintain template files
Build images from template files using different builders

Partial list of the used files, terms and utilities:

packer

Packer le permite crear imágenes de máquinas idénticas para varias plataformas a partir de una única configuración de origen.

Ordenes

packer hcl2_upgrade lxc.json
packer build virtualboxiso.pkr.hcl
packer init plugin_virtualbox.pkr.hcl 
packer plugins installed
packer validate lxc.pkr.hcl

Plugins

Packer utiliza plugins para funcionar con las imagenes de diferentes plataformas

Este es un ejemplo de plugin de virtualbox

plugin_virtualbox.pkr.hcl

packer {
required_plugins {
    virtualbox = {
    version = ">= 0.0.1"
    source = "github.com/hashicorp/virtualbox"
    }
}
}

Iniciar plugin y verificar instalacion

➜  packer init plugin_virtualbox.pkr.hcl 
➜  packer plugins installed

Plantillas

El comportamiento de Packer está determinado por la plantilla de Packer, que consta de una serie de declaraciones y comandos que debe seguir Packer. Esta plantilla le dice a Packer qué complementos (constructores, aprovisionadores, posprocesadores) usar, cómo configurar cada uno de esos complementos y en qué orden ejecutarlos.

Packer utiliza plantillas para generar la imagen que queremos crear, como por ejemplo la siguiente:

 cat lxc.pkr.hcl

source "lxc" "lxc-debian" {
    config_file               = "/etc/lxc/default.conf"
    template_environment_vars = ["SUITE=bullseye"]
    template_name             = "debian"
}

build {
    sources = ["source.lxc.lxc-debian"]
}

Las plantillas de packer pueden escribirsde en JSON o HCL2, aun que se recomienda HCL2

Para crear la imagen se utiliza la opcion build

packer build lxc.pkr.hcl

Se generan los archivos en un directorio output

➜ ls -1 output-lxc-debian 
lxc-config
rootfs.tar.gz

Json to hcl2

En el caso de tener una plantilla Json se puede trasformar a hcl2 con packer hcl2_upgrade <template>

lxc.json

{
"builders": [
    {
    "type": "lxc",
    "name": "lxc-debian",
    "config_file": "/tmp/lxc/config",
    "template_name": "debian",
    "template_environment_vars": ["SUITE=bullseye"]
    },
]
}

pasar archivo json a hcl2

packer hcl2_upgrade lxc.json

 ls -1
lxc.json
lxc.json.pkr.hcl

 cat lxc.json.pkr.hcl

source "lxc" "lxc-debian" {
    config_file               = "/etc/lxc/default.conf"
    template_environment_vars = ["SUITE=bullseye"]
    template_name             = "debian"
}

build {
    sources = ["source.lxc.lxc-debian"]
}

Providers

Los aprovisionadores utilizan software integrado y de terceros para instalar y configurar la imagen de la máquina después del arranque. Los aprovisionadores preparan el sistema, por lo que es posible que desee usarlos para los siguientes casos de uso:

  • instalando paquetes
  • parcheando el kernel
  • creando usuarios
  • descargando el código de la aplicación

Por ejemplo despues de crear el container actualiza y crea un usuario mediante dos scripts

 cat scripts/update.sh 
#!/bin/bash -eux

apt update -y
apt upgrade -y
apt install -y sudo

 cat scripts/sudoers.sh 
#!/bin/bash -eux

useradd -m -s /bin/bash -G sudo mandarina
echo 'mandarina ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/99_mandarina;
chmod 440 /etc/sudoers.d/99_mandarina;

virtualboxiso.pkr.hcl

source "virtualbox-iso" "basic-example" {
    guest_os_type = "Ubuntu_64"
    iso_url = "http://releases.ubuntu.com/12.04/ubuntu-12.04.5-server-amd64.iso"
    iso_checksum = "md5:769474248a3897f4865817446f9a4a53"
    ssh_username = "packer"
    ssh_password = "packer"
    shutdown_command = "echo 'packer' | sudo -S shutdown -P now"
}

build {
    sources = ["sources.virtualbox-iso.basic-example"]

    provisioner "shell" {
        environment_vars    = ["HOME_DIR=/home/mandarina"]
        execute_command     = "echo 'mandarina' | {{ .Vars }} sudo -s -E sh -eux '{{ .Path }}'"
        expect_disconnect   = true
        scripts             = ["scripts/update.sh", "scripts/sudoers.sh"]
    }
}

Post-Processors

Post-processors run after builders and provisioners. Post-processors are optional, and you can use them to upload artifacts, re-package files, and more. The documentation includes a page for each type of post-processor.

virtualboxiso.pkr.hcl

source "virtualbox-iso" "basic-example" {
    guest_os_type = "Ubuntu_64"
    iso_url = "http://releases.ubuntu.com/12.04/ubuntu-12.04.5-server-amd64.iso"
    iso_checksum = "md5:769474248a3897f4865817446f9a4a53"
    ssh_username = "packer"
    ssh_password = "packer"
    shutdown_command = "echo 'packer' | sudo -S shutdown -P now"
}

build {
    sources = ["sources.virtualbox-iso.basic-example"]

    provisioner "shell" {
        environment_vars    = ["HOME_DIR=/home/mandarina"]
        execute_command     = "echo 'mandarina' | {{ .Vars }} sudo -s -E sh -eux '{{ .Path }}'"
        expect_disconnect   = true
        scripts             = ["scripts/update.sh", "scripts/sudoers.sh"]
    }

    post-processor "mandarina" {
        output  = "output/ubuntu-20.04-{{ .Provider }}.box"
        compression_level   = "8"
    }
}

creacion Ubuntu server

https://ubuntu.com/server/docs/install/autoinstall-quickstart

➜ tree 
.
├── http
│   ├── meta-data
│   └── user-data
├── iso
│   └── ubuntu-22.10-live-server-amd64.iso
└── virtualboxiso.pkr.hcl

virtualboxiso.pkr.hcl

source "virtualbox-iso" "basic-example" {
    boot_wait = "5s"
    boot_command = ["<enter><enter><f6><esc><wait>", "autoinstall ds=nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/", "<enter>"]
    http_directory = "http"
    guest_os_type = "Ubuntu_64"
    iso_url = "iso/ubuntu-22.10-live-server-amd64.iso"
    iso_checksum = "md5:874452797430a94ca240c95d8503035aa145bd03ef7d84f9b23b78f3c5099aed"
    ssh_username = "packer"
    ssh_password = "packer"
    shutdown_command = "echo 'packer' | sudo -S shutdown -P now"
    format = "ova"
    ssh_timeout = "10000s"
    vm_name = "ubuntu_pacher"
    vboxmanage = [
        ["modifyvm", "{{ .Name }}", "--memory", "1024"], 
        ["modifyvm", "{{ .Name }}", "--vram", "36"],
        ["modifyvm", "{{ .Name }}", "--cpus", "2"],
    ]
}

build {
    sources = ["sources.virtualbox-iso.basic-example"]
}

user-data

➜ cat http/user-data

#cloud-config
autoinstall:
version: 1
early-commands:
    - systemctl stop ssh
    locale: es_ES
    keyboard:
        layout: es
identity:
    hostname: vagrant
    password: "$6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0"
    username: vagrant
    ssh:
        install-server: yes
        allow-pw: yes