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.
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 é:
- baixar uma imagem cloud oficial e verificar sua integridade;
- importá-la em uma VM que servirá como template;
- adicionar o disco de cloud-init e habilitar console serial e QEMU Guest Agent;
- converter a VM desligada em template;
- criar um clone para cada novo servidor;
- definir usuário, chave SSH, rede e DNS no clone;
- iniciar a VM e aguardar
cloud-init status --wait; - usar snippets somente quando a tela padrão do Proxmox não for suficiente;
- 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:
- Detecção da fonte de dados: o cloud-init procura o disco ou serviço que contém as configurações.
- Rede inicial: a rede necessária para continuar o provisionamento é preparada.
- Configuração: usuários, pacotes, arquivos e outros módulos são processados.
- 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/24e2001:db8::/32sã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.
- Em Create VM, escolha um VMID e nome para o template.
- Em OS, selecione Do not use any media.
- Configure o sistema, CPU, memória e rede.
- Conclua sem iniciar a VM.
- No shell do host, execute
qm disk importpara importar a imagem. - Na aba Hardware, adicione o disco importado à VM usando SCSI.
- Adicione CloudInit Drive.
- Em Options, ajuste a ordem de boot para o disco principal.
- Em Hardware, adicione Serial Port 0 e use display serial, se desejado.
- Habilite QEMU Guest Agent em Options.
- 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
--contentrepresenta a lista completa. Preserve os tipos que já existem no seustorage.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,networkemetagerados pelo Proxmox; - criar apenas
vendor-datapara a baseline comum; - substituir
user-datasomente 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:
defaultpreserva o usuário padrão da distribuição. Se você redefineuserse omitedefault, ele pode deixar de ser criado.lock_passwd: truebloqueia 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
matchpor MAC quando o nome da interface puder mudar; - escreva o MAC entre aspas e em minúsculas;
- prefira rotas
to: defaultagateway4egateway6, 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: falsepara evitar destruir um filesystem reconhecido; - entenda que um erro de identificação pode formatar o disco errado;
- valide o resultado com
lsblk -f,findmnte/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
- Crie uma VM temporária a partir de uma imagem oficial.
- Instale apenas os pacotes-base.
- Valide que a VM inicializa corretamente.
- Remova segredos e estado específico.
- Execute a limpeza final.
- Desligue a VM.
- 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
/tmpe/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:
- registre a versão e o checksum da imagem oficial;
- mantenha a personalização em código;
- reconstrua o template;
- teste um clone;
- publique uma nova versão;
- 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:
- a VM é iniciada;
- o usuário altera
user-data; - reinicia a VM;
- espera que tudo rode novamente;
- 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.logmostra módulos, datasource, decisões e erros internos;cloud-init-output.logregistra 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,virtio0ou equivalente; - CloudInit Drive em
ide2ou outro slot; - placa
net0; - bridge correta;
- boot a partir do disco principal;
cicustom, se utilizado;- parâmetros
ipconfig0,ciuseresshkeys.
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:
ciusernão corresponde ao usuário esperado;- chave pública incorreta ou truncada;
- snippet
user-datasubstituiu 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-configausente; - indentação com tab;
- chave incorreta para a versão instalada;
- módulo ausente;
- tipo errado, como número em vez de string;
write_filesexecutado antes do usuário ou pacote necessário;- comando com caracteres especiais mal interpretado;
- custom
user-datasubstituiu 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:
- verificar nova imagem oficial;
- validar assinatura e checksum;
- revisar changelog da distribuição e do cloud-init;
- reconstruir um template com novo ID;
- clonar uma VM de teste;
- validar acesso, rede, disco, agente, logs e serviços;
- executar scanner de vulnerabilidades aprovado no ambiente;
- promover o novo template;
- manter o anterior durante uma janela curta;
- 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 --longtermina emdone; - 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
- Baixe Ubuntu 24.04 LTS cloud image.
- Verifique checksum.
- Crie VMID
9000. - Importe o disco.
- Adicione CloudInit Drive.
- Configure console serial e QEMU Guest Agent.
- Converta em template.
Fase 2: primeiro clone
- Clone para VMID
101. - Use DHCP.
- Configure seu usuário e chave.
- Inicie.
- Espere o cloud-init terminar.
- Teste SSH.
- Reinicie e confirme estabilidade.
Fase 3: rede estática
- Clone para VMID
102. - Reserve um endereço fora do pool DHCP ou crie reserva.
- Configure IP, prefixo, gateway e DNS.
- Inicie com o console disponível.
- Confirme rotas e resolução.
Fase 4: baseline
- Habilite snippets.
- Crie somente
vendor-data. - Instale
qemu-guest-agent, ferramentas básicas e timezone. - Valide o YAML.
- Teste em VMID
103.
Fase 5: configuração contínua
- Mantenha cloud-init pequeno.
- Instale ou habilite o acesso necessário ao Ansible.
- Aplique serviços pelo Ansible.
- 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
- Cloud-init: documentação oficial
- Cloud-init: datasource NoCloud
- Cloud-init: eventos e estágios do boot
- Cloud-init: formatos aceitos para user-data
- Cloud-init: cabeçalhos de formatos
- Cloud-init: referência da linha de comando
- Cloud-init: arquivos internos e dados da instância
- Cloud-init: hardening e tratamento de dados sensíveis
- Cloud-init: exemplos de usuários e grupos
- Cloud-init: atualização e instalação de pacotes
- Cloud-init: escrita de arquivos
- Cloud-init: configuração de rede v2
- Cloud-init: configuração de discos e filesystems
- Cloud-init: mounts
- Cloud-init: locale e timezone
- Cloud-init: NTP
- Cloud-init: bootcmd e runcmd
- Proxmox VE: administração de máquinas virtuais e cloud-init
- Proxmox VE: guia de administração
- Proxmox: documentação de custom cloud-init e snippets
- Proxmox: exemplo oficial de criação de template cloud-init
- Ubuntu Public Images: documentação
- Ubuntu Public Images: artefatos publicados
- Ubuntu Public Images: verificação de checksum
- Ubuntu Public Images: criação de datasource cloud-init local
- Ubuntu Cloud Images 24.04 LTS
- Debian: imagens cloud oficiais
- Fedora Cloud: downloads oficiais
- HashiCorp Packer: builder oficial para Proxmox ISO
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.