Pular para o conteúdo

AWS · parte 3 de 11

EC2: máquinas virtuais na AWS

Como funcionam as instâncias EC2: tipos, cobrança, grupos de segurança e quando escolher máquinas virtuais em vez de serviços gerenciados.

Revisada em · 23 min de leitura

Tamanho da fonte:
Largura da coluna:

O Amazon EC2 (Elastic Compute Cloud) é um dos serviços mais fundamentais e populares da AWS. Para facilitar o entendimento, pense no EC2 como alugar um computador virtual na nuvem. Você liga, desliga e configura essa máquina como quiser, e paga pelo tempo em que ela fica ligada.

Esta aula começa pelo conceito, passa pelos casos em que vale a pena usar o EC2 e termina com o que você precisa fazer de verdade: lançar uma instância pelo console e pela AWS CLI, colocar uma API em Go para rodar sozinha no boot, proteger a instância com security groups e deixar o número de máquinas se ajustar sozinho com Auto Scaling. Os exemplos usam us-east-1 como região só para dar um contexto concreto. Troque pela sua região.

1. O que é o Amazon EC2?

O EC2 é um serviço de IaaS (Infraestrutura como Serviço). Ele entrega capacidade computacional na nuvem: você recebe uma máquina virtual, chamada instância, e escolhe quanto de processador (CPU), memória (RAM) e disco ela deve ter. Um computador pessoal tem essas peças fixas. No EC2 você troca o tamanho da máquina quando a carga muda, e essa troca leva minutos.

Duas características explicam por que ele é tão usado. A primeira é a flexibilidade de sistema operacional: você escolhe Linux, Windows ou outro sistema disponível como imagem (AMI), e tem acesso de administrador a ele. A segunda é a capacidade de crescer. Você pode aumentar a máquina atual, que é o escalonamento vertical, ou colocar mais máquinas para trabalhar juntas, que é a escalabilidade horizontal.

Arquitetura de produção: alta disponibilidade e escalabilidade

Na prática, instâncias EC2 quase nunca rodam sozinhas. Elas costumam ficar agrupadas em um Auto Scaling group (ASG), espalhadas por mais de uma Zona de Disponibilidade (Multi-AZ). O tráfego chega por um Application Load Balancer (ALB), e os dados ficam em volumes Amazon EBS, que são discos persistentes ligados à instância:

aws ec2 asg alb
figura 1 · aws ec2 asg alb

O desenho mostra o cenário que a seção “Como usar de verdade” monta passo a passo. Cada zona tem uma instância e o seu disco, o ALB reparte as requisições entre elas, e o CloudWatch observa a CPU para decidir quando crescer.

2. Para que serve?

O EC2 é a base para rodar praticamente qualquer carga que antes exigiria um servidor físico. Ele hospeda sites e APIs, sistemas corporativos como ERPs, bancos de dados que você mesmo instala e administra, processamento pesado (renderização, simulações, treinamento de modelos com GPU) e ambientes de desenvolvimento que espelham a produção.

Esses usos têm algo em comum: alguém precisa de um servidor que fique disponível por horas, dias ou meses, com software que o time controla. Quando a aplicação roda de forma curta e disparada por eventos, outras opções são mais econômicas. O Lambda é o exemplo típico. A plataforma Elastic Beanstalk fica no meio do caminho, cuidando das instâncias EC2 por você.

3. Quando usar o EC2?

Escolha o EC2 quando precisa de controle total sobre o ambiente, ou quando a aplicação não cabe bem num modelo serverless. Os casos mais comuns são estes.

  1. Controle do sistema operacional: você precisa instalar pacotes específicos, ajustar o kernel, configurar patches ou ter acesso de administrador.
  2. Aplicações de longa duração: um servidor web ou o backend de um app que precisa responder o tempo todo. Diferente do Lambda, que roda por milissegundos ou minutos, o EC2 mantém o processo vivo.
  3. Migração de sistemas legados (lift and shift): um sistema antigo que roda numa máquina da empresa pode ir para a nuvem quase sem mudanças, porque o EC2 se comporta como um servidor tradicional.
  4. Cargas previsíveis e constantes: quando você sabe que o servidor ficará ligado 24 horas por dia, compromissos de longo prazo costumam sair mais baratos que o preço sob demanda.

Resumo dos tipos de instâncias

Para usar o EC2 com eficiência, convém conhecer as famílias de instâncias, que são combinações de CPU, memória e rede pensadas para cada tipo de carga. O nome da instância, como t3.micro, mostra a família (t3) e o tamanho (micro).

  • Uso geral (por exemplo T e M): equilíbrio entre memória e processamento. Serve bem para sites e APIs pequenas e médias.
  • Otimizadas para computação (por exemplo C): para tarefas que exigem muito processador, como codificação de vídeo.
  • Otimizadas para memória (por exemplo R): para processar grandes volumes de dados na RAM.
  • Computação acelerada (GPU): para processamento gráfico e inteligência artificial.

Para a aula de hoje, t3.micro basta. Ela tem pouca memória e um processador compartilhado, o que é suficiente para testar uma API e errado para carga de produção.

Como usar de verdade

A forma mais segura de aprender é fazer o caminho completo uma vez, do jeito que um time faria: uma instância com a API no boot, um security group que deixa entrar só o que precisa, e depois o mesmo conjunto transformado em Auto Scaling group. Os comandos abaixo usam a AWS CLI v2. Os identificadores (sg-..., i-..., subnet-...) são exemplos que você troca pelos seus.

Antes de começar, confira duas coisas. A primeira é que a CLI está autenticada numa conta de teste (aws sts get-caller-identity deve mostrar a sua conta). A segunda é que você não vai deixar recursos ligados: a seção de custo mostra como desligar e apagar.

Lançar uma instância pelo console

O console é o melhor lugar para entender quais decisões existem antes de automatizá-las. Os nomes dos campos abaixo são os usuais da tela de lançamento, mas não foram conferidos com captura nesta revisão. Se a interface mudar, a lógica continua a mesma.

  1. Abra o EC2, vá em Instâncias e escolha Executar instância.
  2. Dê um nome à instância (por exemplo api-go-1). Esse nome vira a tag Name, que você usa para achar a máquina depois.
  3. Em imagem de máquina (AMI), escolha Amazon Linux 2023. É a imagem padrão recomendada para novas instâncias Linux.
  4. Em tipo de instância, escolha t3.micro.
  5. Em par de chaves, escolha um par existente ou crie um. Sem par de chaves você não entra por SSH, a menos que a AMI tenha outro meio de login.
  6. Em configurações de rede, deixe a VPC padrão para começar. Garanta que existe um IP público, e selecione um security group que libere a porta 80 e a porta 22 só para o seu IP. A seção de security groups mostra como.
  7. Em armazenamento, mantenha o volume raiz padrão, que é um EBS gp3.
  8. Em detalhes avançados, o campo de dados do usuário (user data) recebe o script de inicialização. O perfil de instância IAM também fica aqui, e é ele que dá à instância permissão para usar a AWS sem chaves gravadas no disco.
  9. Revise o resumo e escolha Executar instância.

Depois de lançada, a instância passa pelos estados pending e running. A seção de ciclo de vida explica o que acontece em cada um.

Lançar pela AWS CLI

A CLI deixa o processo repetível, que é o que importa quando você lança mais de uma máquina. Primeiro, crie um par de chaves e guarde o arquivo .pem com permissão restrita:

aws ec2 create-key-pair \
  --key-name chave-api \
  --query 'KeyMaterial' \
  --output text > chave-api.pem

chmod 400 chave-api.pem

O parâmetro --query 'KeyMaterial' pega só a chave privada da resposta. A AWS devolve essa chave uma única vez, por isso o > chave-api.pem precisa estar no mesmo comando. Se você perder o arquivo, o par precisa ser recriado.

Em seguida, crie um security group dentro da sua VPC. Use o ID da VPC padrão, que aparece com aws ec2 describe-vpcs --filters Name=isDefault,Values=true:

aws ec2 create-security-group \
  --group-name sg-api-go \
  --description "API Go, porta 80 publica e 22 restrita" \
  --vpc-id vpc-0123456789abcdef0

A resposta traz o GroupId, algo como {"GroupId": "sg-0abc..."}. Esse valor é o que você usa nos próximos comandos. Note que um security group novo não libera nenhuma entrada, então as regras vêm agora:

aws ec2 authorize-security-group-ingress \
  --group-id sg-0abc1234567890def \
  --protocol tcp --port 80 --cidr 0.0.0.0/0

aws ec2 authorize-security-group-ingress \
  --group-id sg-0abc1234567890def \
  --protocol tcp --port 22 --cidr "$(curl -s https://checkip.amazonaws.com)/32"

A primeira regra abre a porta 80 para qualquer IPv4. A segunda abre a porta 22 só para o seu IP atual, com /32, que é uma máquina só. Se você trocar de rede, o SSH para de funcionar, e a causa é essa regra.

Para descobrir qual AMI usar sem copiar um ID antigo da internet, peça o ID mais recente ao Systems Manager pelo caminho público da imagem:

AMI=$(aws ssm get-parameter \
  --name /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 \
  --query 'Parameter.Value' --output text)

echo "$AMI"

O caminho termina no alias al2023-ami-kernel-default-x86_64, que é a imagem Amazon Linux 2023 para arquitetura x86_64 com o kernel padrão. A AWS documenta esse alias como a forma de pegar a versão mais recente sem fixar um ID. A cada atualização de kernel, o ID muda, e é por isso que você não deve gravá-lo no script.

Agora lance a instância. O script de user data fica num arquivo, que a CLI converte para base64 sozinha quando você usa file://. O perfil de instância aparece porque o script vai copiar um binário do S3, e a própria documentação da AWS exige perfil de instância para chamadas de API feitas dentro do user data:

aws ec2 run-instances \
  --image-id "$AMI" \
  --instance-type t3.micro \
  --key-name chave-api \
  --security-group-ids sg-0abc1234567890def \
  --subnet-id subnet-0123456789abcdef0 \
  --iam-instance-profile Name=perfil-api \
  --user-data file://setup.sh \
  --metadata-options "HttpTokens=required,HttpEndpoint=enabled" \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=api-go-1}]' \
  --count 1

O que cada parâmetro faz:

  • --image-id diz qual AMI usar. Sem ele, o comando não roda, a menos que haja um modelo de lançamento (launch template).
  • --instance-type escolhe o tamanho da máquina.
  • --key-name injeta o par de chaves no usuário padrão da imagem (ec2-user no Amazon Linux).
  • --security-group-ids recebe uma lista de IDs de security group.
  • --subnet-id decide em qual sub-rede, e portanto em qual zona, a instância nasce.
  • --iam-instance-profile associa o perfil com a permissão que o script precisa.
  • --user-data recebe o script. Ele tem limite de 16 KB antes da codificação base64.
  • --metadata-options "HttpTokens=required" exige IMDSv2 para ler os metadados da instância. Sem essa exigência, o serviço de metadados aceita uma requisição simples, sem token, o que facilita ataques em que um processo engana a aplicação para ler credenciais temporárias do perfil.
  • --tag-specifications põe a tag Name já no lançamento, para você achar a máquina depois.
  • --count pede quantas instâncias lançar. Com 1, a chamada cria exatamente uma máquina.

A saída é um JSON grande com o bloco Instances, em que aparecem o InstanceId (algo como i-0123456789abcdef0) e o estado inicial, pending. Para esperar até ficar pronta e ver o IP público:

aws ec2 wait instance-running --instance-ids i-0123456789abcdef0

aws ec2 describe-instances \
  --filters "Name=tag:Name,Values=api-go-1" "Name=instance-state-name,Values=running" \
  --query "Reservations[].Instances[].[InstanceId,PublicIpAddress]" \
  --output table

O wait bloqueia o terminal até o estado virar running. Ele só garante que a máquina ligou. O script de user data pode ainda estar em execução, e a API pode não estar no ar nesse momento.

Anatomia de um user data

O user data é o script que a instância executa no primeiro boot, depois que o sistema operacional sobe. Ele é o que transforma uma AMI genérica numa máquina com a sua aplicação. A documentação da AWS descreve o comportamento que importa aqui: o script roda como root, sem interação, e o log fica em /var/log/cloud-init-output.log. Por padrão, ele roda só no primeiro boot.

O script abaixo instala a API Go a partir de um binário já compilado, guardado num bucket S3, e a registra como serviço do systemd para ela voltar sozinha se cair:

#!/bin/bash
set -euo pipefail

# Roda como root no primeiro boot. Não use sudo aqui.
aws s3 cp s3://meu-bucket-builds/api/v1.2.0/api-linux-amd64 /usr/local/bin/api
chmod 755 /usr/local/bin/api

cat > /etc/systemd/system/api.service <<'UNIT'
[Unit]
Description=API Go
After=network-online.target

[Service]
ExecStart=/usr/local/bin/api
Environment=PORT=5000
Restart=always
User=nobody

[Install]
WantedBy=multi-user.target
UNIT

systemctl daemon-reload
systemctl enable --now api

Cada linha tem uma razão. set -euo pipefail faz o script parar no primeiro erro. Sem isso, um aws s3 cp que falha deixa o restante rodando sobre um arquivo inexistente, e a instância fica running sem API, sem nenhum sinal claro. O Restart=always faz o systemd subir o processo de novo se ele morrer. O User=nobody roda a API sem privilégios, mesmo que o script tenha rodado como root.

O binário é compilado na sua máquina, não na instância, para a arquitetura Linux que a instância usa:

GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o api-linux-amd64 ./cmd/api
aws s3 cp api-linux-amd64 s3://meu-bucket-builds/api/v1.2.0/api-linux-amd64

GOOS e GOARCH dizem o sistema e a arquitetura do alvo. CGO_ENABLED=0 gera um binário estático, que não depende de bibliotecas do sistema. Se a instância for ARM (Graviton, da família t4g), troque amd64 por arm64. Esse detalhe é o erro mais comum de quem copia um binário para a máquina errada: o binário compila, mas o sistema recusa executá-lo.

Para ler a API, a versão mínima do código fica assim. Ela aceita a porta pela variável PORT, com 5000 como padrão, e expõe /health, que um load balancer pode usar para decidir se a instância está saudável:

package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
)

func main() {
	port := os.Getenv("PORT")
	if port == "" {
		port = "5000"
	}

	http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
		fmt.Fprintln(w, "ok")
	})

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "olá, você chegou em %s\n", r.Host)
	})

	log.Printf("escutando na porta %s", port)
	log.Fatal(http.ListenAndServe(":"+port, nil))
}

Testei esse código na minha máquina: compila com go build, passa em go vet, e responde ok em /health quando roda com PORT=8081. A porta 5000 falhou para mim no macOS porque o AirTunes já ocupa essa porta, o que mostra por que o PORT existe: você troca a porta sem mexer no código.

Quando o script termina, o estado da instância continua running. Ele não diz se o script deu certo. Para ver o que aconteceu, entre na máquina e leia o log:

ssh -i chave-api.pem ec2-user@IP_PUBLICO_DA_INSTANCIA
sudo tail -n 50 /var/log/cloud-init-output.log
sudo systemctl status api
ec2 02 user data
figura 2 · ec2 02 user data

O diagrama mostra o caminho de um script de user data. O comando da CLI entrega o script à instância nova, o cloud-init executa uma vez no primeiro boot, e o resultado depende de cada comando. Quando tudo dá certo, a API sobe na porta 5000. Quando um comando falha, o fluxo vermelho termina numa instância que está running e sem a aplicação. Por isso o log é o primeiro lugar a olhar.

Security groups

O security group é um firewall virtual associado à instância. Ele decide quais conexões entram e quais saem. A documentação da AWS descreve o comportamento que importa: o security group é stateful, então a resposta de uma conexão que você iniciou volta mesmo sem regra de entrada explícita. Um security group novo, que você cria sem regras, não libera nenhuma entrada.

A regra mais útil, e a menos óbvia, é aceitar tráfego de outro security group, em vez de um IP. Assim o banco aceita conexões de qualquer instância que pertença ao grupo da API, e a lista muda sozinha quando o Auto Scaling cria ou apaga máquinas. A documentação da AWS faz uma ressalva importante: se o tráfego passa por um equipamento intermediário entre duas instâncias, a referência ao grupo de origem não basta, e é preciso liberar pelo IP ou pelo bloco da sub-rede.

ec2 04 security groups
figura 3 · ec2 04 security groups

O desenho mostra três grupos em cadeia. A internet chega ao ALB pela porta 443, o ALB fala com a API na porta 5000 e a API fala com o banco na porta 5432. Cada salto é liberado pela referência ao grupo anterior, e não por um endereço. O atacante tenta falar com o banco direto, e a regra do sg-db bloqueia, porque a origem permitida é só o sg-app. A conexão do SSH aparece pontilhada, porque é uma exceção de administração e não tráfego da aplicação.

Os erros mais comuns com security groups são estes: abrir a porta 5000 para 0.0.0.0/0 (isso permite contornar o ALB e falar com a API direto), esquecer que o health check do load balancer também precisa passar pelo grupo, e liberar o SSH para o mundo inteiro. A documentação sobre balanceadores orienta que o security group do load balancer consiga falar com as instâncias, e o do grupo de instâncias aceite a porta do health check.

Auto Scaling group com launch template

ec2 03 api em asg
figura 4 · ec2 03 api em asg

O desenho mostra a versão do cenário que vamos montar, com a API em duas zonas. O tráfego entra pelo ALB, o ALB reparte entre as instâncias de cada zona, e todas falam com o mesmo PostgreSQL. O grupo Auto Scaling group engloba as zonas: ele decide quantas instâncias existem, em qual zona cada uma nasce e quando substituir ou criar outra. O banco fica de fora do grupo, porque ele não escala com as instâncias da API.

Uma instância solta é um ponto único de falha. O Auto Scaling group (ASG) mantém um número de instâncias dentro de um intervalo, substitui as que falham e, com uma política de escala, aumenta ou reduz a capacidade com a carga. A documentação da AWS resume o comportamento: o grupo começa lançando a capacidade desejada, faz health checks periódicos e, quando uma instância fica insalubre, termina a máquina e lança outra no lugar.

Para o ASG saber o que lançar, você cria um launch template, que é um modelo com AMI, tipo, chave, security group, perfil e user data. Ele substitui os parâmetros repetidos do run-instances. O user data precisa estar em base64 dentro do template, por isso o arquivo JSON abaixo traz um marcador a ser preenchido:

{
  "ImageId": "ami-0123456789abcdef0",
  "InstanceType": "t3.micro",
  "KeyName": "chave-api",
  "SecurityGroupIds": ["sg-0abc1234567890def"],
  "UserData": "COLE_AQUI_O_SETUP_SH_EM_BASE64",
  "IamInstanceProfile": { "Name": "perfil-api" },
  "MetadataOptions": {
    "HttpTokens": "required",
    "HttpPutResponseHopLimit": 1,
    "HttpEndpoint": "enabled"
  }
}

Gere o valor com base64 -w0 setup.sh no Linux, ou base64 -i setup.sh no macOS, que não aceita -w0. A saída é uma linha só, que você cola no campo. Depois, crie o template e o grupo:

aws ec2 create-launch-template \
  --launch-template-name lt-api-go \
  --version-description "v1 com API 1.2.0" \
  --launch-template-data file://lt.json

aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name asg-api-go \
  --launch-template LaunchTemplateName=lt-api-go,Version='$Latest' \
  --min-size 2 \
  --max-size 4 \
  --desired-capacity 2 \
  --vpc-zone-identifier "subnet-0aaa111122223333a,subnet-0bbb444455556666b" \
  --target-group-arns arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/tg-api/0123456789abcdef \
  --health-check-type ELB \
  --health-check-grace-period 120

Os parâmetros do grupo fazem o seguinte. --min-size e --max-size definem o intervalo que a escala pode usar. --desired-capacity é a quantidade que o grupo tenta manter agora, e precisa ficar entre os dois limites. --vpc-zone-identifier lista as sub-redes, cada uma numa zona diferente, e o grupo espalha as instâncias entre elas. --target-group-arns registra as instâncias no target group do ALB. --health-check-type ELB faz o ASG considerar o health check do load balancer, e não só se a máquina está ligada. Sem isso, uma API travada com a máquina ligada não seria substituída. O --health-check-grace-period dá tempo para o script de boot terminar antes do primeiro check, senão o grupo mata a instância que ainda está instalando a API.

A escala automática fica em uma política associada ao grupo. Uma política de target tracking, por exemplo, tenta manter a CPU média perto de um alvo, como 50%. A forma exata do JSON dessa política não foi conferida na referência da CLI nesta revisão, então consulte a documentação antes de usá-la.

Como o ASG lança instâncias usando o launch template, uma correção no script significa uma versão nova do template. As instâncias antigas continuam com o script antigo até serem substituídas. Uma forma comum de implantar é criar a versão nova do template e atualizar o grupo, substituindo as instâncias aos poucos. A seção de deploy do Elastic Beanstalk e a nota de Estratégias de Deploy na AWS tratam dessas estratégias.

ec2 05 falha e substituicao
figura 5 · ec2 05 falha e substituicao

O diagrama mostra o ciclo de uma falha. O ALB verifica cada instância, e a instância 2 deixa de responder. O load balancer para de mandar tráfego para ela, e o ASG a encerra. Como a capacidade desejada é 2, o grupo lança uma terceira instância, que roda o user data e só depois se registra no ALB. O efeito para o usuário é que a falha some do caminho dele, desde que a outra instância aguente a carga enquanto a nova sobe.

Ciclo de vida e custo

Uma instância passa por estados que definem o que você paga e o que sobrevive. Entender esses estados evita duas surpresas comuns: uma máquina “desligada” que continua cobrando, e uma máquina que perde o IP sem aviso.

ec2 01 ciclo de vida
figura 6 · ec2 01 ciclo de vida

No estado running, você paga pela computação. Ao parar a instância (stop), a cobrança de computação cessa, mas o volume EBS continua existindo e continua cobrado. Ao iniciar de novo, a instância volta com o mesmo disco, e o IP público pode mudar, a menos que você use um Elastic IP. Ao encerrar (terminate), a instância é apagada, e o volume raiz vai junto por padrão. Esse é o estado de que não há volta, por isso o caminho do encerramento aparece em vermelho.

O preço segue o modelo de pagamento pelo uso, mas a AWS tem várias modalidades. No modelo sob demanda você paga pelo tempo ligado, sem compromisso. Instâncias reservadas e Savings Plans trocam um compromisso de uso por desconto. Instâncias Spot usam capacidade ociosa a um preço menor, com o risco de a AWS recuperá-la. Os valores variam por região e mudam com o tempo, por isso esta nota não traz tabela de preços. Use a calculadora oficial da AWS antes de decidir.

O Free Tier mudou. A página oficial consultada em 27 de outubro de 2026 descreve um plano gratuito com créditos (até US$ 200 no total, válidos por até 6 meses, conforme a página) e diz que o EC2 está disponível nos dois planos. Ela não cita 750 horas mensais de t3.micro ou t4g.micro, então essa informação antiga não foi mantida. Confira a página de planos da sua conta antes de contar com qualquer cota gratuita.

Para não gastar à toa durante a aula, encerre o que criou. Liste as instâncias com a tag e apague:

aws ec2 describe-instances \
  --filters "Name=tag:Name,Values=api-go-1" "Name=instance-state-name,Values=running,stopped" \
  --query "Reservations[].Instances[].InstanceId" --output text

aws ec2 terminate-instances --instance-ids i-0123456789abcdef0

Depois, apague o ASG, o launch template e o security group, nessa ordem, porque o grupo usa o template e o template usa o security group. O comando aws autoscaling delete-auto-scaling-group --auto-scaling-group-name asg-api-go --force-delete deve remover o grupo e as instâncias dele. A opção --force-delete não foi conferida na referência da CLI nesta revisão.

Erros comuns e como resolver

Os erros abaixo aparecem com frequência, e quase todos têm causa identificável no log ou na regra de rede.

  • A instância está running, mas a API não responde. A causa mais comum é o script ter falhado no meio. Leia /var/log/cloud-init-output.log antes de mexer em qualquer outra coisa.
  • O script trava esperando resposta. A documentação pede que os comandos rodem sem interação, então use dnf install -y. Um comando que pede confirmação espera para sempre.
  • O script usa sudo. Ele já roda como root, então o sudo é desnecessário. Os arquivos criados pertencem ao root, e você precisa ajustar as permissões se outro usuário precisar deles.
  • O comando aws s3 cp falha com erro de credencial. A instância não tem perfil de instância com permissão para ler o bucket. Associe o perfil no lançamento, e confira a política do IAM.
  • O user data não roda depois de um reboot. Por padrão ele roda só no primeiro boot. Se você precisa que rode de novo, veja a orientação de reexecução que a AWS documenta.
  • O load balancer marca todas as instâncias como não saudáveis. Geralmente o security group das instâncias não aceita a porta do health check vinda do grupo do ALB, ou a API não responde no caminho configurado.
  • O user data não cabe. O limite é de 16 KB antes da codificação base64. Se o script for maior, guarde-o num bucket e faça só o download no user data, como o exemplo acima faz.
  • Na sua máquina, a porta 5000 não sobe no macOS. O AirTunes ocupa essa porta. Use PORT=8081 localmente, e mantenha 5000 apenas na instância.
  • A instância nova não recebe tráfego mesmo com o ASG criando máquinas. O grupo pode ter sido criado sem o target group, ou a sub-rede pode não estar associada ao ALB.

Cobrança

O modelo de cobrança do EC2 segue a lógica de pagamento pelo uso, parecida com a conta de luz. Você paga pelo que consome, sem taxa mensal fixa obrigatória no modelo sob demanda, e sem contrato de longo prazo.

1. Cobrança por tempo de execução

O valor depende do tempo em que a instância fica no estado running. Ao iniciar a máquina, o relógio começa. Ao pará-la, a cobrança de computação para. Essa é a base da elasticidade financeira: num pico de acesso você aumenta a capacidade e paga por ela só durante o pico. Passado o evento, as instâncias extras são encerradas e a cobrança cessa.

Lembre que parar não zera a conta. O volume EBS continua existindo e continua cobrado enquanto a instância estiver parada, como mostrou o diagrama de ciclo de vida.

2. Modalidades de compra

A AWS oferece modalidades diferentes para o mesmo tipo de máquina. Instâncias sob demanda são o modelo mais flexível e têm a tarifa por hora mais alta. Instâncias reservadas e Savings Plans exigem um compromisso de uso, em geral de um a três anos, em troca de desconto. Instâncias Spot aproveitam capacidade ociosa a um preço menor, mas a AWS pode recuperar a máquina com pouco aviso, por isso servem para trabalho que aguenta interrupção.

3. Nível gratuito

O Free Tier atual, descrito na seção de ciclo de vida e custo, é baseado em créditos. Conferir os detalhes na página de planos da sua conta é mais seguro do que confiar em números de guias antigos.

Não verificado nesta revisão

  • Preços por hora de instâncias e de volumes EBS: não consultados. Use a calculadora oficial.
  • O comportamento do IP público ao parar e iniciar, o fato de o volume EBS continuar cobrado com a instância parada e o volume raiz ser apagado junto com a instância por padrão: descritos com base no conhecimento geral do serviço, não reconfirmados na documentação nesta revisão.
  • Se a AWS CLI já vem instalada na AMI Amazon Linux 2023, o que o script de user data assume para o comando aws s3 cp: não confirmado nesta revisão.
  • A forma exata do JSON de uma política de target tracking em aws autoscaling put-scaling-policy: não conferida na referência da CLI.
  • Os nomes exatos dos campos da tela de lançamento do console: conferidos pela descrição de documentação, não por captura de tela.
  • Os comandos da AWS CLI nesta aula não foram executados contra uma conta. Os formatos de saída mostrados são os esperados pela documentação, com identificadores de exemplo.
  • Java: a plataforma Java do Elastic Beanstalk existe, mas o layout do bundle e a porta da aplicação não foram confirmados na documentação oficial nesta revisão.

Fontes

Consultadas em 27 de outubro de 2026.

↑ Voltar ao topo

Atalhos de teclado

Abrir busca
/
Alternar tema claro/escuro
t
Aula anterior na série
←
Próxima aula na série
→
Lista de atalhos
?