--- title: "Guia completo de cloud-init no Proxmox" date: 2026-07-25 summary: "Manual prático para criar imagens-base, templates e máquinas virtuais configuradas automaticamente com cloud-init no Proxmox VE." tags: [pesquisa, cloud-init, proxmox, virtualizacao, automacao, linux] flowerColor: "#72d6c9" --- # 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. ```mermaid 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: ```powershell ssh-keygen -t ed25519 -a 100 -C "pablo-proxmox" ``` No Linux, o mesmo comando funciona: ```bash 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: ```bash 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: ```bash 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: ```bash 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: ```text 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: ```bash 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 ```bash 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: ```bash qm config 9000 pvesm list local-lvm --vmid 9000 ``` ### 3. Anexe o disco importado Se o volume criado foi `vm-9000-disk-0`: ```bash 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 ```bash 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 ```bash 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: ```bash qm config 9000 ``` Se quiser que todos os clones comecem, por exemplo, com mais 20 GB: ```bash 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 ```bash 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 ```bash 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: ```bash install -d -m 0700 /root/keys ``` Copie apenas a chave pública para `/root/keys/pablo.pub` e configure: ```bash 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: ```bash qm set 101 --ipconfig0 ip=dhcp,ip6=auto ``` Para somente IPv4 por DHCP: ```bash qm set 101 --ipconfig0 ip=dhcp ``` ### 4. Ou configure IPv4 estático ```bash qm set 101 \ --ipconfig0 ip=192.0.2.50/24,gw=192.0.2.1 ``` DNS e domínio de pesquisa: ```bash qm set 101 --nameserver "1.1.1.1 9.9.9.9" qm set 101 --searchdomain lab.example ``` Para uma segunda interface: ```bash qm set 101 --net1 virtio,bridge=vmbr1 qm set 101 --ipconfig1 ip=dhcp ``` Em VLAN: ```bash 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 ```bash 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 ```bash qm start 101 ``` Abra o console serial ou consulte o endereço obtido pelo DHCP. Dentro da VM: ```bash cloud-init status --wait --long ``` Quando o estado for `done`, teste: ```bash 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: ```bash 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: ```bash 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 é: ```bash 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: ```text /var/lib/vz/snippets/ ``` Crie-o, se necessário: ```bash 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 ```bash 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: ```bash qm set 101 --cicustom \ "vendor=local:snippets/vendor-data.yaml" ``` ### Valide o YAML antes do boot Em uma máquina com cloud-init instalado: ```bash cloud-init schema \ -c ./user-data.yaml \ --annotate ``` Dentro de uma VM já inicializada: ```bash 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. ```yaml #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. ```yaml #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: ```yaml 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: ```yaml 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: ```yaml #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`: ```yaml #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`: ```yaml #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: ```bash 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: ```text 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`: ```bash sudo apt update sudo apt install cloud-image-utils ``` Crie `user-data.yaml`: ```yaml #cloud-config users: - default ssh_pwauth: false packages: - qemu-guest-agent ``` Crie `meta-data.yaml`: ```yaml instance-id: iid-local-lab-001 local-hostname: lab-001 ``` Gere a mídia: ```bash 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: ```bash 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: ```bash 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: ```bash #!/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: ```bash ./criar-vm.sh 101 srv01 dhcp ``` Uso com IP estático: ```bash ./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 é: ```mermaid 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 ```bash cloud-init status --wait --long ``` Saída estruturada: ```bash cloud-init status --format=json ``` ### Logs ```bash 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: ```bash 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 ```bash 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 ```bash 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 ```bash 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 ```bash 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: ```bash 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: ```bash qm cloudinit dump 101 user qm cloudinit dump 101 network qm cloudinit dump 101 meta qm cloudinit pending 101 ``` Se usa snippets: ```bash 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: ```bash 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: ```bash 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: ```bash 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: ```bash 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: ```bash 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: ```bash 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: ```text 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: ```text /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: ```text 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 - [Cloud-init: documentação oficial](https://docs.cloud-init.io/en/latest/) - [Cloud-init: datasource NoCloud](https://docs.cloud-init.io/en/latest/reference/datasources/nocloud.html) - [Cloud-init: eventos e estágios do boot](https://docs.cloud-init.io/en/latest/explanation/events.html) - [Cloud-init: formatos aceitos para user-data](https://docs.cloud-init.io/topics/format.html) - [Cloud-init: cabeçalhos de formatos](https://docs.cloud-init.io/en/latest/reference/config-format-headers.html) - [Cloud-init: referência da linha de comando](https://docs.cloud-init.io/en/latest/reference/cli.html) - [Cloud-init: arquivos internos e dados da instância](https://docs.cloud-init.io/en/latest/development/internal_files.html) - [Cloud-init: hardening e tratamento de dados sensíveis](https://docs.cloud-init.io/en/latest/explanation/hardening.html) - [Cloud-init: exemplos de usuários e grupos](https://docs.cloud-init.io/en/latest/reference/yaml_examples/user_groups.html) - [Cloud-init: atualização e instalação de pacotes](https://docs.cloud-init.io/en/latest/reference/yaml_examples/package_update_upgrade.html) - [Cloud-init: escrita de arquivos](https://docs.cloud-init.io/en/latest/reference/yaml_examples/write_files.html) - [Cloud-init: configuração de rede v2](https://docs.cloud-init.io/en/latest/reference/network-config-format-v2.html) - [Cloud-init: configuração de discos e filesystems](https://docs.cloud-init.io/en/latest/reference/yaml_examples/disk_setup.html) - [Cloud-init: mounts](https://docs.cloud-init.io/en/latest/reference/yaml_examples/mounts.html) - [Cloud-init: locale e timezone](https://docs.cloud-init.io/en/latest/reference/yaml_examples/locale_and_timezone.html) - [Cloud-init: NTP](https://docs.cloud-init.io/en/latest/reference/yaml_examples/ntp.html) - [Cloud-init: bootcmd e runcmd](https://docs.cloud-init.io/en/25.1/reference/yaml_examples/boot_cmds.html) - [Proxmox VE: administração de máquinas virtuais e cloud-init](https://pve.proxmox.com/pve-docs/chapter-qm.html#qm_cloud_init) - [Proxmox VE: guia de administração](https://pve.proxmox.com/pve-docs/pve-admin-guide.html) - [Proxmox: documentação de custom cloud-init e snippets](https://lists.proxmox.com/pipermail/pve-devel/2019-June/037743.html) - [Proxmox: exemplo oficial de criação de template cloud-init](https://lists.proxmox.com/pipermail/pve-devel/2022-September/054161.html) - [Ubuntu Public Images: documentação](https://documentation.ubuntu.com/public-images/) - [Ubuntu Public Images: artefatos publicados](https://documentation.ubuntu.com/public-images/public-images-reference/artifacts/) - [Ubuntu Public Images: verificação de checksum](https://documentation.ubuntu.com/public-images/public-images-how-to/verify-image-checksum/) - [Ubuntu Public Images: criação de datasource cloud-init local](https://documentation.ubuntu.com/public-images/public-images-how-to/use-local-cloud-init-ds/) - [Ubuntu Cloud Images 24.04 LTS](https://cloud-images.ubuntu.com/noble/current/) - [Debian: imagens cloud oficiais](https://cloud.debian.org/images/cloud/) - [Fedora Cloud: downloads oficiais](https://www.fedoraproject.org/cloud/download/) - [HashiCorp Packer: builder oficial para Proxmox ISO](https://developer.hashicorp.com/packer/integrations/hashicorp/proxmox/latest/components/builder/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.