Packer: Automatizando a Criação de Imagens de Máquina com Infraestrutura Imutável

O que é o Packer?
Packer é uma ferramenta open-source da HashiCorp que permite criar imagens de máquina idênticas para múltiplas plataformas a partir de uma única template. Seja uma AMI na AWS, uma imagem no GCP, um VHD no Azure ou uma VM no VirtualBox — o Packer gera todas com a mesma configuração, eliminando o temido "na minha máquina funciona".
Lançado em 2013, o Packer faz parte do ecossistema HashiCorp (junto com Terraform, Consul, Vault e Nomad) e é a peça central para quem adota infraestrutura imutável: ao invés de atualizar servidores em produção, você cria novas imagens com as alterações e as substitui.
Por que usar Packer?
Gerenciar servidores manualmente ou com scripts de configuração pós-boot (como Ansible no startup) funciona até certo ponto, mas traz problemas:
- Derivação de configuração: Servidores envelhecidos acumulam mudanças manuais, pacotes obsoletos e configurações divergentes
- Reprodutibilidade: Scripts de boot dependem de repositórios externos que podem mudar ou ficar indisponíveis
- Velocidade de provisionamento: Um servidor que leva 15 minutos para configurar no startup atrasa autoscaling e deploys
Com o Packer, tudo isso é resolvido: a imagem já nasce com o sistema operacional, aplicação, dependências e configurações — o boot se torna uma questão de segundos.
Arquitetura do Packer
O Packer funciona com três conceitos principais:
- Builders: Responsáveis por criar a máquina virtual na plataforma alvo (ex:
amazon-ebs,googlecompute,virtualbox-iso) - Provisioners: Executam scripts, ferramentas de configuração ou upload de arquivos dentro da VM durante o build (ex: shell, Ansible, Chef, Puppet, Salt, PowerShell)
- Post-processors: Etapas executadas após a imagem ser criada — compressão, upload para registries, criação de versões, etc.
Exemplo Prático: AMI AWS com Nginx
// template.pkr.hcl
packer {
required_plugins {
amazon = {
version = ">= 1.0.0"
source = "github.com/hashicorp/amazon"
}
}
}
source "amazon-ebs" "ubuntu" {
ami_name = "nginx-server-{{timestamp}}"
instance_type = "t3.micro"
region = "us-east-1"
source_ami_filter {
filters = {
name = "ubuntu/images/hvm-ssd/ubuntu-24.04-amd64-server-*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true
}
ssh_username = "ubuntu"
}
build {
name = "nginx-ami"
sources = ["source.amazon-ebs.ubuntu"]
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y nginx",
"sudo systemctl enable nginx"
]
}
provisioner "file" {
source = "./nginx.conf"
destination = "/tmp/nginx.conf"
}
provisioner "shell" {
inline = [
"sudo mv /tmp/nginx.conf /etc/nginx/nginx.conf",
"sudo systemctl start nginx"
]
}
post-processor "manifest" {
output = "manifest.json"
}
}HCL vs JSON: O Novo Padrão
Desde a versão 1.7, o Packer adotou o HCL (HashiCorp Configuration Language) como formato primário de templates, substituindo o JSON. O HCL é mais legível, suporta variáveis, funções, loops e expressões condicionais — exatamente como no Terraform.
Exemplo de variáveis em HCL:
variable "ami_prefix" {
type = string
default = "my-app"
}
locals {
timestamp = formatdate("YYYYMMDD-hhmmss", timestamp())
}
source "amazon-ebs" "example" {
ami_name = "${var.ami_prefix}-${local.timestamp}"
// ...
}Packer + Ansible: O Combo Perfeito
O provisioner mais poderoso do Packer é o Ansible. Você pode usar seus playbooks existentes para configurar a imagem:
build {
sources = ["source.amazon-ebs.ubuntu"]
provisioner "ansible" {
playbook_file = "./playbook.yml"
extra_arguments = [
"--extra-vars", "environment=production"
]
}
}Isso significa que você pode manter seus playbooks Ansible como única fonte de verdade e usá-los tanto no Packer (para criar imagens) quanto em servidores existentes (para configuração inicial).
Integração com CI/CD
O Packer brilha quando integrado a pipelines de CI/CD. Um fluxo típico:
- Desenvolvedor faz commit de alterações no repositório da aplicação
- CI/CD executa testes automatizados
- Packer constrói uma nova imagem com a versão atualizada
- Post-processor faz upload para o registry (ECR, Docker Hub, etc.)
- Terraform atualiza o autoscaling group com a nova AMI
- Rolling deployment substitui as instâncias antigas
# Exemplo de pipeline GitHub Actions
- name: Build AMI with Packer
run: |
packer init .
packer build -var "ami_prefix=my-app-${{ github.sha }}" .Boas Práticas com Packer
- Prefira HCL sobre JSON: HCL é mais expressivo, testável e reutilizável, além de ser o formato oficial recomendado pela HashiCorp
- Marque suas imagens: Use tags como
version,built-by,environmentpara rastrear a origem de cada imagem - Versione os templates: Mantenha os templates Packer no mesmo repositório da aplicação — a imagem é um artefato do código
- Mantenha imagens enxutas: Instale apenas o necessário para a aplicação funcionar. Imagens menores sobem mais rápido, reduzem custos e a superfície de ataque
- Use source_ami_filter: Sempre filtre por versão recente da AMI base para garantir patches de segurança atualizados
- Combine com Terraform: Packer cria a imagem, Terraform a implanta. É uma separação de responsabilidades que escala muito bem
Packer no Ecossistema DevOps
O Packer se destaca por ser uma ferramenta focada em uma única responsabilidade: criar imagens imutáveis. Ele não substitui Terraform (que gerencia infraestrutura), Ansible (configuração) ou Docker (containers) — ele trabalha com eles. É a ferramenta ideal para cenários onde você precisa de VMs tradicionais, seja por requisitos de compliance, performance ou legado.
Conclusão
O Packer é uma ferramenta indispensável no arsenal DevOps moderno. Ele elimina a derivação de configuração, acelera o provisionamento e garante que todos os ambientes (desenvolvimento, staging, produção) sejam baseados nas mesmas imagens. Se você ainda gerencia servidores com scripts de bootstrap ou configuração manual, o Packer é o próximo passo natural na sua jornada de infraestrutura como código.







