DE Trilhas

M05 — Azure Data Factory (ADF): orquestração

Duração: 3h Pré-requisitos: M04 ok (notebook Bronze → Silver roda). Objetivo: criar o ADF, conectar a uma fonte (SQL Server público), trazer dados para o Bronze, e disparar o notebook do M04 a partir do ADF, com trigger por horário.

Por que ADF (e não Databricks Workflows)

CritérioADFDatabricks Workflows
Conectores nativos90+ (SAP, Oracle, Salesforce, SFTP, on-prem via Self-Hosted IR)~15 (foco em cloud-native)
Orquestração entre serviços externosMuito forte (Logic Apps, Functions, Synapse)Limitado
CustoPay por execução de pipeline + DIU/hora de copyDBU já é caro; workflow é barato
UI / aprendizadoVisual, baixo códigoMais “code-first”
Quando usarIngestão de fontes externas, on-prem, SaaSPipelines internos Databricks-only

Padrão real da indústria:

ADF orquestra a ingestão → grava Bronze
ADF chama notebook Databricks → transforma Bronze → Silver → Gold
ADF agenda + monitora

Parte 1 — Criar o Data Factory

Variáveis:

Terminal window
$PROJ = "de"; $INIC = "w"; $AMB = "dev"; $REGS = "brs"; $REG = "brazilsouth"
$RG = "rg-$PROJ-$AMB-$REGS"
$ADF = "adf-$PROJ-$AMB-$REGS"
$ST = "st$PROJ$INIC$AMB$REGS"
$KV = "kv-$PROJ-$INIC-$AMB"

Criar via CLI:

Terminal window
az datafactory create `
--name $ADF `
--resource-group $RG `
--location $REG `
--tags projeto=$PROJ ambiente=$AMB trilha=azure-e2e

Validar:

Terminal window
az datafactory show -n $ADF -g $RG --query "{name:name, state:provisioningState, identityType:identity.type}" -o table

Pega o principalId da Managed Identity do ADF (vai usar pra dar acesso ao Key Vault e Storage):

Terminal window
$ADFMI = az datafactory show -n $ADF -g $RG --query "identity.principalId" -o tsv
Write-Output "Managed Identity do ADF: $ADFMI"

Se vier vazio, habilita system-assigned:

Terminal window
az datafactory update -n $ADF -g $RG --identity-type SystemAssigned

Parte 2 — Dar permissões à Managed Identity do ADF

ADF vai precisar:

  • Ler/Escrever no Storage (Storage Blob Data Contributor).
  • Ler segredos do Key Vault (Key Vault Secrets User).
  • Disparar runs no Databricks (Contributor no workspace, e cluster permission dentro do Databricks).
Terminal window
$STID = az storage account show -n $ST -g $RG --query "id" -o tsv
$KVID = az keyvault show -n $KV -g $RG --query "id" -o tsv
$DBWID = az databricks workspace show -n "dbw-$PROJ-$AMB-$REGS" -g $RG --query "id" -o tsv
# Storage
az role assignment create --assignee $ADFMI --role "Storage Blob Data Contributor" --scope $STID
# Key Vault (RBAC mode)
az role assignment create --assignee $ADFMI --role "Key Vault Secrets User" --scope $KVID
# Databricks workspace
az role assignment create --assignee $ADFMI --role "Contributor" --scope $DBWID

Espere 1-2 min para propagação.

Parte 3 — Conhecer os elementos do ADF

┌────────────────────────────────────────────┐
│ AZURE DATA FACTORY │
├────────────────────────────────────────────┤
│ │
│ LINKED SERVICE = "conexão" │
│ ↓ aponta para... │
│ DATASET = "esquema/local da fonte"│
│ ↓ usado em... │
│ ACTIVITY = "1 passo do pipeline" │
│ ↓ compõe... │
│ PIPELINE = "fluxo completo" │
│ ↓ disparado por... │
│ TRIGGER = "quando rodar" │
│ │
│ INTEGRATION RUNTIME = "onde a copy roda" │
│ │
└────────────────────────────────────────────┘

Linked Services

“Strings de conexão”. Crie um para:

  1. Azure Key Vault (para ler segredos).
  2. Azure Data Lake Gen2 (seu storage).
  3. Azure Databricks (workspace).
  4. Azure SQL (fonte de exemplo — Parte 5).

Datasets

Apontam para uma tabela/arquivo específico dentro de um Linked Service. Ex.: “tabela Customer no SQL”, “pasta /bronze/sql/customer no ADLS”.

Activities

  • Copy (mais usada): copia de um dataset para outro.
  • Notebook: dispara notebook Databricks.
  • Lookup: lê e devolve para usar em variável.
  • ForEach, If, Switch, Until: controle de fluxo.
  • Web: HTTP call genérico.

Triggers

  • Schedule: hora fixa (ex.: diário 06h).
  • Tumbling Window: janelas de tempo sequenciais (bom para backfill).
  • Storage Event: dispara quando arquivo chega no ADLS.
  • Manual: você roda quando quer.

Parte 4 — Criar Linked Services (via UI, primeira vez)

ADF tem UI muito boa pro primeiro hands-on. Depois (M07) vamos versionar tudo em JSON.

  1. No portal, abra o ADF → Launch Studio → você vai pra adf.azure.com.
  2. Esquerda → ícone caixa de ferramentas (Manage) → Linked services+ New.

LS 1: Key Vault

  • Tipo: Azure Key Vault.
  • Nome: LS_KV.
  • Azure Subscription / Key vault name: selecione seu kv-de-w-dev.
  • Authentication: System Assigned Managed Identity.
  • Test connection → deve dar verde. Se falhar, o role Key Vault Secrets User não propagou ainda; espere 2 min.
  • Create.

LS 2: ADLS Gen2

  • Tipo: Azure Data Lake Storage Gen2.
  • Nome: LS_ADLS.
  • Authentication: System Assigned Managed Identity.
  • Storage account name: stdewdevbrs.
  • Test connection → verde.
  • Create.

LS 3: Azure Databricks

  • Tipo: Azure Databricks.
  • Nome: LS_DATABRICKS.
  • Azure subscription / workspace: selecione dbw-de-dev-brs.
  • Select cluster: Existing interactive cluster → escolha dev-single-node.
    • Em prod usa-se New job cluster, que cria/destrói cluster por execução. Mais barato e isolado.
  • Authentication: Managed service identity.
  • Test connection → verde.
  • Create.

LS 4: Fonte de dados (AdventureWorksLT no Azure SQL)

Para ter uma fonte SQL pública, vamos provisionar um Azure SQL Database serverless (essencialmente grátis em free tier para dataset de amostra).

CLI:

Terminal window
$SQL = "sql-$PROJ-$INIC-$AMB" # nome global
$SQLADMIN = "sqladmin"
$SQLPASS = "ChangeMe!" + (Get-Random)
Write-Output "Senha temporária: $SQLPASS (anote!)"
az sql server create `
--name $SQL --resource-group $RG --location $REG `
--admin-user $SQLADMIN --admin-password $SQLPASS
az sql server firewall-rule create `
--resource-group $RG --server $SQL `
--name AllowAzureServices --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
az sql db create `
--resource-group $RG --server $SQL `
--name AdventureWorksLT `
--sample-name AdventureWorksLT `
--edition GeneralPurpose --family Gen5 --capacity 2 `
--compute-model Serverless `
--auto-pause-delay 60

Guarde a senha no Key Vault:

Terminal window
az keyvault secret set --vault-name $KV --name "sql-admin-password" --value $SQLPASS
Remove-Variable SQLPASS

No ADF Studio:

  • + NewAzure SQL Database → nome LS_SQL_SOURCE.
  • Server: $SQL.database.windows.net.
  • Database: AdventureWorksLT.
  • Authentication: SQL authentication.
  • User name: sqladmin.
  • Password: Azure Key Vault → escolhe LS_KV e nome do segredo sql-admin-password.
  • Test connection → verde.

Parte 5 — Criar Pipeline: Copy SQL → Bronze + Run Notebook

Passo 5.1 — Pipeline novo

ADF Studio → Author (ícone lápis) → +Pipeline. Nome: pl_nyctaxi_diario_dev (ou pl_aw_customer_diario_dev se for usar AdventureWorks; ajustamos).

Passo 5.2 — Atividade 1: Copy SalesLT.Customer → Bronze

  1. Arraste Copy data para o canvas. Nome: copy_customer_to_bronze.
  2. Source:
    • Linked service: LS_SQL_SOURCE.
    • Use query: SELECT * FROM SalesLT.Customer.
  3. Sink:
    • + New datasetAzure Data Lake Storage Gen2Parquet.
    • Nome: ds_bronze_customer_parquet.
    • Linked service: LS_ADLS.
    • File path: bronze / source=adventureworks/schema=salesLT/table=customer/ingestion_date=@{formatDateTime(utcNow(),'yyyy-MM-dd')}/.
    • Confirme.
  4. Settings → Data integration units: Auto. Parallel copies: 4.

Passo 5.3 — Atividade 2: Notebook Databricks (depende de 1)

  1. Arraste Notebook para o canvas. Nome: transforma_customer_silver.
  2. Conecte a saída verde do Copy à entrada do Notebook (= dependência “on success”).
  3. Aba Azure Databricks → Linked service: LS_DATABRICKS.
  4. Aba Settings → Notebook path: /Users/SEU_EMAIL/02_bronze_to_silver (vamos parametrizar — veja Parte 6).

Passo 5.4 — Salvar e debugar

  • Clique em Validate (topo) → corrige erros eventuais.
  • Debug (não publica ainda): roda o pipeline 1x.
  • Acompanhe em Monitor (ícone de medidor) → veja sucesso/falha.

Se OK, Publish all (botão azul, topo).

Parte 6 — Parametrizar para reuso

Pipelines hardcoded não escalam. Vamos parametrizar.

No pipeline, criar parâmetros:

  • p_data_processamento (string, default = @formatDateTime(utcNow(),'yyyy-MM-dd')).
  • p_tabela_origem (string, default = SalesLT.Customer).

Source do Copy:

  • Query: @concat('SELECT * FROM ', pipeline().parameters.p_tabela_origem, ' WHERE ModifiedDate >= ''', pipeline().parameters.p_data_processamento, '''').

Sink path (no Dataset):

  • Parameterize o dataset (no Dataset → Parameters → adicione p_table, p_date).
  • File path: bronze / @concat('source=adventureworks/schema=salesLT/table=', dataset().p_table, '/ingestion_date=', dataset().p_date, '/').
  • No Copy → Sink → preencha esses parâmetros vindos do pipeline.

Base parameters do Notebook:

  • data_processamento = @pipeline().parameters.p_data_processamento.
  • tabela = @pipeline().parameters.p_tabela_origem.

No notebook (M04), receba com dbutils.widgets:

dbutils.widgets.text("data_processamento", "")
dbutils.widgets.text("tabela", "")
data_proc = dbutils.widgets.get("data_processamento")
tabela = dbutils.widgets.get("tabela")

Parte 7 — Trigger por horário

ADF Studio → Add trigger (topo) → New/Edit+ New:

  • Nome: tg_diario_06_brt.
  • Type: Schedule.
  • Start date: amanhã 06h.
  • Time zone: (UTC-03:00) Brasilia.
  • Recurrence: 1 Day.
  • OK → vincula ao pipeline → Publish.

Desligue o trigger após testar (ManageTriggers → para o trigger). Não esqueça! Cluster pode subir sozinho às 6h.

Parte 8 — Monitor + Alertas

Monitor

  • ADF Studio → MonitorPipeline runs → últimos 24h.
  • Clique em uma run para ver duração por atividade, payload e erro.

Alertas (em prod)

  • ADF → Alerts+ New alert rule → métrica PipelineFailedRuns > 0 nos últimos 5 min → Action Group: e-mail / Teams.

Pegadinhas

  1. “Forbidden” ao testar LS → role no Storage/KV não propagou. Esperar 2 min ou reverificar atribuição.
  2. Test connection LS Databricks falha → MI do ADF não tem Contributor no workspace. Também precisa do Cluster permission “Can attach to” dentro do Databricks (Workspace → Compute → cluster → Permissions).
  3. Notebook activity demora 5+ min só pra iniciar → cluster estava desligado. Em prod, use Job cluster novo por execução.
  4. Pipeline sumiu após Publish → você estava em uma branch Git (se configurou Git mode). Veja em main.
  5. Custo escondido: cada execução de pipeline cobra “Activity Run” (USD 0.001/run). Trivial. O caro são os DIUs do Copy (USD ~0.25/DIU/hora). Auto + paralelismo 4 = ok.

Linked Service em JSON (preview de M07)

Linked Services em JSON ficam assim — você vai versionar no Git:

{
"name": "LS_ADLS",
"properties": {
"type": "AzureBlobFS",
"typeProperties": {
"url": "https://stdewdevbrs.dfs.core.windows.net"
},
"annotations": [],
"description": "ADLS Gen2 (dev)"
}
}

E o pipeline (resumido):

{
"name": "pl_aw_customer_diario_dev",
"properties": {
"activities": [
{
"name": "copy_customer_to_bronze",
"type": "Copy",
"typeProperties": { "...": "..." }
},
{
"name": "transforma_customer_silver",
"type": "DatabricksNotebook",
"dependsOn": [{ "activity": "copy_customer_to_bronze", "dependencyConditions": ["Succeeded"] }],
"linkedServiceName": { "referenceName": "LS_DATABRICKS", "type": "LinkedServiceReference" },
"typeProperties": {
"notebookPath": "/Users/SEU_EMAIL/02_bronze_to_silver",
"baseParameters": {
"data_processamento": "@pipeline().parameters.p_data_processamento",
"tabela": "@pipeline().parameters.p_tabela_origem"
}
}
}
],
"parameters": {
"p_data_processamento": { "type": "string", "defaultValue": "@formatDateTime(utcNow(),'yyyy-MM-dd')" },
"p_tabela_origem": { "type": "string", "defaultValue": "SalesLT.Customer" }
}
}
}

No M07 versionamos esses JSONs.

Checklist de saída

  • ADF criado com Managed Identity habilitada.
  • 4 Linked Services criados e testados (KV, ADLS, Databricks, SQL).
  • Pipeline com Copy + Notebook, executado em Debug com sucesso.
  • Pipeline parametrizado (p_data_processamento, p_tabela_origem).
  • Notebook recebe widgets corretamente.
  • Trigger criado (mas desligado para não disparar sozinho).
  • Aprendeu a navegar em Monitor e diagnosticar uma run.

Próximo

M06 — Unity Catalog + Governança

← Anterior
M04 Spark Primeiro Notebook
Próximo →
M06 Unity Catalog Governanca