M02 — ADLS Gen2 + arquitetura Medallion
Duração: 2h Pré-requisitos: M01 concluído (Storage Account com HNS habilitado). Objetivo: criar a estrutura de bronze / silver / gold, entender ACLs, fazer o primeiro upload de dados, configurar lifecycle para economizar.
Conceitos
Medallion (camadas Bronze / Silver / Gold)
| Camada | Função | Estado dos dados | Formato típico |
|---|---|---|---|
| Bronze | Cópia fiel da fonte (raw) | Imutável, append-only, sem regra de negócio | Parquet/JSON/CSV originais |
| Silver | Limpo, tipado, deduplicado | Schema estável, pronto para análise | Delta |
| Gold | Agregado para consumo (BI/ML) | Star schema, fato/dim, marts | Delta |
Princípio: cada camada lê só da anterior (bronze → silver → gold). Nunca silver lendo direto da fonte, nunca gold lendo bronze.
Container vs File System vs Pasta
No ADLS Gen2:
- Container = “File System” raiz (em Gen2 são sinônimos). Limite: 500 por storage.
- Dentro do container: pastas reais (não prefixos como no S3).
- URL:
abfss://<container>@<storage>.dfs.core.windows.net/<pasta>/<arquivo>
ACLs vs RBAC
- RBAC (Role-Based Access Control): permissão em nível de Storage / Container (ex.: “Storage Blob Data Contributor” no container
bronze). - ACL POSIX: permissão por pasta/arquivo (ex.: usuário X só pode ler
silver/clientes_anonimizados/). - Boa prática: RBAC para grupos amplos, ACL para casos finos.
Parte 1 — Criar os 3 containers (CLI)
Variáveis do M01:
$PROJ = "de"; $INIC = "w"; $AMB = "dev"; $REGS = "brs"$RG = "rg-$PROJ-$AMB-$REGS"$ST = "st$PROJ$INIC$AMB$REGS" # confira com: az storage account list -g $RG -o tableCriar containers:
foreach ($c in @("bronze","silver","gold")) { az storage container create ` --account-name $ST ` --name $c ` --auth-mode login}--auth-mode login usa seu usuário Azure CLI (RBAC), não a chave. É a forma recomendada (você é Owner do RG; tem permissão).
Validar:
az storage container list --account-name $ST --auth-mode login --query "[].name" -o tsvEsperado:
bronzesilvergoldParte 2 — Estrutura de pastas dentro de cada camada
Convenção da trilha (vai aparecer no M04/M05/M08):
bronze/ └─ source=sqlserver/ └─ schema=sales/ └─ table=customer/ └─ ingestion_date=2026-05-16/ └─ customer_20260516_001.parquet
silver/ └─ domain=sales/ └─ customer/ └─ _delta_log/ └─ part-00000-....snappy.parquet
gold/ └─ mart=sales/ └─ fact_orders/ └─ _delta_log/ └─ ... └─ dim_customer/ └─ _delta_log/ └─ ...Por que assim:
- Bronze particiona por data de ingestão → permite reprocessamento sem afetar histórico.
- Silver/Gold são Delta tables (uma pasta = uma tabela com
_delta_log/). - Caminhos legíveis = debug em produção rápido.
Parte 3 — Primeiro upload (dataset público de exemplo)
Vamos baixar um dataset pequeno (NYC Taxi, ~12 MB) e subir pro Bronze.
Passo 3.1 — Baixar localmente
$DEST = "C:\Users\willi\Downloads\nyc-yellow-2024-01.parquet"Invoke-WebRequest ` -Uri "https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2024-01.parquet" ` -OutFile $DESTConfirme:
Get-Item $DEST | Select-Object Name, LengthEsperado: tamanho ~50 MB.
Passo 3.2 — Subir para Bronze
az storage blob upload ` --account-name $ST ` --auth-mode login ` --container-name bronze ` --name "source=nyctaxi/dataset=yellow/year=2024/month=01/yellow_tripdata_2024-01.parquet" ` --file $DESTValidar:
az storage blob list ` --account-name $ST ` --auth-mode login ` --container-name bronze ` --prefix "source=nyctaxi" ` --query "[].{name:name, size:properties.contentLength}" -o tablePasso 3.3 — Ver no portal
Portal → Storage Account → Storage browser (menu esquerdo) → bronze → navega na hierarquia. Note que cada nível é uma pasta real (graças ao HNS), não um prefixo.
Parte 4 — Lifecycle Management (economia)
Bronze cresce sem parar. Você não quer pagar Hot para dado de 3 anos atrás.
Política sugerida
- Arquivos com 30+ dias sem acesso → tier Cool (50% mais barato em storage, mas paga retrieval).
- Arquivos com 90+ dias → tier Archive (95% mais barato; retrieval em horas).
- Snapshots/versões antigas → deletar após 30 dias.
Aplicar via CLI
Crie o JSON lifecycle.json na sua pasta:
{ "rules": [ { "enabled": true, "name": "bronze-cool-then-archive", "type": "Lifecycle", "definition": { "filters": { "blobTypes": ["blockBlob"], "prefixMatch": ["bronze/"] }, "actions": { "baseBlob": { "tierToCool": { "daysAfterModificationGreaterThan": 30 }, "tierToArchive": { "daysAfterModificationGreaterThan": 90 } } } } } ]}Aplica:
az storage account management-policy create ` --account-name $ST ` --resource-group $RG ` --policy "@lifecycle.json"Valida:
az storage account management-policy show -g $RG --account-name $ST -o jsonCuidado em prod: Archive tem retrieval lento (horas) e custo de “rehydrate”. Só para dado realmente frio.
Parte 5 — ACLs (entender, não obrigatório executar)
Cenário típico: você quer que o time de Data Science leia silver/clientes_anonimizados/ mas não silver/clientes_raw/.
# Dar leitura (r-x) a um usuário específico numa pasta:az storage fs access set ` --account-name $ST ` --auth-mode login ` --file-system silver ` --path "domain=sales/customer" ` --acl "user:fulano@empresa.com:r-x"Recursivo (toda a árvore):
az storage fs access set-recursive ` --account-name $ST ` --auth-mode login ` --file-system silver ` --path "domain=sales/customer" ` --acl "user:fulano@empresa.com:r-x"Na trilha (uma pessoa, dev), não vamos mexer em ACL. Mas em entrevista cai. Decore:
r--= ler arquivos--x= atravessar pastar-x= ler arquivos + atravessar (mínimo pra “navegar e ler”)rwx= escrever também- ACLs default: aplicadas a arquivos/pastas novos criados ali.
Parte 6 — Networking (preview do M03)
Por padrão, seu storage aceita conexão de qualquer IP da internet (autenticado, claro). Em produção real:
- Private Endpoint + VNet: storage só acessível de dentro da rede privada.
- Firewall: liberar só IPs específicos (do seu workspace Databricks, do ADF).
Para a trilha (free tier, dev), deixamos público com autenticação. Em entrevista, esteja pronto pra falar de Private Endpoint — é diferencial.
Pegadinhas
- Subir via
az storage blob upload-batchdireto na raiz: cria arquivo na raiz do container, não dentro de pasta. Sempre coloque--name "<caminho>/<arquivo>". - Confundir
namecompath: no Gen2,nameé o caminho completo dentro do container. - Tentar
--auth-mode keysem ter exportado a chave: use--auth-mode login(recomendado) ou exporteAZURE_STORAGE_KEY. - Lifecycle não dispara imediato: a engine roda 1x/dia. Não espere migração instantânea.
- “Bronze é raw, então pode ser CSV mesmo” → certo. Mas Silver e Gold sempre Delta. Não economize formato aí.
Snippets de exploração
Listar tamanho total por container:
az storage blob list -c bronze --account-name $ST --auth-mode login ` --query "sum([].properties.contentLength)" -o tsvDeletar tudo de um container (cuidado):
# az storage blob delete-batch --source bronze --account-name $ST --auth-mode loginBaixar um arquivo do Bronze:
az storage blob download ` --account-name $ST --auth-mode login ` --container-name bronze ` --name "source=nyctaxi/dataset=yellow/year=2024/month=01/yellow_tripdata_2024-01.parquet" ` --file ".\copia.parquet"Checklist de saída
- 3 containers existem:
bronze,silver,gold. - Subiu pelo menos 1 parquet no Bronze, dentro de uma estrutura de pastas com
=(Hive-style). - Consegue navegar no portal e ver as pastas reais (não só prefixos).
- Sabe explicar HNS, container, ACL vs RBAC em uma frase cada.
- Lifecycle policy aplicada (opcional, mas recomendado).