← back to the garden

MD

Guia completo de cloud-init no Proxmox

Manual prático para criar imagens-base, templates e máquinas virtuais configuradas automaticamente com cloud-init no Proxmox VE.

  • pesquisa
  • cloud-init
  • proxmox
  • virtualizacao
  • automacao
  • linux

Guia completo de cloud-init no Proxmox

O cloud-init é a peça que transforma uma imagem Linux genérica em uma máquina virtual pronta para uso: com identidade própria, usuário administrativo, chave SSH, rede, pacotes e configurações aplicados automaticamente no primeiro boot. No Proxmox VE, ele permite manter um template limpo e criar novas VMs em poucos minutos, sem repetir manualmente uma instalação inteira.

Este guia começa do zero e acompanha o fluxo completo: entender o que o Proxmox faz, escolher uma imagem, construir um template, clonar uma VM, configurar DHCP ou IP estático, usar snippets personalizados, criar uma imagem-base própria, validar o resultado e diagnosticar falhas. Os exemplos usam principalmente Ubuntu Server 24.04 LTS e Debian, mas os princípios servem para outras distribuições com suporte ao cloud-init.

Resposta curta: para usar cloud-init no Proxmox, você normalmente não precisa montar um servidor de cloud-init. O Proxmox gera um pequeno disco de configuração no formato NoCloud e o conecta à VM. A imagem Linux lê esse disco no primeiro boot e aplica o conteúdo.

Resumo executivo

Para a maioria dos ambientes Proxmox, o melhor desenho é:

  1. baixar uma imagem cloud oficial e verificar sua integridade;
  2. importá-la em uma VM que servirá como template;
  3. adicionar o disco de cloud-init e habilitar console serial e QEMU Guest Agent;
  4. converter a VM desligada em template;
  5. criar um clone para cada novo servidor;
  6. definir usuário, chave SSH, rede e DNS no clone;
  7. iniciar a VM e aguardar cloud-init status --wait;
  8. usar snippets somente quando a tela padrão do Proxmox não for suficiente;
  9. usar Ansible ou outra ferramenta para configuração contínua depois do primeiro boot.

Há três coisas diferentes que as pessoas costumam chamar de “meu cloud-init”:

Camada O que você cria Quando usar
Template padrão Uma imagem cloud oficial importada no Proxmox Melhor opção para quase todos os servidores
Configuração própria Arquivos user-data, vendor-data, network-config e, raramente, meta-data Quando é preciso instalar pacotes, criar arquivos, executar scripts ou controlar a rede além da interface do Proxmox
Imagem-base própria Uma golden image preparada manualmente ou por Packer Quando o boot precisa ser muito rápido, há agentes obrigatórios ou existe uma base corporativa bem controlada

O cloud-init não substitui completamente Ansible, Salt, Puppet ou scripts de implantação. Ele é especialmente bom para preparar a identidade e o estado inicial da VM. Para alterações recorrentes, aplicações complexas e manutenção contínua, uma ferramenta de configuração posterior costuma ser mais previsível.

Metodologia e critérios

A pesquisa foi construída a partir da documentação atual do cloud-init, da referência oficial do Proxmox VE, das páginas de imagens cloud do Ubuntu, Debian e Fedora e da documentação do Packer. Os comandos foram organizados em uma sequência reproduzível e os exemplos evitam depender de um armazenamento, bridge ou faixa de endereços específicos.

Os critérios principais foram:

  • usar imagens oficiais e assinadas sempre que possível;
  • manter o template genérico, pequeno e sem segredos;
  • separar configuração gerada pelo Proxmox de configuração personalizada;
  • priorizar SSH por chave em vez de senha;
  • evitar processos frágeis que só funcionam uma vez sem explicar por quê;
  • permitir diagnóstico tanto pelo Proxmox quanto dentro da VM;
  • deixar claro quando um comando pode apagar dados ou alterar a identidade da máquina.

Os nomes de storages, bridges, discos, usuários e endereços IP dos exemplos precisam ser adaptados ao ambiente real.

O que é cloud-init

Cloud-init é um sistema de inicialização de instâncias. Ele nasceu para nuvens, mas também funciona muito bem em hipervisores locais. Durante o boot, ele procura uma fonte de dados, lê metadados e instruções e executa módulos em fases diferentes da inicialização.

Entre as tarefas que ele consegue realizar estão:

  • definir hostname;
  • criar usuários e grupos;
  • instalar chaves SSH;
  • configurar senha, quando realmente necessário;
  • configurar DHCP, IPv4 e IPv6 estáticos;
  • definir DNS e domínio de pesquisa;
  • crescer a partição e o filesystem;
  • criar e montar discos;
  • instalar e atualizar pacotes;
  • escrever arquivos;
  • configurar fuso horário, locale e NTP;
  • executar comandos;
  • registrar a conclusão do provisionamento.

Cloud-init não é um daemon de administração central que permanece “mandando” na VM. A maior parte da configuração de identidade é aplicada na primeira inicialização da instância. Alguns módulos podem rodar a cada boot, mas outros rodam apenas uma vez por instância.

As quatro fases que importam

Em termos práticos, o boot passa por estas etapas:

  1. Detecção da fonte de dados: o cloud-init procura o disco ou serviço que contém as configurações.
  2. Rede inicial: a rede necessária para continuar o provisionamento é preparada.
  3. Configuração: usuários, pacotes, arquivos e outros módulos são processados.
  4. Finalização: comandos tardios, como runcmd, são executados e o estado final é registrado.

Isso explica por que uma VM pode responder ao ping ou até aceitar conexão enquanto o provisionamento ainda está terminando. Para automações, “a VM ligou” não significa necessariamente “o cloud-init terminou”.

Como o Proxmox entrega a configuração

Em VMs Linux, o Proxmox normalmente utiliza o datasource NoCloud. Ao adicionar um CloudInit Drive, o Proxmox cria uma mídia pequena contendo os dados da instância. A imagem convidada encontra essa mídia durante o boot.

O NoCloud trabalha com quatro documentos principais:

Documento Finalidade
meta-data Identidade da instância, hostname e outros metadados
user-data Usuários, chaves, pacotes, arquivos, comandos e configuração específica
vendor-data Base definida pelo provedor ou administrador, que o usuário pode complementar ou substituir
network-config Interfaces, DHCP, endereços, rotas e DNS

Quando você preenche a aba Cloud-Init na interface do Proxmox, o próprio Proxmox gera esses dados. Quando usa cicustom, você substitui uma ou mais partes por arquivos próprios guardados em um storage com suporte a snippets.

flowchart LR
    A["Template com imagem cloud"] --> B["Clone da VM"]
    C["Opções Cloud-Init do Proxmox"] --> D["Disco NoCloud"]
    E["Snippets personalizados, opcionais"] --> D
    D --> B
    B --> F["Primeiro boot"]
    F --> G["cloud-init aplica identidade, rede e configuração"]
    G --> H["VM pronta para SSH e configuração posterior"]

Não é necessário instalar um servidor HTTP, metadata server ou serviço paralelo para esse fluxo. O disco de configuração anexado pelo Proxmox é suficiente.

O que você precisa antes de começar

No host Proxmox

  • Proxmox VE instalado e atualizado;
  • um storage para o disco da VM, como local-lvm, ZFS ou Ceph;
  • uma bridge de rede, normalmente vmbr0;
  • um storage que aceite snippets, caso use arquivos personalizados;
  • acesso administrativo ao host ou à interface web;
  • espaço para a imagem, o template e os clones.

Para as VMs

  • uma imagem cloud oficial com cloud-init instalado;
  • uma chave SSH pública;
  • uma estratégia de endereçamento: DHCP ou IP estático;
  • DNS, gateway e VLAN definidos, quando aplicável;
  • IDs livres para o template e as VMs.

Convenções usadas nos exemplos

Item Exemplo Adapte para
VMID do template 9000 Um ID livre reservado a templates
VMID do primeiro clone 101 Um ID livre
Storage de discos local-lvm Seu storage real
Storage de snippets local Um storage do tipo Directory com snippets
Bridge vmbr0 Sua bridge
Usuário pablo Seu usuário administrativo
Nome da VM srv01 Seu padrão de nomes
Rede de documentação 192.0.2.0/24 Sua rede real

Os endereços 192.0.2.0/24 e 2001:db8::/32 são reservados para documentação. Eles não funcionarão como endereços reais da sua rede.

Primeiro passo: crie uma chave SSH

Em um computador confiável, crie uma chave moderna:

ssh-keygen -t ed25519 -a 100 -C "pablo-proxmox"

No Linux, o mesmo comando funciona:

ssh-keygen -t ed25519 -a 100 -C "pablo-proxmox"

O arquivo terminado em .pub é a chave pública e pode ser entregue ao Proxmox. A chave privada nunca deve ser copiada para o template, para o host Proxmox ou para o arquivo cloud-init.

Verifique a chave pública:

ssh-keygen -lf ~/.ssh/id_ed25519.pub

Guarde a chave privada com backup protegido. Perder a chave sem ter outro método de acesso pode deixar a VM inacessível.

Escolhendo uma imagem cloud

Uma imagem cloud é diferente do ISO de instalação. Ela já contém um sistema instalado, preparado para ser clonado e inicializado por cloud-init.

Boas opções:

Distribuição Indicação Observação
Ubuntu Server LTS Servidores gerais e maior quantidade de documentação Use a imagem de release estável, não uma daily build
Debian GenericCloud Base enxuta e previsível Excelente para servidores Debian no Proxmox
Fedora Cloud Pacotes recentes, SELinux e ecossistema Fedora Ciclo de suporte menor que uma LTS
Rocky Linux / AlmaLinux GenericCloud Ambientes compatíveis com RHEL Confirme o nome da imagem e suporte da versão escolhida
openSUSE Leap / MicroOS openSUSE tradicional ou host transacional O fluxo e os módulos disponíveis podem variar

Ubuntu 24.04 LTS

A página oficial publica a imagem noble-server-cloudimg-amd64.img e arquivos de checksums. Baixe a imagem de release atual:

cd /var/lib/vz/template/iso
wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
wget https://cloud-images.ubuntu.com/noble/current/SHA256SUMS
wget https://cloud-images.ubuntu.com/noble/current/SHA256SUMS.gpg

No mínimo, compare o SHA-256:

sha256sum noble-server-cloudimg-amd64.img
grep noble-server-cloudimg-amd64.img SHA256SUMS

A verificação criptográfica completa exige importar e conferir a chave usada pelo Ubuntu. A documentação oficial de imagens públicas explica o processo de assinatura. Não trate apenas o download por HTTPS como substituto permanente da verificação quando a imagem será usada em produção.

Debian

O Debian publica imagens cloud em cloud.debian.org. Uma imagem GenericCloud para amd64 costuma seguir este padrão:

https://cloud.debian.org/images/cloud/trixie/latest/debian-13-genericcloud-amd64.qcow2

Confirme o nome atual no índice oficial antes de automatizar, pois versões e nomes mudam. Baixe também os arquivos de checksum disponibilizados no mesmo diretório.

Não use imagens aleatórias

Uma imagem-base controla todo o sistema operacional das VMs clonadas. Prefira:

  • site oficial da distribuição;
  • checksum publicado no mesmo canal;
  • assinatura, quando disponível;
  • versão ainda suportada;
  • arquivo imutável ou checksum registrado no seu repositório de infraestrutura.

Evite templates de fóruns e discos preparados por terceiros sem processo de construção auditável.

Caminho recomendado: template Ubuntu no Proxmox pela CLI

Este é o procedimento mais curto, reproduzível e fácil de diagnosticar.

1. Crie uma VM vazia

No shell do host Proxmox:

qm create 9000 \
  --name ubuntu-2404-cloud \
  --memory 2048 \
  --cores 2 \
  --cpu host \
  --net0 virtio,bridge=vmbr0

O parâmetro --cpu host oferece os recursos da CPU física e costuma ser adequado quando a VM não precisa migrar entre hosts com processadores diferentes. Em um cluster heterogêneo com migração, use um modelo de CPU comum aos nós.

2. Importe o disco da imagem

qm disk import 9000 noble-server-cloudimg-amd64.img local-lvm

Em versões antigas, ou em tutoriais escritos para elas, o mesmo procedimento aparece como qm importdisk. O Proxmox importa o arquivo e informa o volume criado. Em uma VM nova, ele costuma aparecer como vm-9000-disk-0, mas não presuma o nome em um script sem conferir:

qm config 9000
pvesm list local-lvm --vmid 9000

3. Anexe o disco importado

Se o volume criado foi vm-9000-disk-0:

qm set 9000 \
  --scsihw virtio-scsi-pci \
  --scsi0 local-lvm:vm-9000-disk-0

O controlador VirtIO SCSI oferece bom suporte para Linux moderno. Dependendo do storage e da sua política, você também pode avaliar discard=on e ssd=1, mas não os copie sem entender o suporte do armazenamento.

4. Adicione o CloudInit Drive

qm set 9000 --ide2 local-lvm:cloudinit

Embora apareça como IDE neste exemplo, esse é apenas o pequeno disco de configuração. O disco principal continua em SCSI.

5. Defina boot, console e agente

qm set 9000 --boot order=scsi0
qm set 9000 --serial0 socket --vga serial0
qm set 9000 --agent enabled=1

O console serial é especialmente útil com imagens cloud, que frequentemente são preparadas para ele. Habilitar o agente no Proxmox configura o lado do hipervisor; o pacote qemu-guest-agent e seu serviço também precisam existir dentro da imagem.

6. Aumente o disco-base, se necessário

Confira o tamanho:

qm config 9000

Se quiser que todos os clones comecem, por exemplo, com mais 20 GB:

qm disk resize 9000 scsi0 +20G

Versões anteriores também aceitam ou documentam o atalho qm resize. O cloud-init normalmente expande a partição raiz e o filesystem no primeiro boot se a imagem e sua tabela de partições forem compatíveis. Aumentar o disco virtual não garante sozinho que todo layout personalizado crescerá.

7. Não inicialize o template sem necessidade

Uma imagem cloud oficial já foi preparada para o primeiro boot. Não é preciso iniciá-la, entrar nela e “limpar” antes de convertê-la em template. Cada boot desnecessário cria estado, cache e identidade que depois precisam ser removidos corretamente.

8. Converta em template

qm template 9000

O template deve permanecer desligado e genérico. Configurações específicas de servidor devem ser aplicadas aos clones.

O mesmo fluxo pela interface web

A interface web ajuda a visualizar a VM, mas importar o disco cloud pela CLI ainda é o caminho mais direto.

  1. Em Create VM, escolha um VMID e nome para o template.
  2. Em OS, selecione Do not use any media.
  3. Configure o sistema, CPU, memória e rede.
  4. Conclua sem iniciar a VM.
  5. No shell do host, execute qm disk import para importar a imagem.
  6. Na aba Hardware, adicione o disco importado à VM usando SCSI.
  7. Adicione CloudInit Drive.
  8. Em Options, ajuste a ordem de boot para o disco principal.
  9. Em Hardware, adicione Serial Port 0 e use display serial, se desejado.
  10. Habilite QEMU Guest Agent em Options.
  11. Clique com o botão direito na VM e escolha Convert to template.

O nome exato de alguns controles pode variar entre versões do Proxmox VE, mas os objetos necessários são os mesmos: disco raiz, placa de rede, disco cloud-init e ordem de boot.

Criando a primeira VM a partir do template

1. Faça um clone completo

qm clone 9000 101 --name srv01 --full 1

Um clone completo é independente do template e é a escolha mais simples para servidores permanentes. Linked clones economizam espaço e tempo, mas dependem do disco-base e do suporte a snapshots do storage.

2. Defina usuário e chave SSH

Crie um diretório protegido no host para chaves públicas administrativas:

install -d -m 0700 /root/keys

Copie apenas a chave pública para /root/keys/pablo.pub e configure:

qm set 101 --ciuser pablo
qm set 101 --sshkeys /root/keys/pablo.pub

O Proxmox codifica corretamente o conteúdo para o disco cloud-init. Não informe o caminho de uma chave privada.

3. Configure rede por DHCP

Para IPv4 por DHCP e IPv6 por autoconfiguração:

qm set 101 --ipconfig0 ip=dhcp,ip6=auto

Para somente IPv4 por DHCP:

qm set 101 --ipconfig0 ip=dhcp

4. Ou configure IPv4 estático

qm set 101 \
  --ipconfig0 ip=192.0.2.50/24,gw=192.0.2.1

DNS e domínio de pesquisa:

qm set 101 --nameserver "1.1.1.1 9.9.9.9"
qm set 101 --searchdomain lab.example

Para uma segunda interface:

qm set 101 --net1 virtio,bridge=vmbr1
qm set 101 --ipconfig1 ip=dhcp

Em VLAN:

qm set 101 --net0 virtio,bridge=vmbr0,tag=20

A porta da bridge ou o switch físico também precisa transportar a VLAN. O parâmetro no Proxmox não corrige sozinho uma rede que não entrega a VLAN ao host.

5. Confira o que será entregue

qm config 101
qm cloudinit dump 101 user
qm cloudinit dump 101 network
qm cloudinit dump 101 meta
qm cloudinit pending 101

Essa inspeção é uma das melhores maneiras de detectar um usuário incorreto, uma chave ausente ou um endereço digitado errado antes do boot.

6. Inicie e acompanhe

qm start 101

Abra o console serial ou consulte o endereço obtido pelo DHCP. Dentro da VM:

cloud-init status --wait --long

Quando o estado for done, teste:

ssh pablo@ENDERECO_DA_VM

Se o QEMU Guest Agent estiver instalado e ativo, o Proxmox consegue exibir com mais facilidade os endereços do guest. A descoberta por DHCP também pode ser feita no roteador ou servidor DHCP.

Senha ou chave SSH?

Use chave SSH. Se você configurar uma senha:

qm set 101 --cipassword

o comando pode pedir a senha de forma interativa. Ainda assim, o uso de senha cria mais riscos operacionais e pode exigir que o login por senha esteja habilitado no SSH da imagem.

Nunca coloque uma senha em texto puro dentro de:

  • histórico do shell;
  • script versionado;
  • user-data;
  • variável exposta em pipeline;
  • captura de tela da interface;
  • arquivo compartilhado de snippets.

Se uma senha temporária for indispensável, use hash compatível com a distribuição, proteja o arquivo, force a troca e desabilite o método depois. Cloud-init não é um cofre de segredos.

O que a aba Cloud-Init do Proxmox resolve

Sem escrever YAML, normalmente é possível configurar:

  • usuário;
  • senha;
  • chave SSH;
  • upgrade de pacotes, conforme versão e interface;
  • DNS;
  • domínio de pesquisa;
  • IPv4 e IPv6 por interface;
  • gateway;
  • tipo de datasource.

Isso é suficiente para muitas VMs. Comece por aí. Use snippets apenas quando houver uma necessidade concreta, como instalar uma baseline, escrever arquivos ou executar uma preparação própria.

Snippets personalizados: sua configuração cloud-init

Como habilitar snippets no storage

O storage precisa aceitar o tipo de conteúdo Snippets. No storage local, que normalmente corresponde a /var/lib/vz, isso pode ser habilitado em:

Datacenter → Storage → local → Edit → Content → Snippets

Na CLI, primeiro veja a configuração atual:

pvesm status
grep -A 8 '^dir: local' /etc/pve/storage.cfg

Depois acrescente snippets à lista de conteúdos sem remover os tipos existentes. Um exemplo comum é:

pvesm set local --content iso,vztmpl,backup,snippets

Não copie a lista acima cegamente. O parâmetro --content representa a lista completa. Preserve os tipos que já existem no seu storage.cfg.

No storage padrão local, o diretório costuma ser:

/var/lib/vz/snippets/

Crie-o, se necessário:

install -d -m 0750 /var/lib/vz/snippets

Em cluster, o snippet precisa existir em todos os nós para os quais a VM pode migrar, ou estar em um storage compartilhado acessível por todos. Uma referência local:snippets/... válida no nó A pode falhar no nó B se o arquivo não tiver sido replicado.

Como ligar os arquivos à VM

qm set 101 --cicustom \
  "user=local:snippets/user-data.yaml,vendor=local:snippets/vendor-data.yaml,network=local:snippets/network-config.yaml"

Também existe a parte meta= quando metadados personalizados forem realmente necessários.

O ponto mais importante é: um arquivo customizado substitui aquela parte gerada pelo Proxmox; ele não é simplesmente acrescentado. Se você fornecer user=..., o usuário e a chave configurados na aba do Proxmox podem deixar de aparecer, a menos que seu próprio user-data os contenha.

Uma estratégia segura é:

  • deixar user, network e meta gerados pelo Proxmox;
  • criar apenas vendor-data para a baseline comum;
  • substituir user-data somente nas VMs que exigem automação mais avançada.

Exemplo:

qm set 101 --cicustom \
  "vendor=local:snippets/vendor-data.yaml"

Valide o YAML antes do boot

Em uma máquina com cloud-init instalado:

cloud-init schema \
  -c ./user-data.yaml \
  --annotate

Dentro de uma VM já inicializada:

cloud-init schema --system

Validação de sintaxe YAML não garante que todos os comandos de shell funcionarão, mas elimina muitos problemas de indentação, chaves inválidas e tipos incorretos.

Exemplo seguro de user-data

O cabeçalho #cloud-config é obrigatório para identificar o formato.

#cloud-config

hostname: srv01
manage_etc_hosts: true

users:
  - default
  - name: pablo
    gecos: Pablo
    groups: [adm, sudo]
    shell: /bin/bash
    sudo: "ALL=(ALL) NOPASSWD:ALL"
    lock_passwd: true
    ssh_authorized_keys:
      - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... pablo-proxmox

ssh_pwauth: false
disable_root: true

package_update: true
packages:
  - qemu-guest-agent
  - curl
  - vim
  - htop
  - ca-certificates

timezone: America/Sao_Paulo
locale: pt_BR.UTF-8

write_files:
  - path: /etc/motd
    owner: root:root
    permissions: '0644'
    content: |
      Servidor provisionado por cloud-init.
      Consulte a documentação interna antes de alterar a rede.

runcmd:
  - [systemctl, enable, --now, qemu-guest-agent]

final_message: "Cloud-init terminou em $UPTIME segundos."

Observações:

  • default preserva o usuário padrão da distribuição. Se você redefine users e omite default, ele pode deixar de ser criado.
  • lock_passwd: true bloqueia autenticação por senha para o usuário, mas a chave SSH continua funcionando.
  • NOPASSWD é conveniente, porém aumenta o impacto do comprometimento da conta. Se o ambiente exigir mais controle, remova-o.
  • permissões devem ser strings, como '0644', para evitar interpretação inesperada do YAML;
  • runcmd é executado uma vez por instância, perto do final do processo;
  • pacotes dependem de rede e repositórios funcionais.

Uma baseline compartilhada com vendor-data

vendor-data é adequado para defaults administrados por você. O usuário ou a configuração específica da VM pode complementar ou substituir partes dessa base.

#cloud-config

package_update: true
packages:
  - qemu-guest-agent
  - curl
  - jq
  - chrony

timezone: America/Sao_Paulo

write_files:
  - path: /etc/sysctl.d/60-lab-baseline.conf
    owner: root:root
    permissions: '0644'
    content: |
      net.ipv4.conf.all.accept_redirects = 0
      net.ipv4.conf.default.accept_redirects = 0

runcmd:
  - [sysctl, --system]
  - [systemctl, enable, --now, qemu-guest-agent]

Não transforme vendor-data em um script gigante. Mantenha ali apenas o que realmente é comum a todas as VMs daquele template.

Exemplo de rede estática personalizada

Quando a configuração gerada pelo Proxmox não cobre um cenário de rede, use network-config v2:

version: 2
ethernets:
  lan0:
    match:
      macaddress: "52:54:00:12:34:56"
    set-name: lan0
    addresses:
      - 192.0.2.50/24
      - 2001:db8:20::50/64
    routes:
      - to: default
        via: 192.0.2.1
      - to: default
        via: 2001:db8:20::1
    nameservers:
      search:
        - lab.example
      addresses:
        - 192.0.2.53
        - 2001:4860:4860::8888

Boas práticas:

  • faça o match por MAC quando o nome da interface puder mudar;
  • escreva o MAC entre aspas e em minúsculas;
  • prefira rotas to: default a gateway4 e gateway6, que estão depreciados no formato v2;
  • confirme se a distribuição usa Netplan, NetworkManager ou outro renderer compatível;
  • mantenha acesso ao console do Proxmox enquanto testa IP estático;
  • não configure o mesmo endereço em duas VMs.

Para DHCP:

version: 2
ethernets:
  lan0:
    match:
      macaddress: "52:54:00:12:34:56"
    set-name: lan0
    dhcp4: true
    dhcp6: true

Se o MAC da placa for gerado no clone, um snippet de rede rígido com o MAC antigo não funcionará. Nesse caso, gere o snippet por VM ou deixe a rede sob controle do Proxmox.

Escrevendo arquivos depois que pacotes e usuários existirem

Por padrão, write_files pode ocorrer antes da instalação de pacotes e antes da criação de determinados usuários. Em versões atuais do cloud-init, defer: true adia a escrita:

#cloud-config

packages:
  - nginx

write_files:
  - path: /etc/nginx/conf.d/status.conf
    owner: root:root
    permissions: '0644'
    defer: true
    content: |
      server {
          listen 127.0.0.1:8080;
          server_name _;

          location /health {
              access_log off;
              return 200 "ok\n";
          }
      }

runcmd:
  - [nginx, -t]
  - [systemctl, enable, --now, nginx]

O bind em 127.0.0.1 mantém o endpoint fora da rede até que você decida como expô-lo. Se o serviço deve ser público, configure firewall, TLS e controle de acesso conscientemente.

Tarefas longas: use uma unidade systemd

Comandos muito demorados em runcmd tornam o primeiro boot difícil de acompanhar. Uma alternativa é criar uma unidade oneshot:

#cloud-config

write_files:
  - path: /usr/local/sbin/bootstrap-aplicacao
    owner: root:root
    permissions: '0750'
    content: |
      #!/usr/bin/env bash
      set -euo pipefail
      install -d -m 0750 /var/lib/minha-aplicacao
      date --iso-8601=seconds > /var/lib/minha-aplicacao/provisionado-em

  - path: /etc/systemd/system/bootstrap-aplicacao.service
    owner: root:root
    permissions: '0644'
    content: |
      [Unit]
      Description=Bootstrap inicial da aplicacao
      After=network-online.target
      Wants=network-online.target
      ConditionPathExists=!/var/lib/minha-aplicacao/provisionado-em

      [Service]
      Type=oneshot
      ExecStart=/usr/local/sbin/bootstrap-aplicacao
      RemainAfterExit=yes

      [Install]
      WantedBy=multi-user.target

runcmd:
  - [systemctl, daemon-reload]
  - [systemctl, enable, --now, bootstrap-aplicacao.service]

Para aplicações reais, Ansible, um pipeline ou uma imagem versionada costuma oferecer observabilidade e repetição melhores do que dezenas de linhas de shell dentro do YAML.

Preparando e montando um segundo disco

Cloud-init pode particionar, formatar e montar volumes. Essa capacidade é útil, mas potencialmente destrutiva.

Exemplo conceitual para um disco vazio identificado como /dev/sdb:

#cloud-config

disk_setup:
  /dev/sdb:
    table_type: gpt
    layout: true
    overwrite: false

fs_setup:
  - label: dados
    filesystem: ext4
    device: /dev/sdb
    partition: auto

mounts:
  - [LABEL=dados, /srv/dados, ext4, "defaults,nofail", "0", "2"]

Antes de usar:

  • confirme o nome estável do dispositivo;
  • prefira /dev/disk/by-id, serial, label ou UUID quando o módulo e a distribuição permitirem;
  • teste em um clone descartável;
  • mantenha overwrite: false para evitar destruir um filesystem reconhecido;
  • entenda que um erro de identificação pode formatar o disco errado;
  • valide o resultado com lsblk -f, findmnt e /etc/fstab.

Para um disco de dados importante, muitas equipes preferem preparar o volume fora do cloud-init ou usar uma automação que faça verificações explícitas antes de alterar partições.

bootcmd, runcmd e scripts

Recurso Quando roda Uso típico
bootcmd Em todos os boots, bem cedo Pequenos ajustes necessários antes da configuração normal
runcmd Uma vez por instância, na fase final Habilitar serviços e executar bootstrap
Script com #! Conforme o formato de user-data Procedimentos inteiramente em shell
write_files + systemd Controlado pelo systemd Processos idempotentes e mais observáveis

Evite usar /tmp para arquivos que precisam sobreviver até módulos posteriores. Durante o boot, serviços de limpeza podem removê-los. Use /run, /var/tmp ou um diretório próprio conforme o ciclo de vida necessário.

Se o YAML for grande ou tiver múltiplos tipos de conteúdo, cloud-init suporta MIME multipart e outros formatos. Para um ambiente pequeno, um #cloud-config legível e versionado costuma ser melhor.

Criando sua própria imagem-base

Você não precisa construir uma distribuição do zero. A opção mais segura é partir da imagem cloud oficial e adicionar somente o indispensável.

O que vale embutir

  • cloud-init;
  • qemu-guest-agent;
  • certificados internos realmente necessários;
  • agente de monitoramento padronizado;
  • ferramentas básicas aprovadas;
  • configuração de repositórios internos;
  • drivers ou módulos exigidos por todo o ambiente.

O que não deve estar na imagem

  • senha pessoal;
  • chave SSH privada;
  • chave SSH de host reutilizada;
  • token de API;
  • credencial de registry;
  • cookie, sessão ou histórico de shell;
  • hostname final;
  • IP estático final;
  • machine-id de uma VM já usada;
  • logs e cache do cloud-init de uma instância anterior.

Método simples: preparar uma VM e limpá-la

  1. Crie uma VM temporária a partir de uma imagem oficial.
  2. Instale apenas os pacotes-base.
  3. Valide que a VM inicializa corretamente.
  4. Remova segredos e estado específico.
  5. Execute a limpeza final.
  6. Desligue a VM.
  7. Converta-a em template sem voltar a iniciá-la.

Dentro da VM, antes do desligamento final:

sudo apt update
sudo apt install -y cloud-init qemu-guest-agent
sudo systemctl enable qemu-guest-agent

sudo cloud-init clean --logs --machine-id --seed
sudo rm -f /etc/ssh/ssh_host_*
sudo poweroff

O --machine-id deixa o identificador preparado para ser recriado no próximo boot. A remoção das chaves de host SSH evita que clones diferentes apresentem a mesma identidade SSH.

Dependendo da distribuição e dos pacotes instalados, revise também:

  • leases DHCP;
  • regras persistentes de rede;
  • logs;
  • caches de gerenciadores;
  • arquivos em /tmp e /var/tmp;
  • histórico de comandos;
  • credenciais de agentes;
  • registros do sistema em serviços externos.

Não apague arquivos indiscriminadamente. Faça um checklist específico para a distribuição e teste um clone antes de colocar o template em produção.

Método reproduzível: Packer

O Packer possui builder oficial para Proxmox. Ele consegue criar uma VM, instalar ou personalizar o sistema, desligá-la e convertê-la em template.

Packer passa a valer a pena quando:

  • a imagem precisa ser recriada regularmente;
  • há vários clusters;
  • o processo precisa ser auditável;
  • a baseline é versionada;
  • a preparação manual já ficou longa ou sujeita a esquecimentos.

Fluxo recomendado:

Repositório Git
  ├── packer/
  │   ├── template.pkr.hcl
  │   └── variáveis não secretas
  ├── cloud-init/
  │   ├── vendor-data.yaml
  │   └── exemplos/
  └── ansible/
      └── baseline.yml

Não armazene tokens do Proxmox dentro do arquivo HCL. Use variáveis de ambiente, um cofre de segredos ou credenciais temporárias com permissões mínimas.

Imagem mutável ou reconstruída?

É tentador ligar o template, atualizá-lo e desligá-lo novamente. Com o tempo, isso acumula estado e torna a origem dos problemas difícil de descobrir.

Uma política melhor:

  1. registre a versão e o checksum da imagem oficial;
  2. mantenha a personalização em código;
  3. reconstrua o template;
  4. teste um clone;
  5. publique uma nova versão;
  6. aposente a anterior depois de confirmar a migração.

Gerando um datasource NoCloud manualmente

O Proxmox já gera o disco de configuração. Ainda assim, criar um seed manual é útil para aprender, testar no QEMU ou usar fora do Proxmox.

Em Ubuntu ou Debian, instale cloud-image-utils:

sudo apt update
sudo apt install cloud-image-utils

Crie user-data.yaml:

#cloud-config
users:
  - default
ssh_pwauth: false
packages:
  - qemu-guest-agent

Crie meta-data.yaml:

instance-id: iid-local-lab-001
local-hostname: lab-001

Gere a mídia:

cloud-localds seed-lab-001.img user-data.yaml meta-data.yaml

O arquivo seed-lab-001.img pode ser conectado à VM junto da imagem cloud. O instance-id é importante: cloud-init o usa para decidir se está diante de uma nova instância.

O NoCloud também consegue consumir uma mídia ISO ou VFAT com label CIDATA e os arquivos esperados na raiz. A ferramenta cloud-localds elimina boa parte dos detalhes manuais.

Como cloud-init decide se é o primeiro boot

Cloud-init guarda cache em /var/lib/cloud. Ao iniciar, ele compara a identidade recebida da fonte de dados com a identidade registrada. Se considerar que é a mesma instância, módulos marcados como “por instância” não serão executados de novo.

Isso causa um erro comum:

  1. a VM é iniciada;
  2. o usuário altera user-data;
  3. reinicia a VM;
  4. espera que tudo rode novamente;
  5. nada acontece porque a instância não mudou.

O fluxo normal é corrigir a configuração e criar um clone novo. Para teste controlado, dentro de uma VM descartável:

sudo cloud-init clean --logs --machine-id --seed
sudo reboot

Esse comando pode recriar identidade, chaves e rede. Não o execute em uma VM de produção apenas para “ver se funciona”.

Atualizando a configuração de uma VM

Antes do primeiro boot:

qm set 101 --ciuser pablo
qm set 101 --sshkeys /root/keys/pablo.pub
qm set 101 --ipconfig0 ip=dhcp
qm cloudinit update 101

O Proxmox normalmente regenera o disco quando necessário, e qm cloudinit update permite solicitar a atualização explicitamente.

Depois que a VM já foi inicializada, alterar a configuração no Proxmox não garante que os módulos por instância rodarão novamente. Escolha uma destas abordagens:

  • recriar a VM a partir do template, preferível para servidores descartáveis;
  • aplicar a mudança com Ansible ou administração normal;
  • executar manualmente apenas a correção necessária;
  • limpar o estado do cloud-init somente em laboratório e entendendo os efeitos.

Automação simples para criar clones

Um script pequeno pode padronizar a criação sem esconder o que acontece:

#!/usr/bin/env bash
set -euo pipefail

template_id=9000
vm_id="${1:?Uso: $0 VMID NOME IP/CIDR GATEWAY}"
vm_name="${2:?Informe o nome da VM}"
vm_ip="${3:?Informe IP/CIDR ou dhcp}"
vm_gateway="${4:-}"
ssh_key=/root/keys/pablo.pub

if qm status "$vm_id" >/dev/null 2>&1; then
  echo "O VMID $vm_id já existe." >&2
  exit 1
fi

if [[ ! -r "$ssh_key" ]]; then
  echo "Chave pública não encontrada: $ssh_key" >&2
  exit 1
fi

if [[ "$vm_ip" != "dhcp" && -z "$vm_gateway" ]]; then
  echo "Gateway obrigatório para IP estático." >&2
  exit 1
fi

qm clone "$template_id" "$vm_id" --name "$vm_name" --full 1
qm set "$vm_id" --ciuser pablo
qm set "$vm_id" --sshkeys "$ssh_key"

if [[ "$vm_ip" == "dhcp" ]]; then
  qm set "$vm_id" --ipconfig0 ip=dhcp
else
  qm set "$vm_id" --ipconfig0 "ip=${vm_ip},gw=${vm_gateway}"
fi

qm cloudinit update "$vm_id"

echo "Revise antes de iniciar:"
qm config "$vm_id"
qm cloudinit dump "$vm_id" user
qm cloudinit dump "$vm_id" network

Uso com DHCP:

./criar-vm.sh 101 srv01 dhcp

Uso com IP estático:

./criar-vm.sh 102 srv02 192.0.2.52/24 192.0.2.1

O exemplo para antes de ligar a VM, permitindo revisar a configuração. Se quiser automatizar também o start, acrescente qm start "$vm_id" somente depois de ter validações adequadas de IP, VLAN, storage e quotas.

Cloud-init com Terraform, OpenTofu e Ansible

Em um laboratório maior, as responsabilidades podem ser separadas:

Ferramenta Responsabilidade
Packer Construir e versionar o template
Terraform/OpenTofu Criar VM, CPU, RAM, discos, rede e opções cloud-init
cloud-init Preparar identidade e acesso inicial
Ansible Configurar serviços e manter o estado depois do boot

Uma sequência robusta é:

flowchart TD
    A["Packer cria template versionado"] --> B["Proxmox armazena template"]
    B --> C["OpenTofu ou Terraform cria o clone"]
    C --> D["Proxmox entrega NoCloud"]
    D --> E["cloud-init prepara acesso e baseline mínima"]
    E --> F["Automação espera cloud-init terminar"]
    F --> G["Ansible configura serviços"]
    G --> H["Monitoramento e backup validam a VM"]

Não comece por todas essas ferramentas ao mesmo tempo. Primeiro faça um clone funcionar manualmente. Depois automatize o processo que você já entende.

Diagnóstico dentro da VM

Estado geral

cloud-init status --wait --long

Saída estruturada:

cloud-init status --format=json

Logs

sudo less /var/log/cloud-init.log
sudo less /var/log/cloud-init-output.log
  • cloud-init.log mostra módulos, datasource, decisões e erros internos;
  • cloud-init-output.log registra a saída dos comandos e scripts.

Buscas rápidas:

sudo grep -iE 'error|warning|failed|traceback' /var/log/cloud-init.log
sudo grep -iE 'error|failed' /var/log/cloud-init-output.log

Descobrir a fonte de dados

cloud-id
sudo journalctl -u cloud-init-local -u cloud-init -u cloud-config -u cloud-final

Procure DataSourceNoCloud. Se o resultado indicar que nenhuma fonte foi encontrada, verifique o CloudInit Drive e a ordem de boot no Proxmox.

Ver os dados efetivamente recebidos

sudo ls -la /var/lib/cloud/instance/
sudo sed -n '1,240p' /var/lib/cloud/instance/user-data.txt
sudo sed -n '1,240p' /var/lib/cloud/instance/cloud-config.txt
sudo cat /run/cloud-init/instance-data.json

Esses arquivos podem conter dados sensíveis. Não os publique em tickets ou repositórios sem revisar.

Desempenho e módulos lentos

cloud-init analyze show
cloud-init analyze blame

blame ajuda a encontrar módulos demorados, como atualização de pacotes ou comandos que aguardam a rede.

Pacote de diagnóstico

sudo cloud-init collect-logs

O arquivo gerado reúne informações úteis para suporte. Revise-o antes de compartilhar, pois pode conter hostname, endereços, configuração e partes do user-data.

Diagnóstico no Proxmox

Comece verificando a definição da VM:

qm config 101

Procure:

  • disco principal em scsi0, virtio0 ou equivalente;
  • CloudInit Drive em ide2 ou outro slot;
  • placa net0;
  • bridge correta;
  • boot a partir do disco principal;
  • cicustom, se utilizado;
  • parâmetros ipconfig0, ciuser e sshkeys.

Inspecione o conteúdo gerado:

qm cloudinit dump 101 user
qm cloudinit dump 101 network
qm cloudinit dump 101 meta
qm cloudinit pending 101

Se usa snippets:

pvesm status
ls -l /var/lib/vz/snippets/
grep -A 8 '^dir: local' /etc/pve/storage.cfg

Confira o log de tarefas pela interface web ou em /var/log/pve/tasks/. Para problemas de rede, valide a bridge e a VLAN no host antes de culpar o cloud-init.

Erros comuns e como corrigir

“Não consigo fazer login”

Possíveis causas:

  • ciuser não corresponde ao usuário esperado;
  • chave pública incorreta ou truncada;
  • snippet user-data substituiu a configuração gerada;
  • login por senha está desabilitado;
  • o cloud-init ainda não terminou;
  • rede ou firewall impede o acesso.

Verifique no Proxmox:

qm cloudinit dump 101 user

Depois use o console e consulte os logs da VM.

“A VM não recebeu IP”

Verifique:

  • ipconfig0;
  • bridge;
  • VLAN;
  • servidor DHCP;
  • MAC;
  • nome da interface;
  • configuração estática e gateway;
  • logs do cloud-init;
  • configuração do renderer de rede.

Se a rede foi personalizada por snippet, compare o MAC do YAML com:

qm config 101 | grep '^net'

“Mudei o YAML, reiniciei e nada aconteceu”

Provavelmente o módulo é por instância e já foi executado. Crie um novo clone para testar. Não use cloud-init clean indiscriminadamente em produção.

“Meu YAML parece válido, mas parte dele foi ignorada”

Possíveis causas:

  • cabeçalho #cloud-config ausente;
  • indentação com tab;
  • chave incorreta para a versão instalada;
  • módulo ausente;
  • tipo errado, como número em vez de string;
  • write_files executado antes do usuário ou pacote necessário;
  • comando com caracteres especiais mal interpretado;
  • custom user-data substituiu a parte gerada pelo Proxmox.

Valide com:

cloud-init schema -c user-data.yaml --annotate

“O QEMU Guest Agent está habilitado, mas não funciona”

Marcar a opção no Proxmox não instala o agente. Dentro da VM:

sudo systemctl status qemu-guest-agent
sudo systemctl enable --now qemu-guest-agent

Se a unidade não existir, instale o pacote da distribuição.

“O disco aumentou, mas o filesystem não”

Analise:

lsblk
findmnt /
df -hT /
sudo growpart --dry-run /dev/sda 1

O dispositivo e a partição podem não ser /dev/sda1. LVM, Btrfs, partições múltiplas e layouts próprios exigem procedimento específico.

“O clone tem a mesma chave SSH de host”

Isso indica que a imagem foi capturada depois da geração das chaves e não foi limpa corretamente. Reconstrua o template e remova as chaves de host antes do desligamento final:

sudo rm -f /etc/ssh/ssh_host_*
sudo cloud-init clean --logs --machine-id --seed
sudo poweroff

Teste se clones diferentes apresentam fingerprints diferentes.

“O snippet funciona em um nó e falha em outro”

O arquivo está em storage local e não existe no segundo nó. Use storage compartilhado com suporte a snippets ou replique os arquivos e mantenha checksums iguais.

“O apt travou ou o primeiro boot demora muito”

Possíveis causas:

  • DNS ou gateway incorreto;
  • lock do gerenciador de pacotes;
  • mirror lento;
  • atualização grande;
  • serviço aguardando interação;
  • relógio incorreto;
  • proxy não configurado.

Use cloud-init analyze blame, logs e journalctl. Para produção, publique templates atualizados regularmente em vez de obrigar cada VM a baixar centenas de pacotes no primeiro boot.

Segurança

Não coloque segredos no user-data

Dependendo do ambiente, user-data pode ficar acessível:

  • no disco NoCloud;
  • nos arquivos em /var/lib/cloud;
  • em logs;
  • no histórico do shell;
  • em backup do Proxmox;
  • no repositório que guarda snippets;
  • para usuários locais privilegiados.

Use cloud-init para instalar o cliente de um cofre, criar uma identidade inicial ou iniciar um processo de obtenção de credenciais de curta duração. Não use o YAML como cofre.

Chaves e acesso

  • use Ed25519 quando compatível;
  • mantenha mais de uma chave administrativa somente quando houver necessidade;
  • remova chaves de pessoas que perderam acesso;
  • desabilite senha no SSH;
  • não permita login direto de root;
  • use firewall do Proxmox e do guest;
  • guarde acesso de console como recuperação, não como rotina.

Template

  • nunca clone uma VM com credenciais de produção;
  • limpe machine-id e chaves de host;
  • aplique atualizações de segurança antes de publicar uma nova versão;
  • registre origem, checksum e data;
  • mantenha template anterior por tempo limitado para rollback;
  • teste restore de backup e não apenas criação de VM.

Snippets

  • restrinja escrita no diretório;
  • versione arquivos sem segredos;
  • revise mudanças;
  • use nomes com versão quando a alteração for incompatível;
  • em cluster, garanta consistência;
  • valide schema antes de associar à VM.

Organização recomendada

Mesmo em homelab, uma estrutura pequena evita confusão:

infraestrutura/
  README.md
  imagens/
    checksums.txt
    origem-e-versao.md
  cloud-init/
    vendor-data-v1.yaml
    exemplos/
      web-user-data.yaml
      worker-user-data.yaml
      network-static.yaml
  scripts/
    criar-vm.sh
  ansible/
    inventory/
    baseline.yml

No Proxmox:

/var/lib/vz/snippets/
  vendor-data-v1.yaml
  web-user-data-v2.yaml
  network-srv01.yaml

Use nomes que revelem função e versão. Evite um único arquivo chamado config.yaml compartilhado por dezenas de VMs sem histórico claro.

Estratégia de atualização dos templates

Uma rotina mensal ou alinhada ao ciclo de patches pode ser:

  1. verificar nova imagem oficial;
  2. validar assinatura e checksum;
  3. revisar changelog da distribuição e do cloud-init;
  4. reconstruir um template com novo ID;
  5. clonar uma VM de teste;
  6. validar acesso, rede, disco, agente, logs e serviços;
  7. executar scanner de vulnerabilidades aprovado no ambiente;
  8. promover o novo template;
  9. manter o anterior durante uma janela curta;
  10. remover templates obsoletos somente após confirmar backups e dependências.

Exemplo de nomes:

ubuntu-2404-cloud-2026-07
debian-13-cloud-2026-07

O VMID pode ser estável para o template atual ou versionado. Em automação, é mais seguro resolver explicitamente qual versão será usada do que depender de “o último template”.

Plano de teste

Antes de considerar o template pronto, crie pelo menos dois clones descartáveis: um com DHCP e outro com IP estático.

Identidade

  • hostname é único;
  • machine-id é diferente entre clones;
  • chave SSH de host é diferente entre clones;
  • usuário administrativo correto existe;
  • somente as chaves autorizadas estão presentes.

Rede

  • DHCP funciona;
  • IP estático funciona;
  • gateway responde;
  • DNS resolve nomes;
  • IPv6 funciona ou está conscientemente desabilitado;
  • VLAN e bridge estão corretas;
  • reboot não perde a configuração.

Armazenamento

  • partição raiz cresceu;
  • filesystem usa o espaço esperado;
  • segundo disco foi identificado corretamente;
  • mounts sobrevivem ao reboot;
  • discard é usado somente quando suportado.

Cloud-init

  • cloud-init status --wait --long termina em done;
  • schema é válido;
  • logs não têm erros relevantes;
  • pacotes foram instalados;
  • arquivos têm dono e permissão corretos;
  • comandos são idempotentes ou executados apenas no momento esperado.

Proxmox

  • QEMU Guest Agent responde;
  • shutdown pela interface funciona;
  • IP aparece quando esperado;
  • snapshot ou backup funciona;
  • restauração do backup foi testada;
  • migração encontra todos os snippets necessários.

Um roteiro prático para seu primeiro laboratório

Fase 1: template mínimo

  1. Baixe Ubuntu 24.04 LTS cloud image.
  2. Verifique checksum.
  3. Crie VMID 9000.
  4. Importe o disco.
  5. Adicione CloudInit Drive.
  6. Configure console serial e QEMU Guest Agent.
  7. Converta em template.

Fase 2: primeiro clone

  1. Clone para VMID 101.
  2. Use DHCP.
  3. Configure seu usuário e chave.
  4. Inicie.
  5. Espere o cloud-init terminar.
  6. Teste SSH.
  7. Reinicie e confirme estabilidade.

Fase 3: rede estática

  1. Clone para VMID 102.
  2. Reserve um endereço fora do pool DHCP ou crie reserva.
  3. Configure IP, prefixo, gateway e DNS.
  4. Inicie com o console disponível.
  5. Confirme rotas e resolução.

Fase 4: baseline

  1. Habilite snippets.
  2. Crie somente vendor-data.
  3. Instale qemu-guest-agent, ferramentas básicas e timezone.
  4. Valide o YAML.
  5. Teste em VMID 103.

Fase 5: configuração contínua

  1. Mantenha cloud-init pequeno.
  2. Instale ou habilite o acesso necessário ao Ansible.
  3. Aplique serviços pelo Ansible.
  4. Recrie uma VM do zero para provar que o processo é reproduzível.

Recomendações práticas

Para começar hoje

Use uma imagem cloud oficial do Ubuntu ou Debian, deixe o Proxmox gerar user-data, network-config e meta-data, e configure apenas usuário, chave e rede. Esse caminho já entrega a maior parte do benefício com poucas peças.

Depois que o básico funcionar

Adicione um vendor-data curto com:

  • QEMU Guest Agent;
  • timezone;
  • NTP;
  • ferramentas administrativas realmente usadas;
  • uma baseline mínima de segurança.

Não coloque a aplicação inteira nessa camada.

Para serviços permanentes

Use:

  • cloud-init para acesso inicial e identidade;
  • Ansible para aplicações, firewall do guest e manutenção;
  • backup do Proxmox para recuperação;
  • monitoramento para detectar falha de serviço;
  • DNS e inventário como fontes organizadas de nomes e endereços.

Para muitos templates

Adote Packer somente depois que o processo manual estiver entendido. Versione a origem, o checksum, os snippets e o código de construção. Gere templates novos em vez de editar indefinidamente o mesmo disco.

Para evitar problemas

  • não inicialize o template “só para testar” e depois o clone sem limpeza;
  • não armazene segredos em cloud-init;
  • não espere que mudar user-data após o primeiro boot reaplique tudo;
  • não presuma o nome do disco importado;
  • não substitua a lista de tipos do storage ao habilitar snippets;
  • não use snippets locais em cluster sem replicação;
  • não formate discos por cloud-init sem teste destrutivo controlado;
  • não confunda “VM ligada” com “provisionamento concluído”.

Conclusão

No Proxmox, criar seu próprio fluxo de cloud-init é mais simples do que montar uma nuvem inteira. O hipervisor já consegue gerar a mídia NoCloud; você precisa de uma imagem cloud confiável, um template bem preparado e uma configuração por clone.

A melhor primeira versão é deliberadamente pequena: imagem oficial, disco cloud-init, usuário, chave SSH, DHCP ou IP estático e QEMU Guest Agent. Depois, snippets adicionam uma baseline própria. Se a preparação crescer, Packer constrói a imagem e Ansible assume a configuração contínua.

O segredo de um bom template não é conter tudo. É ser limpo, reproduzível, sem identidade reutilizada, sem segredos e fácil de substituir. Quando um clone novo nasce com hostname, rede, chaves e acesso corretos, e o processo pode ser repetido sem trabalho manual dentro da VM, o cloud-init está cumprindo seu papel.

Fontes consultadas


Nota sobre atualidade

Pesquisa concluída em 25 de julho de 2026. Comandos, opções da interface, versões de distribuições e formatos aceitos podem mudar. Confirme nomes de imagens, checksums, suporte da distribuição e sintaxe na documentação oficial antes de aplicar em produção.