Base de conhecimento

Faça o trabalho de primeira inicialização com cloud-init

Anexe um documento de user-data ao pedido e a instância chega com seu usuário, sua chave, seus pacotes e seu firewall já no lugar.

O que roda, e quando

Toda imagem Linux traz cloud-init. Na primeira inicialização, ele lê o user-data anexado ao seu pedido, aplica-o uma vez e grava um marcador para que nunca mais rode. Tudo isso acontece antes que você pudesse digitar qualquer coisa, que é o ponto: a janela entre uma instância existir e ser configurada é a janela que você não deveria ter.

Valide o documento antes de pedir. O verificador de esquema pega o erro de indentação que, caso contrário, custaria uma reconstrução:

cloud-init schema --config-file user-data.yaml --annotate

Um user-data que faz as coisas úteis

#cloud-config
hostname: edge-01
fqdn: edge-01.example.com
timezone: UTC

users:
  - name: deploy
    groups: [sudo]
    shell: /bin/bash
    sudo: "ALL=(ALL) NOPASSWD:ALL"
    ssh_authorized_keys:
      - ssh-ed25519 AAAAC3Nza... deploy@laptop

ssh_pwauth: false
disable_root: true

package_update: true
package_upgrade: true
packages:
  - nftables
  - vnstat
  - mtr-tiny

write_files:
  - path: /etc/ssh/sshd_config.d/10-local.conf
    permissions: "0644"
    content: |
      PermitRootLogin no
      PasswordAuthentication no
      AllowUsers deploy

runcmd:
  - [systemctl, enable, --now, nftables]
  - [systemctl, restart, ssh]

A primeira linha não é comentário nem opcional. Sem #cloud-config o documento é ignorado silenciosamente e a instância inicializa como se você não tivesse anexado nada.

No AlmaLinux, groups: [sudo] vira groups: [wheel] e o serviço a reiniciar é sshd. Todo o resto é idêntico.

Vendo funcionar

cloud-init status --long
journalctl -u cloud-final -b
less /var/log/cloud-init-output.log

O journal diz em qual estágio falhou. cloud-init-output.log guarda a saída real das suas entradas runcmd, que é onde estará o motivo.

Não coloque segredos nele

O user-data permanece legível de dentro da instância por toda a sua vida:

cloud-init query userdata

Qualquer coisa ali está disponível para qualquer processo que alcance root e para quem restaurar um snapshot do disco. Use-o para instalar uma credencial que busca o segredo, não para carregar o segredo.

Testar sem queimar uma instância

cloud-init clean --logs --reboot

Isso remove o marcador, os logs e o datasource em cache e reinicia para um primeiro boot limpo. Rode em uma instância descartável. Rode em produção e você descobrirá o que o seu runcmd faz na segunda vez, que raramente é o que fez na primeira.

Onde parar

O cloud-init é para bootstrap e não faz ideia do estado em que a máquina deveria estar amanhã. Use-o para chegar ao ponto em que suas ferramentas reais assumem: uma chave, uma rede, um agente. Pare aí. Sessenta linhas é um user-data saudável; seiscentas é um sistema de gerenciamento de configuração sem jeito de convergir.

cloud-init query -a
cloud-init query ds.meta_data

Instance ID, código do site, hostname e os endereços atribuídos no boot estão todos ali, que é o que um script precisa quando tem de se registrar em algum lugar e ainda não sabe onde acordou.

Pronto quando você estiver

Escolha uma cidade. Escolha um tamanho. Pague em cripto.

Sem formulários sobre quem você é, sem esperar aprovação de um humano, sem ligação para verificar nada. O pagamento é confirmado e as credenciais chegam na sua caixa de entrada.