Quando uma instância EC2 cai e uma standby assume no lugar dela em segundos, sem trocar IP, sem trocar MAC, sem esperar DNS propagar, o que realmente aconteceu não foi a AWS "mover" a instância. Foi outra coisa: a peça que carregava a identidade de rede foi desconectada de uma máquina e conectada em outra. Essa peça é a ENI, e entender que ela existe separada da instância muda como você lê praticamente todo o resto da rede na AWS.
O que é uma ENI
Elastic Network Interface é o objeto de rede virtual que efetivamente conecta uma instância EC2 à VPC. É o equivalente lógico de uma placa de rede física, só que desacoplável: pode ser criada, configurada e destruída independente de qualquer instância, e anexada ou desanexada de instâncias diferentes ao longo do tempo.
O ponto que costuma passar despercebido: o IP privado, o IP público, o Elastic IP, o MAC address e os security groups não pertencem à instância, pertencem à ENI. A instância só enxerga rede porque tem uma ENI plugada nela. Toda vez que você lança uma instância EC2 "normal", a AWS cria uma ENI primária automaticamente e já a anexa, então essa separação fica invisível, parece que é tudo a mesma coisa. Só fica óbvia quando você anexa uma segunda ENI, ou quando move uma ENI entre instâncias.
| Atributo | Vive na ENI |
|---|---|
| IP privado (primário e secundários) | Sim |
| IP público / Elastic IP associado | Sim |
| Endereço MAC | Sim |
| Security groups | Sim |
| Subnet (e portanto AZ) | Sim, fixa desde a criação |
| Source/destination check | Sim |
ENI primária vs secundária
Toda instância nasce com uma ENI primária (eth0, índice de dispositivo 0). Ela não pode ser desanexada enquanto a instância existir, e ela também não pode trocar de subnet depois de criada.
ENIs secundárias são opcionais, você cria e anexa quando precisa. Cada uma ocupa um índice de dispositivo diferente (1, 2, 3...) e pode estar em qualquer subnet, desde que na mesma AZ da instância e da mesma VPC.
# criar uma ENI numa subnet específica
aws ec2 create-network-interface \
--subnet-id subnet-0123456789abcdef0 \
--groups sg-0123456789abcdef0 \
--description "eni-servico-interno"
# anexar numa instância já em execução
aws ec2 attach-network-interface \
--network-interface-id eni-0123456789abcdef0 \
--instance-id i-0123456789abcdef0 \
--device-index 1Anexar e desanexar: hot-attach, com ressalvas
ENIs secundárias em geral podem ser anexadas e desanexadas com a instância rodando, sem precisar parar nada:
aws ec2 detach-network-interface --attachment-id eni-attach-0123456789abcdef0
aws ec2 attach-network-interface \
--network-interface-id eni-0123456789abcdef0 \
--instance-id i-0987654321fedcba0 \
--device-index 1Duas ressalvas importantes:
- A AZ é fixa. Uma ENI só pode ser anexada a instâncias na mesma AZ onde a subnet dela existe. Failover via ENI, portanto, só funciona entre instâncias na mesma AZ. Cross-AZ exige outra estratégia (Elastic IP realocado, DNS, load balancer), como vimos em IP privado, público e Elastic IP.
- O sistema operacional pode não perceber sozinho. Detach/attach troca a interface no nível da AWS, mas dependendo da AMI o SO pode precisar de um
dhclientou reinicialização de rede para reconhecer a mudança. Isso costuma ser tratado por scripts de boot (cloud-init, udev rules) nas AMIs oficiais, mas vale testar antes de depender disso em produção.
Para que serve, na prática
Failover rápido. É o caso mais citado, mas é uma consequência do desenho, não o motivo dele existir. Desanexar a ENI da instância com falha e anexar numa standby preserva IP privado, IP público e MAC, então qualquer coisa que dependa desses três (allowlist de firewall, licença presa a MAC, DNS já propagado) continua funcionando sem reconfiguração.
Instância com múltiplas faces de rede. Uma ENI numa subnet pública recebendo tráfego de entrada, outra numa subnet privada falando com banco de dados, na mesma instância. Separa fisicamente o tráfego, e cada ENI pode ter seu próprio conjunto de security groups.
Testar rede antes de comprometer a instância. Criar a ENI, configurar IP, security group e Elastic IP, validar que está tudo certo, e só então anexar na instância de destino.
Densidade de containers. O VPC CNI plugin do EKS e o Fargate atribuem uma ENI (ou um IP secundário numa ENI) por pod. Cada pod recebe um IP roteável de verdade dentro da VPC, sem overlay network nem NAT entre pods, e as security groups da ENI seguem valendo por pod.
Limites: quantas ENIs e IPs cabem numa instância
O número de ENIs e de IPs privados por ENI que uma instância suporta escala com o tamanho da instância, não com a família, um t3.micro e um m5.large de gerações diferentes seguem tabelas parecidas por tamanho equivalente. Alguns exemplos:
| Tipo | ENIs | IPv4 por ENI |
|---|---|---|
| t3.micro | 2 | 2 |
| t3.small | 3 | 4 |
| m5.large | 3 | 10 |
| m5.xlarge | 4 | 15 |
| m5.24xlarge | 15 | 50 |
Os números exatos mudam por tipo e vale sempre conferir a tabela oficial antes de desenhar algo que dependa de um número específico de IPs por instância (é exatamente esse limite, aliás, que define quantos pods por nó o VPC CNI do EKS consegue rodar).
Source/destination check
Toda ENI nasce com source/destination check habilitado: a instância só processa pacotes onde ela é a origem ou o destino declarado. Isso é o comportamento correto para a esmagadora maioria dos casos, mas quebra qualquer cenário onde a instância precisa encaminhar tráfego que não é dela, como uma NAT instance ou uma appliance de rede fazendo proxy.
aws ec2 modify-network-interface-attribute \
--network-interface-id eni-0123456789abcdef0 \
--no-source-dest-checkDesabilitar isso é uma decisão pontual, deve valer só para a ENI que realmente encaminha tráfego de terceiros, nunca como padrão de uma frota inteira.
O que ela não resolve
ENI não substitui NAT Gateway nem Internet Gateway, ela é a interface que se conecta a essas rotas, não o mecanismo de tradução ou saída para internet em si. Também não é o mesmo que Elastic IP: o EIP é um endereço que se associa a uma ENI, a ENI é o objeto que carrega esse endereço junto com o resto da identidade de rede, os dois resolvem problemas diferentes e um depende do outro para existir junto numa instância pública.
Preço
Criar, anexar e desanexar ENIs não tem custo próprio. O que continua sendo cobrado é o que já é cobrado de qualquer forma: a instância em execução, e qualquer Elastic IP associado a uma das interfaces, seguindo a cobrança por hora de todo IPv4 público descrita em IP privado, público e Elastic IP.
Como isso se conecta com o resto
A ENI é a peça que faltava para entender por que IP privado, público e Elastic IP se comportam do jeito que se comportam, eles não são atributos da instância, são atributos de uma interface que a instância está usando, como vimos em IP privado, público e Elastic IP. Também explica por que Placement Groups não têm relação nenhuma com quantas interfaces ou IPs uma instância suporta, placement group decide onde o hardware fica, ENI decide como a rede chega até ele, são eixos independentes. E o limite de quantas ENIs uma instância aguenta vem do mesmo lugar que define CPU e memória disponíveis, o tamanho escolhido em Tipos de instância EC2.
Referências
- AWS. Elastic network interfaces. Documentação oficial sobre criação, anexação e atributos de uma ENI.
- AWS. IP addresses per network interface per instance type. Tabela oficial de limites de ENIs e IPs por tipo de instância.
- AWS. Disabling source/destination checks. Quando e por que desabilitar o source/dest check numa ENI.
- AWS. New: Elastic Network Interfaces in the Virtual Private Cloud. Post original de lançamento da ENI, explicando a motivação por trás do recurso.