AWS na Prática: EC2, VPC e IAM em Profundidade

[303] AWS na Prática: EC2, VPC e IAM em Profundidade

Os três serviços mais fundamentais da AWS em profundidade: famílias de instância e ciclo de vida do EC2, tipos de volume EBS, user data e o instance metadata, o planejamento de CIDR que é difícil de desfazer, security groups contra NACLs, VPC endpoints e o modelo de avaliação de políticas do IAM.
DevOps

22 min de leitura

Os artigos anteriores (Grafana: Dashboards e Alertas que Fazem Sentido, Rastreamento Distribuído com OpenTelemetry, Alertas Inteligentes e Cultura de Resposta a Incidentes) introduziram EC2, VPC e IAM como parte da prática com Terraform. Os recursos foram criados, o código funcionou. Mas criar recursos via Terraform sem entender profundamente os serviços subjacentes é construir sobre uma fundação frágil — quando algo dá errado, quando o comportamento não é o esperado, quando é necessário tomar uma decisão de arquitetura, a falta de conhecimento profundo se manifesta como horas de debugging e decisões subótimas.

Este artigo aprofunda os três serviços mais fundamentais da AWS — EC2, VPC e IAM — com o nível de detalhe necessário para tomar decisões de arquitetura conscientes e diagnosticar problemas com eficiência.

EC2 em Profundidade

Famílias de Instâncias e Quando Usar Cada Uma

A AWS oferece centenas de tipos de instâncias organizados em famílias com propósitos distintos. Escolher o tipo errado significa pagar mais por menos performance ou ter um gargalo que não é o esperado.

As famílias mais relevantes para aplicações web e serviços de backend:

Família T — Burstable Performance. As instâncias T acumulam créditos de CPU durante períodos ociosos e os gastam durante picos. São econômicas para workloads com tráfego irregular — servidores de desenvolvimento, ambientes de staging, aplicações com tráfego variável. A geração atual é T4g (ARM Graviton) e T3. O modelo t3.medium (2 vCPU, 4GB RAM) é o ponto de partida mais comum para APIs de médio porte.

A armadilha das instâncias T é o CPU credit exhaustion: se a aplicação demanda CPU continuamente acima da baseline, os créditos se esgotam e a performance cai drasticamente. O CloudWatch expõe a métrica CPUCreditBalance — quando ela se aproxima de zero em uma instância T, é hora de migrar para uma família M.

Família M — General Purpose. Balanceamento equilibrado de CPU, memória e rede. A família M6i (Intel), M6a (AMD) e M6g (Graviton ARM) representa o padrão para servidores de aplicação em produção. A geração Graviton (sufixo g) oferece, em média, 20% mais performance por custo que as equivalentes x86.

Família C — Compute Optimized. Alta proporção de CPU em relação à memória. Indicada para servidores de aplicação que fazem processamento intensivo — codificação de vídeo, análise científica, servidores de jogos, processamento de machine learning para inferência. A família atual é C7g (Graviton).

Família R — Memory Optimized. Alta proporção de memória em relação à CPU. Indicada para bancos de dados in-memory, caches de grande volume, processamento de big data com Spark ou Hadoop. A família R7g é a geração atual.

Família I — Storage Optimized. Alto throughput de I/O com NVMe local. Indicada para bancos de dados que precisam de latência de storage extremamente baixa — Cassandra, MongoDB, Elasticsearch em alta escala. O armazenamento local é efêmero — perde os dados ao parar a instância.

Ciclo de Vida de uma Instância EC2

Entender os estados possíveis de uma instância é fundamental para diagnosticar comportamentos inesperados e automatizar corretamente:

pending → running → stopping → stopped → terminated
              ↓
         shutting-down → terminated

pending — a instância está sendo inicializada. O user_data está sendo executado. A instância ainda não está pronta para receber tráfego.

running — a instância está em execução. Cobrança ocorre neste estado.

stopping — o sistema operacional está sendo encerrado graciosamente. Em instâncias com armazenamento EBS, o volume é preservado.

stopped — a instância está desligada. O EBS é preservado. A cobrança de EC2 cessa, mas o EBS continua sendo cobrado. O IP público é liberado — ao reiniciar, um novo IP é atribuído, a menos que haja um Elastic IP.

shutting-down / terminated — a instância está sendo destruída permanentemente. Por padrão, os volumes EBS com DeleteOnTermination=true são destruídos junto.

EBS: Tipos de Volume e Quando Usar

O Elastic Block Store é o armazenamento de bloco persistente da AWS. A escolha do tipo de volume afeta diretamente a performance e o custo:

gp3 — General Purpose SSD de terceira geração. O padrão recomendado para a maioria dos casos. Oferece 3.000 IOPS e 125 MB/s de throughput base, independentemente do tamanho do volume. IOPS e throughput adicionais podem ser provisionados separadamente. Mais econômico que o gp2 para volumes acima de 1TB.

io2 Block Express — SSD de alta performance com IOPS provisionadas. Usado em bancos de dados que precisam de latência consistente abaixo de 1ms e IOPS acima de 16.000. Significativamente mais caro que o gp3.

st1 — HDD de throughput otimizado. Para dados acessados sequencialmente com alto volume — logs, data warehouses, backups. Não adequado para sistemas operacionais ou bancos de dados transacionais.

sc1 — HDD de custo otimizado. O mais barato da linha. Para dados acessados raramente — arquivos de backup, dados frios.

# Exemplo de configuração de volumes no Terraform
resource "aws_instance" "banco_dados" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "r6g.xlarge"

  # Volume raiz — sistema operacional
  root_block_device {
    volume_type           = "gp3"
    volume_size           = 50
    encrypted             = true
    delete_on_termination = true
  }

  # Volume de dados — banco de dados
  ebs_block_device {
    device_name           = "/dev/sdb"
    volume_type           = "io2"
    volume_size           = 500
    iops                  = 10000
    encrypted             = true
    delete_on_termination = false  # preserva dados ao terminar a instância
  }
}

User Data e Instance Metadata Service

O user data é um script executado uma única vez quando a instância inicia pela primeira vez. É o mecanismo de bootstrapping — instalação de pacotes, configuração inicial, registro em sistemas de configuração.

#!/bin/bash
# user_data.sh — script de bootstrapping de uma instância de aplicação

set -euo pipefail

# Configura logging do user_data
exec > >(tee /var/log/user-data.log | logger -t user-data -s 2>/dev/console) 2>&1

echo "=== Iniciando bootstrapping ==="
echo "Instância: $(curl -s http://169.254.169.254/latest/meta-data/instance-id)"
echo "AZ: $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)"
echo "Tipo: $(curl -s http://169.254.169.254/latest/meta-data/instance-type)"

# Atualiza o sistema
apt-get update -y
apt-get upgrade -y

# Instala dependências
apt-get install -y docker.io awscli jq

# Configura Docker
systemctl enable docker
systemctl start docker
usermod -aG docker ubuntu

# Lê segredos do AWS Secrets Manager
SECRET=$(aws secretsmanager get-secret-value \
  --secret-id "minha-api/producao" \
  --region us-east-1 \
  --query SecretString \
  --output text)

# Cria o arquivo .env a partir dos segredos
echo "$SECRET" | jq -r 'to_entries[] | "\(.key)=\(.value)"' \
  > /opt/minha-api/.env
chmod 600 /opt/minha-api/.env

# Baixa e inicia a aplicação
ACCOUNT_ID=$(curl -s http://169.254.169.254/latest/meta-data/iam/info \
  | jq -r '.InstanceProfileArn' | cut -d: -f5)
REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/region)

aws ecr get-login-password --region $REGION | \
  docker login --username AWS --password-stdin \
  $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com

docker run -d \
  --name minha-api \
  --restart unless-stopped \
  --env-file /opt/minha-api/.env \
  -p 3000:3000 \
  $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/minha-api:latest

echo "=== Bootstrapping concluído ==="

O Instance Metadata Service (IMDS) disponível em http://169.254.169.254/latest/meta-data/ expõe informações sobre a instância — ID, tipo, AZ, IP, IAM role — sem necessidade de credenciais. A versão IMDSv2 é mais segura e exige um token de sessão:

# IMDSv2 — recomendado para novas instâncias
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

INSTANCE_ID=$(curl -s \
  -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/instance-id)

PRIVATE_IP=$(curl -s \
  -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/local-ipv4)

IAM_ROLE=$(curl -s \
  -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/)

VPC em Profundidade

CIDR Planning: A Decisão Que É Difícil de Desfazer

O bloco CIDR de uma VPC é uma das poucas decisões em infraestrutura AWS que é genuinamente difícil de reverter. Uma vez que a VPC está criada e tem recursos dentro dela, alterar o CIDR principal exige destruir e recriar tudo.

Princípios para planejamento de CIDR:

Use blocos /16 para VPCs de produção. Um /16 oferece 65.536 endereços — espaço mais que suficiente para crescer sem desperdiçar. Blocos menores parecem econômicos mas criam problemas quando o sistema cresce.

Evite sobreposição com redes on-premises. Se a empresa tem ou planeja ter uma conexão VPN ou Direct Connect com data center próprio, os blocos CIDR não podem se sobrepor. Os ranges 10.0.0.0/8, 172.16.0.0/12 e 192.168.0.0/16 são os ranges privados RFC 1918 — planeje a alocação com antecedência.

Reserve espaço para crescimento. Se a organização tem múltiplas contas AWS com peering entre VPCs, todos os blocos CIDR precisam ser distintos.

Uma estrutura de alocação para uma organização com múltiplos ambientes:

10.0.0.0/8  — range organizacional completo

  10.0.0.0/16   — conta Production
    10.0.0.0/24  — subnet pública AZ-a
    10.0.1.0/24  — subnet pública AZ-b
    10.0.2.0/24  — subnet pública AZ-c
    10.0.10.0/24 — subnet privada app AZ-a
    10.0.11.0/24 — subnet privada app AZ-b
    10.0.12.0/24 — subnet privada app AZ-c
    10.0.20.0/24 — subnet privada db AZ-a
    10.0.21.0/24 — subnet privada db AZ-b
    10.0.22.0/24 — subnet privada db AZ-c

  10.1.0.0/16   — conta Staging
  10.2.0.0/16   — conta Development
  10.3.0.0/16   — conta Shared Services

Security Groups vs NACLs: Quando Usar Cada Um

Ambos controlam tráfego de rede, mas com filosofias e aplicações diferentes:

Security Groups são stateful e operam no nível de instâncias e interfaces de rede. Stateful significa que o tráfego de retorno de uma conexão iniciada de dentro é automaticamente permitido, independentemente das regras. Security Groups só têm regras de allow — sem regras de deny explícitas.

Network ACLs são stateless e operam no nível de subnets. Stateless significa que o tráfego de retorno precisa de uma regra explícita de allow. NACLs têm regras de allow e deny, processadas em ordem numérica.

Na prática, a maioria dos times usa Security Groups para controle de acesso e NACLs apenas para regras de bloqueio amplo — bloquear um range de IPs maliciosos, impedir comunicação entre subnets de ambientes diferentes:

# Security Group — controle de acesso granular por recurso
resource "aws_security_group" "aplicacao" {
  name   = "minha-api-app-sg"
  vpc_id = aws_vpc.principal.id

  # Apenas permite tráfego do load balancer — referência por SG
  ingress {
    from_port       = 3000
    to_port         = 3000
    protocol        = "tcp"
    security_groups = [aws_security_group.load_balancer.id]
    description     = "Tráfego do ALB"
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Todo tráfego de saída"
  }
}

# NACL — bloqueio amplo no nível de subnet
resource "aws_network_acl" "privada" {
  vpc_id     = aws_vpc.principal.id
  subnet_ids = aws_subnet.privada[*].id

  # Bloqueia um range de IPs conhecido como malicioso
  ingress {
    rule_no    = 50
    protocol   = "-1"
    action     = "deny"
    cidr_block = "203.0.113.0/24"
    from_port  = 0
    to_port    = 0
  }

  # Permite todo o resto
  ingress {
    rule_no    = 100
    protocol   = "-1"
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }

  egress {
    rule_no    = 100
    protocol   = "-1"
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }
}

VPC Endpoints: Tráfego Interno sem Sair para a Internet

Por padrão, quando uma instância EC2 em uma subnet privada acessa o S3 ou o DynamoDB, o tráfego sai pela internet — passando pelo NAT Gateway e gerando custo de transferência de dados. VPC Endpoints eliminam esse custo e aumentam a segurança ao manter o tráfego dentro da rede da AWS:

# Gateway Endpoint para S3 — gratuito
resource "aws_vpc_endpoint" "s3" {
  vpc_id            = aws_vpc.principal.id
  service_name      = "com.amazonaws.us-east-1.s3"
  vpc_endpoint_type = "Gateway"
  route_table_ids   = aws_route_table.privada[*].id

  tags = {
    Name = "s3-endpoint"
  }
}

# Interface Endpoint para Secrets Manager — tem custo por hora
resource "aws_vpc_endpoint" "secrets_manager" {
  vpc_id              = aws_vpc.principal.id
  service_name        = "com.amazonaws.us-east-1.secretsmanager"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = aws_subnet.privada[*].id
  security_group_ids  = [aws_security_group.vpc_endpoints.id]
  private_dns_enabled = true

  tags = {
    Name = "secretsmanager-endpoint"
  }
}

IAM em Profundidade

O Modelo de Avaliação de Políticas

O IAM avalia permissões seguindo uma lógica bem definida que é fundamental entender para diagnosticar erros de permissão:

1. Deny explícito em qualquer política? → DENY (fim)
2. Allow explícito em alguma política? → ALLOW
3. Nenhum dos dois? → DENY implícito (padrão)

As políticas avaliadas incluem: políticas de identidade (anexadas ao usuário, grupo ou role), políticas de resource (bucket S3, key KMS), SCPs do AWS Organizations e permission boundaries.

Políticas Inline vs Gerenciadas

Existem três tipos de políticas IAM com trade-offs distintos:

AWS Managed Policies — criadas e mantidas pela AWS. Cobrem casos de uso comuns como AmazonS3ReadOnlyAccess e AmazonSSMManagedInstanceCore. São convenientes mas frequentemente mais permissivas que o necessário — concedem acesso a ações que a aplicação não precisa.

Customer Managed Policies — criadas pelo time, reutilizáveis em múltiplas identidades. O padrão recomendado para políticas que seguem o princípio do mínimo privilégio.

Inline Policies — embutidas diretamente em um usuário, grupo ou role. Adequadas para permissões únicas que não fazem sentido ser reutilizadas.

Escrevendo Políticas com Mínimo Privilégio

A tendência natural ao começar com IAM é conceder permissões amplas — s3:* em vez de s3:GetObject — para evitar erros de permissão durante o desenvolvimento. Isso é tecnicamente correto mas perigoso em produção.

Uma política bem construída para uma aplicação que lê e escreve em um bucket S3 específico:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ListarBucket",
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": "arn:aws:s3:::minha-empresa-assets-production",
      "Condition": {
        "StringLike": {
          "s3:prefix": ["uploads/*", "publico/*"]
        }
      }
    },
    {
      "Sid": "OperacoesNosObjetos",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::minha-empresa-assets-production/uploads/*",
        "arn:aws:s3:::minha-empresa-assets-production/publico/*"
      ]
    },
    {
      "Sid": "LerSecretos",
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue"
      ],
      "Resource": "arn:aws:secretsmanager:us-east-1:123456789:secret:minha-api/*"
    },
    {
      "Sid": "LogsCloudWatch",
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogStreams"
      ],
      "Resource": "arn:aws:logs:us-east-1:123456789:log-group:/minha-api/*"
    }
  ]
}

IAM Roles para EC2: O Fluxo de Credenciais

Quando uma instância EC2 tem uma IAM Role associada via Instance Profile, as credenciais temporárias são renovadas automaticamente pelo serviço de metadados. A aplicação nunca lida com Access Keys estáticas:

// A AWS SDK usa automaticamente as credenciais da Instance Role
// Não é necessário configurar ACCESS_KEY_ID ou SECRET_ACCESS_KEY
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');

// O SDK detecta automaticamente as credenciais nesta ordem:
// 1. Variáveis de ambiente (AWS_ACCESS_KEY_ID, etc.)
// 2. Arquivo ~/.aws/credentials
// 3. Instance Metadata Service (IMDS) — usado em EC2 com IAM Role
// 4. ECS Task Role — usado em containers ECS
const s3 = new S3Client({ region: 'us-east-1' });

async function uploadArquivo(buffer, chave) {
  await s3.send(new PutObjectCommand({
    Bucket: process.env.S3_BUCKET,
    Key: chave,
    Body: buffer,
    ServerSideEncryption: 'AES256',
  }));
}

Auditando Permissões com IAM Access Analyzer

O IAM Access Analyzer é um serviço que identifica recursos com acesso externo não intencional e políticas excessivamente permissivas:

# Cria um analyzer para a conta AWS atual
aws accessanalyzer create-analyzer \
  --analyzer-name minha-empresa-analyzer \
  --type ACCOUNT \
  --region us-east-1

# Lista findings — recursos com acesso externo não intencional
aws accessanalyzer list-findings \
  --analyzer-arn arn:aws:access-analyzer:us-east-1:123456789:analyzer/minha-empresa-analyzer \
  --filter '{"status": {"eq": ["ACTIVE"]}}' \
  --query 'findings[*].{Resource:resource,Type:resourceType,Principal:principal}' \
  --output table

# Valida uma política antes de aplicá-la
aws accessanalyzer validate-policy \
  --policy-document file://politica.json \
  --policy-type IDENTITY_POLICY \
  --query 'findings[*].{Tipo:findingType,Mensagem:findingDetails}' \
  --output table

O Que Vem a Seguir

O próximo artigo aprofunda os serviços gerenciados de computação da AWS — ECS para containers, Lambda para funções serverless e como escolher entre as duas abordagens para diferentes tipos de workload.

Referências para Aprofundamento

Documentação oficial AWS

Segurança e boas práticas

Ferramentas

Exercícios

Exercício 1

O que é CPU credit exhaustion nas instâncias da família T, qual métrica do CloudWatch o denuncia, e o que fazer quando ela se aproxima de zero? Para um servidor de banco Cassandra com exigência de I/O local extremo, qual família seria adequada — e que risco ela traz?

Ver resposta

✓ Resposta: As instâncias T são burstable: acumulam créditos de CPU quando estão ociosas e os gastam nos picos. O credit exhaustion acontece quando a aplicação consome CPU continuamente acima da baseline — os créditos acabam e a performance cai drasticamente, limitada à baseline. O sintoma é traiçoeiro porque a instância funcionou bem por horas ou dias antes de degradar, sem nenhuma mudança no código.

A métrica é CPUCreditBalance no CloudWatch. Quando ela se aproxima de zero de forma consistente, o caminho é migrar para a família M (general purpose), que entrega CPU sustentada. É um caso clássico de saturação como indicador preditivo: o saldo de créditos caindo avisa antes de o usuário sentir.

Para o Cassandra, a família adequada é a I (Storage Optimized), com NVMe local e altíssimo throughput de I/O. O risco é que esse armazenamento local é efêmero: os dados são perdidos ao parar a instância. Só é viável em bancos distribuídos que replicam entre nós — como o próprio Cassandra —, onde a perda de um nó é tolerada pelo cluster. Usar armazenamento efêmero como fonte única de verdade seria perder tudo num simples stop.

Exercício 2

Uma instância é parada (stopped) e depois reiniciada. O que acontece com o volume EBS, com o IP público e com a cobrança? E qual a diferença de terminated quanto aos volumes?

Ver resposta

✓ Resposta: O volume EBS é preservado — os dados continuam lá ao religar. O IP público é liberado, e ao reiniciar a instância recebe um endereço novo, a menos que exista um Elastic IP associado. Quanto à cobrança, a de EC2 cessa no estado stopped, mas o EBS continua sendo cobrado — parar não é o mesmo que não pagar nada.

A perda do IP é a pegadinha operacional: qualquer coisa que aponte para o endereço antigo — registro de DNS, allowlist de firewall de terceiro, configuração fixa em outro serviço — quebra silenciosamente após um simples stop/start.

No terminated a instância é destruída permanentemente e, por padrão, os volumes com DeleteOnTermination=true são destruídos junto. É exatamente por isso que, no exemplo do artigo, o volume raiz mantém delete_on_termination = true (é só o sistema operacional, descartável) enquanto o volume de dados io2 usa delete_on_termination = false, preservando o banco mesmo que a instância deixe de existir.

Exercício 3

Por que o CIDR da VPC é descrito como "difícil de desfazer"? Cite duas restrições que precisam ser consideradas antes de escolher o bloco e explique a lógica da alocação 10.0.x / 10.0.1x / 10.0.2x do exemplo.

Ver resposta

✓ Resposta: Porque, uma vez criada a VPC e com recursos dentro dela, alterar o CIDR principal exige destruir e recriar tudo. Não é uma configuração que se ajusta depois — diferente de quase todo o resto na AWS, o erro aqui só se corrige com migração completa.

Duas restrições: não sobrepor redes on-premises, caso exista ou venha a existir VPN ou Direct Connect com o data center próprio — endereços iguais dos dois lados tornam o roteamento impossível; e não sobrepor outras VPCs da organização, já que peering entre VPCs exige blocos distintos. Daí a recomendação de planejar a alocação dentro dos ranges privados da RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) com antecedência, e de usar /16 em produção — 65.536 endereços, espaço para crescer sem desperdício real.

A alocação do exemplo separa por faixa de dezena conforme a camada: 10.0.0-2.0/24 para subnets públicas, 10.0.10-12.0/24 para app privada e 10.0.20-22.0/24 para banco privado, uma por AZ em cada grupo. A vantagem é que o endereço comunica a função: ao ver 10.0.21.4 num log, sabe-se de imediato que é banco, na segunda AZ. E cada camada tem folga de oito subnets antes de esbarrar na faixa seguinte, o que permite crescer sem reorganizar o esquema.

Exercício 4

Explique a diferença entre Security Group e NACL quanto a stateful/stateless, escopo e tipos de regra. Se você precisa bloquear um range de IPs maliciosos para uma subnet inteira, qual dos dois usar e por quê?

Ver resposta

✓ Resposta: Security Groups são stateful, operam no nível de instância / interface de rede e só possuem regras de allow. Stateful significa que o tráfego de retorno de uma conexão iniciada de dentro é automaticamente permitido, sem precisar de regra correspondente — é o que explica um security group de banco funcionar sem nenhum bloco egress.

NACLs são stateless, operam no nível de subnet e têm regras de allow e deny, avaliadas em ordem numérica. Stateless significa que o retorno precisa de regra explícita: liberar a entrada na 443 sem liberar a saída nas portas efêmeras faz a conexão travar pela metade.

Para bloquear um range de IPs maliciosos, a resposta é NACL, por duas razões. Primeiro, security groups não têm regra de deny — só é possível listar o que se permite, o que torna impossível excluir um endereço específico de um acesso já público. Segundo, a NACL age na subnet inteira, protegendo tudo que está ali de uma vez, sem precisar editar o security group de cada recurso.

É o padrão descrito no artigo: security groups para controle de acesso granular entre camadas, NACLs para bloqueio amplo — banir ranges, isolar ambientes.

Exercício 5

Descreva os três passos da avaliação de políticas do IAM. Se uma role tem AmazonS3FullAccess anexada e uma SCP da organização nega s3:DeleteObject, o que acontece ao tentar apagar um objeto? Por que uma aplicação em EC2 com IAM Role não precisa de Access Keys?

Ver resposta

✓ Resposta: A avaliação é: (1) existe deny explícito em alguma política? Então DENY, e a análise termina. (2) Existe allow explícito? Então ALLOW. (3) Nenhum dos dois? DENY implícito, que é o padrão. São consideradas políticas de identidade, políticas de recurso, SCPs do Organizations e permission boundaries.

No caso descrito, a exclusão falha. O AmazonS3FullAccess concede um allow, mas o deny explícito da SCP é avaliado primeiro e vence — deny explícito sempre prevalece sobre qualquer allow, não importa quantas políticas permissivas existam nem quão amplas sejam. É o que torna SCPs e permission boundaries eficazes como barreira organizacional: nenhum administrador de conta consegue anulá-las anexando mais permissões.

Quanto às credenciais: com uma IAM Role associada via Instance Profile, o Instance Metadata Service fornece credenciais temporárias renovadas automaticamente, e o SDK da AWS as descobre sozinho na sua cadeia de resolução (variáveis de ambiente → ~/.aws/credentials → IMDS → ECS Task Role). O ganho de segurança é grande: não existe Access Key estática para vazar em commit, log ou variável de ambiente, nada precisa ser rotacionado manualmente, e as credenciais expiram sozinhas — mesmo que capturadas, têm validade curta e só valem para aquela role.

Comentários

Mais em DevOps

Notificações, Logs e Monitoramento do Pipeline
Notificações, Logs e Monitoramento do Pipeline

O pipeline que falha em silêncio e o alerta genérico que ninguém lê…

Instalando e Rodando Seus Primeiros Containers
Instalando e Rodando Seus Primeiros Containers

Docker na prática: instalação pelo repositório oficial, uso sem sudo…

Kubernetes em Produção: Segurança, GitOps e Deploys Avançados
Kubernetes em Produção: Segurança, GitOps e Deploys Avançados

A distância entre funcionar e estar pronto para produção: os perfis do Pod…