← Back to list

AWS para Engenheiros de Dados (Parte 3): AWS Organizations + SCPs (Governança Multi-Conta)

Domine AWS Organizations e SCPs: construa uma governança multi-conta segura e escalável para seus pipelines de Engenharia de Dados.

Rafael Trindade · 2026-07-03 14:30 · 36 claps · 9.9 min read
#aws #engenharia-de-dados #cloud-computing #terraform #arquitetura-de-dados
Open on Medium ↗
Wiki topics: ☁️ · DevOps & Cloud

AWS para Engenheiros de Dados (Parte 3): AWS Organizations + SCPs (Governança Multi-Conta)

Bem-vindo(a) à série AWS para Engenheiros de Dados (Parte 3). Esta série nasceu das minhas anotações, estudos e experiências práticas explorando o ecossistema AWS sob a perspectiva da engenharia de dados. Mais do que aprender serviços específicos, a proposta é entender os fundamentos que sustentam arquiteturas seguras, escaláveis e preparadas para produção.

Ao longo dos próximos capítulos, vamos explorar os principais serviços da AWS conectando teoria e prática, desde os conceitos essenciais até cenários reais de arquitetura, operação, certificações e ambientes produtivos. A ideia é construir uma visão sólida da plataforma, entendendo não apenas como usar cada serviço, mas principalmente por que ele existe e quais problemas ele resolve.

No episódio de hoje, vamos dominar o AWS Organizations + SCPs (Service Control Policies), entendendo como ir além do básico para construir uma estrutura de governança multi-conta robusta, eficiente e totalmente segura para os seus pipelines e ambientes de dados.

“Empresa pequena tem uma conta AWS. Empresa grande tem dezenas; ou centenas. AWS Organizations é o que mantém esse universo sob controle.”

1. O QUE É AWS ORGANIZATIONS?

É o serviço que permite gerenciar múltiplas contas AWS como uma só unidade. Em vez de entrar em cada conta separadamente para aplicar políticas, você define regras no Organizations e elas se propagam automaticamente para toda a hierarquia.

Problema que resolve:

Sem Organizations, cada conta é uma ilha. Com 10 contas, você tem 10 lugares para configurar segurança, 10 faturas separadas, 10 conjuntos de políticas para manter em sincronia e nenhuma garantia de que as regras são consistentes.

Quando empresas usam:

Toda empresa que leva segurança a sério usa multi-conta. A AWS Landing Zone e o AWS Control Tower são construídos em cima do Organizations. Empresas como iFood, Nubank, e Itaú têm centenas de contas organizadas assim.

Por que multi-conta e não multi-VPC?

Exemplo real - Engenharia de Dados:

conta-dados-raw      → ingestão bruta, acesso mínimo
conta-dados-trusted  → transformações Glue/Spark
conta-dados-refined  → consumo Athena/Redshift
conta-dados-sandbox  → analistas testando queries sem risco
conta-segurança      → logs centralizados de tudo
conta-billing        → visibilidade de custos por time

2. ANATOMIA DO AWS ORGANIZATIONS

Os blocos de construção:

Management Account (raiz da organização)
└── Root (ponto de aplicação de SCPs globais)
    ├── OU: Security
    │   └── Conta: log-archive
    │   └── Conta: audit
    ├── OU: Workloads
    │   ├── OU: Produção
    │   │   └── Conta: dados-prod
    │   │   └── Conta: app-prod
    │   └── OU: Homologação
    │       └── Conta: dados-hml
    └── OU: Sandbox
        └── Conta: dev-ana
        └── Conta: dev-rafael
  • Management Account: A conta raiz da organização.
  • Root: O ponto mais alto de aplicação de políticas globais.
  • OU (Organizational Unit): Pense na OU como se fosse uma “pasta” no seu computador. Só que, em vez de guardar arquivos, ela guarda Contas da AWS. Elas servem para agrupar contas que precisam do mesmo nível de segurança. Assim, você aplica uma regra (SCP) na “pasta”, e todas as contas lá dentro herdam a regra automaticamente.
  • Contas-membro: As contas onde seus workloads e dados realmente vivem.

Regra de ouro: SCPs aplicadas num nível afetam tudo abaixo - OUs filhas e todas as contas dentro delas.

3. SCPS - SERVICE CONTROL POLICIES

SCPs são políticas de limite máximo de permissão. Elas não concedem acesso, elas definem o teto do que é possível fazer numa conta.

A metáfora perfeita:

SCP = teto do elevador

IAM Policy = o andar em que você está

Você só pode ir até o andar que a IAM Policy permite,
mas NUNCA acima do teto que a SCP define.

Como SCPs se combinam com IAM:

Permissão efetiva = IAM Policy  ∩  SCP

Exemplo:
  IAM Policy: Allow s3:*  (tudo no S3)
  SCP:        Allow s3:GetObject, s3:PutObject  (só leitura e escrita)

  Resultado efetivo: só GetObject e PutObject
  (a interseção - o que as duas permitem)

Detalhe crítico: SCPs não afetam a Management Account. Ela está sempre fora do alcance das SCPs.

4. EXEMPLOS PRÁTICOS

## Terraform - Estrutura completa de Organizations

# Ativa o Organizations (feito uma vez na Management Account)
resource "aws_organizations_organization" "main" {
  aws_service_access_principals = [
    "cloudtrail.amazonaws.com",
    "config.amazonaws.com",
    "sso.amazonaws.com",
    "billing.amazonaws.com"
  ]
  feature_set = "ALL"  # habilita SCPs
}

# OU raiz de dados
resource "aws_organizations_organizational_unit" "dados" {
  name      = "dados"
  parent_id = aws_organizations_organization.main.roots[0].id
}

# Sub-OU produção
resource "aws_organizations_organizational_unit" "dados_prod" {
  name      = "producao"
  parent_id = aws_organizations_organizational_unit.dados.id
}

# Sub-OU sandbox
resource "aws_organizations_organizational_unit" "sandbox" {
  name      = "sandbox"
  parent_id = aws_organizations_organization.main.roots[0].id
}

# Criar conta-membro para dados de produção
resource "aws_organizations_account" "dados_prod" {
  name      = "empresa-dados-prod"
  email     = "aws-dados-prod@empresa.com"
  parent_id = aws_organizations_organizational_unit.dados_prod.id

  tags = {
    Environment = "production"
    Team        = "data-engineering"
    CostCenter  = "DE-001"
  }
}

## SCPs essenciais para Engenharia de Dados

SCP 1 - Bloquear regiões não aprovadas (aplica no Root):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyUnapprovedRegions",
      "Effect": "Deny",
      "NotAction": [
        "iam:*",
        "organizations:*",
        "support:*",
        "sts:*",
        "cloudfront:*",
        "route53:*",
        "waf:*"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": [
            "sa-east-1",
            "us-east-1"
          ]
        }
      }
    }
  ]
}

⚠️ Use NotAction e não Action aqui. Serviços globais (IAM, Route53, CloudFront) não têm região - se você usar Action: *, vai bloquear até operações de IAM.

SCP 2 - Proteger dados de produção contra deleção acidental:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ProtectDataLakeFromDeletion",
      "Effect": "Deny",
      "Action": [
        "s3:DeleteBucket",
        "s3:DeleteObject",
        "s3:DeleteObjectVersion",
        "glue:DeleteDatabase",
        "glue:DeleteTable",
        "glue:DeleteJob",
        "redshift:DeleteCluster",
        "rds:DeleteDBInstance",
        "rds:DeleteDBCluster"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:PrincipalTag/Role": "DataPlatformAdmin"
        }
      }
    }
  ]
}

SCP 3 - Sandbox com controle de custos:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyExpensiveServicesInSandbox",
      "Effect": "Deny",
      "Action": [
        "redshift:CreateCluster",
        "redshift:RestoreFromClusterSnapshot",
        "elasticmapreduce:RunJobFlow",
        "sagemaker:CreateTrainingJob",
        "ec2:RunInstances"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "ec2:InstanceType": [
            "t3.micro",
            "t3.small",
            "t3.medium"
          ]
        }
      }
    },
    {
      "Sid": "DenyAccessToProductionData",
      "Effect": "Deny",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::empresa-datalake-prod",
        "arn:aws:s3:::empresa-datalake-prod/*"
      ]
    }
  ]
}

SCP 4 - Forçar criptografia em todos os recursos (aplica na OU Produção):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyUnencryptedS3Uploads",
      "Effect": "Deny",
      "Action": "s3:PutObject",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption": "aws:kms"
        }
      }
    },
    {
      "Sid": "DenyUnencryptedRDS",
      "Effect": "Deny",
      "Action": "rds:CreateDBInstance",
      "Resource": "*",
      "Condition": {
        "Bool": {
          "rds:StorageEncrypted": "false"
        }
      }
    }
  ]
}

## Aplicando SCP via Terraform

resource "aws_organizations_policy" "deny_non_approved_regions" {
  name        = "DenyNonApprovedRegions"
  description = "Bloqueia uso de regiões não aprovadas"
  type        = "SERVICE_CONTROL_POLICY"
  content     = file("${path.module}/scps/deny-regions.json")
}

# Aplica no Root (afeta TODA a organização)
resource "aws_organizations_policy_attachment" "deny_regions_root" {
  policy_id = aws_organizations_policy.deny_non_approved_regions.id
  target_id = aws_organizations_organization.main.roots[0].id
}

# SCP específica para sandbox
resource "aws_organizations_policy" "sandbox_guardrails" {
  name    = "SandboxGuardrails"
  type    = "SERVICE_CONTROL_POLICY"
  content = file("${path.module}/scps/sandbox-guardrails.json")
}

resource "aws_organizations_policy_attachment" "sandbox_guardrails" {
  policy_id = aws_organizations_policy.sandbox_guardrails.id
  target_id = aws_organizations_organizational_unit.sandbox.id
}

## CLI - Operações do dia a dia

# Ver estrutura da organização
aws organizations describe-organization

# Listar todas as OUs
aws organizations list-organizational-units-for-parent \
  --parent-id r-xxxx  # ID do Root

# Listar contas numa OU
aws organizations list-accounts-for-parent \
  --parent-id ou-xxxx-xxxxxxxx

# Ver SCPs aplicadas em uma OU
aws organizations list-policies-for-target \
  --target-id ou-xxxx-xxxxxxxx \
  --filter SERVICE_CONTROL_POLICY

# Mover conta de OU (sandbox → produção)
aws organizations move-account \
  --account-id 123456789012 \
  --source-parent-id ou-xxxx-sandbox \
  --destination-parent-id ou-xxxx-producao

# Assumir role em outra conta (cross-account)
aws sts assume-role \
  --role-arn arn:aws:iam::123456789012:role/OrganizationAccountAccessRole \
  --role-session-name acesso-conta-dados-prod

## Python - Automatizando inventário de contas

import boto3

def listar_contas_por_ou(ou_id: str) -> list[dict]:
    """Lista todas as contas de uma OU recursivamente"""
    org = boto3.client('organizations')
    contas = []

    # Contas diretas nesta OU
    paginator = org.get_paginator('list_accounts_for_parent')
    for page in paginator.paginate(ParentId=ou_id):
        for conta in page['Accounts']:
            contas.append({
                'id': conta['Id'],
                'nome': conta['Name'],
                'email': conta['Email'],
                'status': conta['Status'],
                'ou': ou_id
            })

    # OUs filhas (recursão)
    pag_ou = org.get_paginator('list_organizational_units_for_parent')
    for page in pag_ou.paginate(ParentId=ou_id):
        for ou in page['OrganizationalUnits']:
            contas.extend(listar_contas_por_ou(ou['Id']))

    return contas

def verificar_scps_conta(account_id: str) -> list[str]:
    """Retorna todas as SCPs que afetam uma conta, subindo até o Root"""
    org = boto3.client('organizations')
    scps_efetivas = []

    current_id = account_id

    while True:
        parents = org.list_parents(ChildId=current_id)['Parents']
        if not parents:
            break

        parent_id = parents[0]['Id'] # Uma conta/OU só tem 1 pai direto

        policies = org.list_policies_for_target(
            TargetId=parent_id,
            Filter='SERVICE_CONTROL_POLICY'
        )

        for p in policies['Policies']:
            scps_efetivas.append(p['Name'])

        # Prepara para a próxima iteração subindo um nível
        current_id = parent_id

        # Se chegamos no Root, paramos
        if parent_id.startswith('r-'):
            break

    return scps_efetivas

# Uso:
root_id = boto3.client('organizations')\
    .list_roots()['Roots'][0]['Id']

todas_contas = listar_contas_por_ou(root_id)
for conta in todas_contas:
    scps = verificar_scps_conta(conta['id'])
    print(f"{conta['nome']} → SCPs: {scps}")

5. COMO CAI EM CERTIFICAÇÕES AWS

Tabela de conceitos-chave

Pegadinhas clássicas:

  1. SCP não concede permissão. Ela só limita
SCP com Allow s3:* NÃO dá acesso ao S3.
O usuário ainda precisa de uma IAM Policy permitindo.
SCP só remove o que IAM Policy teria dado.
  1. Management Account ignora SCPs
Você aplicou uma SCP que bloqueia EC2 em us-west-2.
A Management Account pode criar EC2 em us-west-2 mesmo assim.
→ Por isso nunca use a Management Account para workloads reais.
  1. SCP com Deny explícito bloqueia TUDO, inclusive admin
Você colocou: Deny s3:DeleteObject para *
O admin da conta, mesmo com AdministratorAccess, não consegue deletar.
→ Cuidado ao aplicar Deny sem Condition de escape.
  1. Consolidated Billing vs. All Features
Consolidated Billing: só une faturas, sem SCPs
All Features: faturas unidas + SCPs + outras políticas

Na prova: "precisa de SCPs" → All Features obrigatório
  1. Reserved Instances e Savings Plans são compartilhados
Conta A tem RI de EC2 mas não usa.
Conta B da mesma organização usa automaticamente.
→ Economia de custo automática entre contas da mesma org.

6. MAPA MENTAL

AWS Organizations
├── ESTRUTURA
│   ├── Management Account → controla tudo, nunca use para workload
│   ├── Root → nível mais alto, SCPs aqui = todas as contas
│   ├── OU → agrupa contas com mesmo perfil de segurança
│   └── Conta-membro → onde os workloads reais ficam
│
├── SCPs
│   ├── Não concedem permissão (só limitam)
│   ├── Afetam tudo abaixo na hierarquia
│   ├── Não afetam Management Account
│   ├── Deny explícito é absoluto (nem admin fura)
│   └── Permissão efetiva = IAM ∩ SCP
│
├── BENEFÍCIOS
│   ├── Consolidated Billing → desconto por volume
│   ├── RI/Savings Plans compartilhados → economia automática
│   ├── Isolamento de blast radius → erro numa conta não afeta outras
│   └── Governança centralizada → uma regra, todas as contas
│
└── INTEGRAÇÃO
    ├── AWS SSO/IAM Identity Center → login único em todas as contas
    ├── AWS Config → conformidade centralizada
    ├── CloudTrail Organizations → logs de todas as contas num S3
    └── AWS Control Tower → Organizations + boas práticas prontas

7. FLASHCARDS:

*SCP Allow `s3:` aplicada na OU dá acesso ao S3?* Não. SCP só define o teto. O usuário ainda precisa de IAM Policy que permita.*

Um admin com AdministratorAccess pode burlar uma SCP Deny?

  • Não. SCP Deny é absoluto ; nem o admin da conta fura.*

A Management Account é afetada pelas SCPs?

  • Não. Por isso nunca use a Management Account para recursos reais.*

Qual a diferença entre Consolidated Billing e All Features?

  • Consolidated Billing só une faturas. All Features habilita SCPs e controle completo.*

8. PENSE COMO ENGENHEIRO

Cenários reais de decisão

Problema 1 - Design de estrutura multi-conta para time de dados:

Contexto: empresa com 3 times (ingestão, transformação, consumo)
          e 3 ambientes (dev, hml, prod)

Estrutura recomendada:

Root
├── OU: Security (log-archive, audit)
├── OU: Shared-Services (tooling compartilhado)
│   └── Conta: cicd (pipelines de dados)
├── OU: DataPlatform
│   ├── OU: Production
│   │   ├── Conta: ingestao-prod
│   │   ├── Conta: transformacao-prod
│   │   └── Conta: consumo-prod
│   ├── OU: Homologacao
│   │   └── Conta: dataplat-hml (uma só para economizar)
│   └── OU: Dev
│       └── Conta: dataplat-dev
└── OU: Sandbox
    └── Conta por analista (auto-provisionado)

Problema 2 - Troubleshooting: “SCP aplicada mas IAM Policy permite por que está bloqueando?”

Diagnóstico:
1. Verifique se a SCP tem Deny explícito (tem precedência absoluta)
2. Verifique se a SCP foi aplicada na OU pai ou no Root
3. Use IAM Policy Simulator para testar permissões efetivas
4. Veja se há SCPs em múltiplos níveis (efeito cumulativo)

Comando útil:
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::ACCOUNT_ID:role/minha-role \
  --action-names s3:DeleteObject \
  --resource-arns arn:aws:s3:::meu-bucket/*

Problema 3 - Custo explodindo em contas de sandbox:

Solução com SCP + Budget:

1. SCP: bloqueia instâncias grandes (> t3.medium)
2. SCP: bloqueia serviços caros (Redshift, EMR, SageMaker)
3. AWS Budgets: alerta quando conta sandbox > $100/mês
4. Lambda: desliga recursos automaticamente às 20h
5. Tag Policy: força tag "CostCenter" em todos os recursos

## Trade-offs importantes:

9. EXERCÍCIOS

## Quiz Rápido

*1. Uma SCP com `Allow ec2:` foi aplicada na OU de Produção. Um novo usuário, sem nenhuma política IAM associada, tenta criar uma instância EC2. O que acontece?**

  • a) Consegue criar - tem AdministratorAccess
  • b) Não consegue - SCP Allow não concede permissão, só limita ✅ (precisa de IAM Policy também)
  • c) Consegue só se a conta for a Management Account
  • d) Depende da Bucket Policy

2. Você aplica uma SCP Deny s3:DeleteObject no Root. O admin da Management Account tenta deletar um objeto S3. O que acontece?

  • a) Não consegue - Deny é absoluto
  • b) Consegue - Management Account ignora SCPs ✅
  • c) Consegue só com MFA
  • d) Depende do Bucket Policy

*3. Qual é a permissão efetiva quando a IAM Policy permite `s3:e a SCP permite apenass3:GetObjectes3:PutObject`?**

  • a) Tudo no S3 (IAM Policy é mais ampla)
  • b) Nada (conflito entre políticas)
  • c) Apenas GetObject e PutObject ✅ (interseção)
  • d) Depende da ordem de aplicação

## Lab Prático

Lab: Multi-conta para Engenharia de Dados:

1. Crie uma organização com All Features
2. Crie OUs: dados-prod, dados-dev, sandbox
3. Crie contas-membro em cada OU
4. Aplique SCP no Root: deny regiões não aprovadas
5. Aplique SCP em sandbox: deny instâncias > t3.medium
6. Aplique SCP em dados-prod: deny delete de S3 e Glue
7. Ative CloudTrail a nível de organização (um log para tudo)
8. Configure Consolidated Billing com Budget de alerta
9. Teste: tente criar EMR na conta sandbox → deve falhar ✅
10. Teste: tente deletar S3 na conta prod → deve falhar ✅

Próximo Passo (Parte 4)

AWS STS + OIDC (autenticação federada: como CI/CD acessa AWS) - Em breve


메타데이터
post_id
97f8ddbe0a4b
slug
aws-para-engenheiros-de-dados-parte-3-aws-organizations-scps-governança-multi-conta-97f8ddbe0a4b
url
https://medium.com/@rafa-trindade/aws-para-engenheiros-de-dados-parte-3-aws-organizations-scps-governan%C3%A7a-multi-conta-97f8ddbe0a4b
canonical_url
https://medium.com/@rafa-trindade/aws-para-engenheiros-de-dados-parte-3-aws-organizations-scps-governan%C3%A7a-multi-conta-97f8ddbe0a4b
author_url
https://medium.com/@rafa-trindade
status
ok
fetched_at
2026-08-02 11:33:19