Arquitetura No-Ops para Ingestão e Processamento no Lakehouse usando Terraform + Databricks (AWS)

Thiago Heron
Warren Tech
Published in
11 min readNov 21, 2022

Artigo escrito por Thiago Heron em conjunto com o Marcos Junior.

Atualmente, com o crescimento da área de dados, as empresas necessitam de uma maior ingestão e processamento de dados, com uma arquitetura que permita ser escalável, além de suportar toda a gestão e governança da mesma.

Porém, a alta complexidade das ferramentas demanda muito tempo de estudo e dedicação dos times e, por muitas vezes termos que lidar com os diferentes perfis de engenharia de dados (DataOps, Analytics Engineering, etc), a escassez dessa mão de obra qualificada no mercado resulta na sobrecarga dos profissionais nos times. Dado esse contexto, decidimos usar ferramentas e arquiteturas menos complexas, porém, mantendo a alta eficiência e desempenho do time.

Considerando que os times de engenharia são compostos geralmente por pessoas com background de desenvolvimento, torna-se muito mais tangível aprender a usar ferramentas de IaC (Infrastructure as Code) do que todas as camadas de complexidade de gestão de Clusters Kubernetes (EKS), Clusters de Map Reduce (EMR) e ainda manter a alta performance e um custo balanceado.

Pensando nos problemas citados acima — e também porque queremos uma stack de dados moderna — decidimos optar por uma arquitetura mais No-Ops e uma Plataforma de Dados do mercado já consolidada. Testamos diversas ferramentas, como: BigQuery, Snowflake e Databricks, e optamos pela última.

Agora, vamos ver as diferenças entre nossa antiga arquitetura em comparação com a nova.

Antiga Arquitetura de Dados da Warren em 2021

  • Airflow (MWAA)
  • Kubernetes (EKS)
  • EMR Clusters / EMR Serverless
  • Elastic Container Service (ECS)
  • Elastic Container Registry (ECR)
Arquitetura de Dados Warren 2021 [EKS, EMR Cluster / EMR Serverless, AIrflow (MWAA), ECR] — Link aqui.

Nova Arquitetura de Dados da Warren em 2022

  • Terraform (Infrastructure as a Code)
  • Databricks + Databricks Workflows

Databricks Workflows é um serviço de orquestrador de tasks lançado recentemente, concorrendo com Airflow, Dagster, etc. Além disso, utiliza toda a gestão de Clusters Databricks para processamento das tasks. Apesar disso, existem algumas limitações que traremos a seguir.

Arquitetura de Dados Warren 2022 [Terraform, Databricks] — Link aqui.

Prós e Contras da Plataforma

Prós:

  • Gestão de Infraestrutura de Clusters, como AutoScaling, entre outros, é feita pela Databricks;
  • Eliminação de gestão de ferramentas complexas como EKS + EMR, Airflow (MWAA ou Self-managed dentro do EKS);
  • Custos menores para manter a nova arquitetura com Terraform + Workflows Databricks, em comparação com antiga arquitetura de EKS / EMR Cluster / EMR Serverless / Airflow (MWAA);
  • Databricks atende 80% da nossa carga de processamento, sem a necessidade de nenhum tipo de tuning, pois os Clusters da Databricks já vem com seu Spark otimizado;
  • Formato Delta como padrão pela Databricks que, além de diminuir o tempo de processamento dos nossos pipelines, ainda facilita a ingestão incremental (CDC) do Lakehouse;
  • Baixa exigência na adaptação de códigos vindos da antiga arquitetura para Databricks (basicamente, tivemos que mudar a forma de passar os parâmetros);
  • Gerenciamento de usuários facilitada para cada Workflow, permitindo diferentes níveis de acesso, como: apenas visualização, edit, trigger, etc;
  • Aumento da velocidade do tempo de desenvolvimento, pois não temos mais a complexidade tuning de Spark e build de imagens Dockers, que eram necessários na antiga arquitetura;
  • Databricks é uma empresa com suporte da comunidade muito grande e, também, a empresa em si tem uma frente grande de apoio aos seus clientes no Brasil;
  • Seu dado fica armazenado no seu Storage (S3) e o formato Delta é Open Source, o que facilita caso a empresa queira sair da Databricks;
  • Permite multi-cloud com a Databricks (AWS, GCP, Azure).

Contras:

  • Apesar do Databricks Workflows possuírem mecanismo de orquestração, o Airflow possui features mais avançadas, como o reprocessamento de um período histórico e execução de tasks isoladas em uma DAG, enquanto no Workflow é necessário fazer isso através de code, ou executar apenas um dia de cada vez do seu histórico;
  • Airflow possui bastante operators prontos que permitem uma ingestão de dados mais rápido, enquanto no Databricks será necessário criar através de códigos;
  • Devido a essa falta de operators, é necessário usar uma ferramenta de ingestão aliada ao Databricks. No nosso caso, optamos pelo Airbyte;
  • Apesar de muito completa a documentação, ela é longa, e a plataforma requer algumas horas de estudos, principalmente na configuração inicial. A curva de aprendizado depende do perfil de cada profissional, mas, no geral, é mais fácil aprender Databricks do que outras três ferramentas para atender as mesmas funcionalidades;
  • Inicialização de clusters demoram alguns minutos.

Implementação da Arquitetura No-Ops

A partir de agora, vamos demonstrar como implementar um pipeline de dados e a nossa Arquitetura No-Ops com Terraform + Databricks. Antes de iniciarmos, alguns pré-requisitos:

  • Conhecimento básico em Terraform.
  • Possuir um Workspace criado no Databricks.
  • Possuir uma conta na AWS.

Para o desenvolvimento dessa arquitetura, vamos passar por algumas etapas:

  1. Como configurar repositórios do GitHub no Databricks.
  2. Identificar informações de seu Workspace Databricks para a criação de recursos.
  3. Criar passo a passo o código Terraform, desde a estrutura de projeto, criação de Workflow, Clusters, Tasks, e Orquestração do Pipeline, Invocação de Código do Pipeline em um Repositório Remoto do GitHub.
  4. Por fim, a visualização do pipeline implementado no Workflows Databricks.

Configuração do GitHub no Databricks

Vamos iniciar pela configuração no GitHub no Databricks para que o Databricks Workflow consiga enxergar o repositório e executar os códigos com você nele.

Primeiro, entre em sua conta no Databricks, clique em Settings -> User Settings -> Git Integration tab -> Selecione o Git Provider: ‘GitHub’ -> Adicione o Personal Access Token (PAT) da sua Conta GitHub.

  • Para criar um Personal Access Token (PAT) no GitHub, siga a seguinte documentação.
  • Caso tenha alguma dificuldade na configuração do GitHub no Databricks, siga a seguinte documentação.

Após isso, sua conta Databricks terá acesso aos códigos de sua conta do GitHub.

Observação: O ideal é que você use uma Service Account ao invés da sua conta pessoal, e utilize ela para configurar o GitHub, PAT e Databricks.

Informações do Workspace Databricks

Após a configuração do GitHub, será necessária algumas informações de seu ambiente Databricks, que são:

  • DATABRICKS_HOST
  • DATABRICKS_ACCOUNT_ID
  • DATABRICKS_TOKEN

Essas informações podem ser obtidas seguindo a seguinte documentação!

Essas informações serão necessárias para criarmos os recursos no Databricks e permissões AWS através do Terraform.

Desenvolvimento com Terraform

Nosso objetivo aqui é demonstrar como implementar pipelines no Workflows Databricks utilizando Terraform. Não vamos entrar em detalhes sobre controle de ambientes (produção, homologação e desenvolvimento), remotes states, state locks, etc, mas podemos no futuro escrever um novo artigo trazendo esses pontos.

Estrutura do Repositório

Os códigos do repositório estarão disponíveis no GitHub.

Estrutura do Repositório “medium_warren_noops_terraform”.
  • main.tf: Configurações de Providers AWS e Databricks.
  • workflow.tf: Databricks Workflow do Pipeline (Orquestração, Gestão de Cluster + Invocação de Códigos)
  • permissions.tf: Permissões da AWS e Databricks (Roles, Policies, Instances Profiles, etc…)
  • jsons/: Diretório de JSONs com Roles e Policies necessárias.

Vamos detalhar logo abaixo, para que serve e o que contém nesses arquivos.

Terraform: “main.tf”

Arquivo “main.tf”, que são as configurações de providers da Databricks e AWS e suas respectivas versões.

Terraform: ‘main.tf’ — Arquivo de Configurações de Providers e Versões.

Terraform: “permissions.tf” — Configuração de Roles e Instance Profiles

Para que o Workflow Databricks consiga se comunicar com a AWS, é necessário a criação de uma Role na AWS, um Instance Profile (AWS) e um Instance Profile (Databricks). Para isso, vamos utilizar os seguintes recursos do Terraform:

Terraform: “permissions.tf” — Parte I — Criação de Roles, Instance Profiles da AWS e Databricks.

Terraform: “permissions.tf” — Configuração de Policies para Accesos aos Serviços da AWS

Após a configuração de Roles e Instance Profiles, o nosso Workflow já consegue se comunicar com a AWS. Agora, precisamos passar quais serviços que o Workflow terá acesso. Como exemplo, vamos criar uma Policy com permissões para que o Workflow consiga manipular objetos em um Bucket do S3. Para isso, vamos utilizar os seguintes recursos do Terraform:

Terraform: “permissions.tf” — Parte II — Criação de Policy com acesso ao serviço do S3.

Observação: A Policy abaixo foi criada com Full Access ao Bucket do S3 apenas para fins de demonstração. Limite os seus acessos seguindo o conceito de Least Privilege Principle das Best Practices da AWS.

JSON — Exemplo de Policy de Full Access ao S3.

Pronto! Acabamos de configurar a comunicação do Databricks com a AWS, e também demonstramos como permitir os acessos aos serviços específicos da AWS, no caso, o S3.

Terraform: “workflows.tf”

Com todas as permissões devidamente configuradas, vamos iniciar a implementação de orquestração de pipelines e criação de cluster através do Databricks Workflows.

Configurações Gerais do Workflow

  • Primeiro, vamos criar um locals centralizando as configurações gerais do Workflow, como nome de pipelines, versão de spark, etc.
  • Os parâmetros são autoexplicativos.
Terraform: “workflow.tf” — Configurações no Locals.

Criando o Databricks Workflow

Vamos criar um Workflow utilizando recurso databricks_job do Terraform.

Vamos adicionar o recurso databricks_job no código e atribuir os valores definidos no locals (código acima) para criar nosso Workflow Databricks Pipeline, denominado “Warren-Pipeline-Example”

Terraform: “workflow.tf” — Parte I — Configurações Gerais do Workflow.

Criação de Cluster no Workflow

Após a criação do Workflow, vamos criar um Cluster para o Workflow, onde as tasks serão executadas. Para isso vamos utilizar a key job_cluster do recurso databricks_job:

  • Observe que, dentro de aws_attributes estamos atribuindo o Instance Profile criado arquivo permissions.tf . Dessa forma, estamos permitindo que o Cluster se comunique com a AWS e tenha os acessos aos recursos, por exemplo: manipulação de objetos no Bucket do S3, ou algum outro serviço específico, etc.
Terraform: “workflow.tf” — Configuração de Cluster.

Existem duas formas de criarmos um Cluster no Workflow:

  1. Workflow com Single Cluster
  2. Workflow com Cluster por Task

Vamos dar uma olhadinha nas duas:

Workflow com Single Cluster

  • Para criar o Workflow com Single Cluster, no momento da criação, é necessário passar uma configuração de spark_config.
  • Essa configuração define que só terá um Single Node, ou seja, todas as tasks serão executadas em um único node.
Terraform: “workflow.tf” — Configuração de Single Cluster.

Workflow com Cluster por Task

Para criar o Workflow por Task, é necessário criar um cluster para através do new_cluster{…} dentro cada task{…}. Além disso, você pode configurar um mínimo e máximo de workers por cluster por task.

  • autoscale -> min_workers: Mínimo de workers do cluster para aquela task.
  • autoscale -> max_workers: Máximo de workers do cluster para aquela task.
Exemplo de Configuração de Cluster por Task/Job

Criando Tasks e Orquestração no Databricks Workflow

Pronto, agora que sabemos como criar um Workflow, e como configurar Single Cluster / Cluster Por Task, vamos então criar nossas tasks que executarão o código do GitHub, e sua orquestração.

Para isso, vamos utilizar a key task{}. Dentro de task, é possível realizar diversas configurações como:

  • Instalação de Libraries do PyPi, Jar, Egg, Whl, entre outros.
  • Dependência entre Tasks/Jobs.
  • Passagem de parâmetros para cada task/jobs (Inclusive horário de execução, etc).
  • Controle de retries, delay entre cada tentativa.
  • No campo notebook_task, você deve passar o caminho do código do seu repositório que deseja executar (não coloque o .py). Além, a primeira linha desse arquivo deve conter o seguinte código: “# Databricks notebook source”. Para mais informações, consulte a documentação.
Terraform: “workflows.tf” — Exemplo de Criação da Task-1

Nessa segunda imagem, estamos demonstrando a criação de uma nova task, denominada “Task-2”, que tem uma dependência da Task-1. Dessa forma, é possível criar as dependências entre tasks.

Terraform: “workflows.tf” — Exemplo de Criação da Task-2 que depende da Task-1

Terraform Plan / Apply

Após toda a infraestrutura implementada, precisamos dar um apply no Terraform para criar os recursos na AWS e Databricks.

  1. Exporte as seguintes variávies de ambiente:
  • DATABRICKS_HOST
  • DATABRICKS_ACCOUNT_ID
  • DATABRICKS_TOKEN
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_SESSION_TOKEN (Opcional)

2. Crie um plano de execução do Terraform, e aplique a implementação:

  • Step Plan:
  • Step Apply:

Pronto! Após isso, os recursos já devem estar disponíveis na AWS e no Databricks.

Demonstração do Workflow no Databricks

Entre na sua conta Databricks, clique na aba lateral esquerda “Workflows”, no campo de busca, digite “Warren-Pipeline-Example”, e clique para abrir.

O resultado da seguinte infraestrutura será apresentado logo abaixo:

  • Visão de Histórico de Execuções
  • Visão do Plano de Execução
  • Visão de Tempo de Execuções
  • Visão do Configurações e Informações do Cluster.

Visão de Histórico de Execuções

  • Possibilita a visualização de todas as execuções, com seu tempo e status de execução. (Succeeded, Failed, Retry, Skipped, etc).
  • Permite iniciar uma execução manualmente clicando em Run now ou Run now with different parameters (permitindo passar novos valores para os parâmetros das task, como, por exemplo, um start_date diferente).

Visão do Plano de Execução

  • Na parte superior, clique na aba Tasks para visualizar o Plano de Execução e a dependências entre tasks.
  • É possível visualizar cada uma das suas tasks, dependência entre elas, quais clusters elas serão executadas, configurações de parâmetros, etc.

Após a execução com sucesso de um Workflow, os status das tasks serão demonstrados dessa forma:

Os exemplos de logs/outputs de uma execução:

Visão de Tempo de Execuções

  • Na parte superior, clique no botão “Matrix”.
  • Permite comparar os tempos de execução de cada tasks ao longo do tempo, além de seus status finais.

Visão do Configurações e Informações do Cluster.

  • Na aba lateral direita, encontre o campo Compute, e depois clique em Configure.
  • Possui as informações necessárias sobre seu Cluster.

Conclusões

Ainda que tenha desafios de aprendizado e a necessidade de algumas features que tínhamos na arquitetura antiga, o ganho de gestão, tempo de desenvolvimento, processamento, qualidade de entrega e custos nos fez concluir que tomamos a decisão certa ao adotar essa arquitetura, baseado no nosso contexto.

Gostaria mencionar e agradecer a Karinne Cristina, Marcos Junior e Leonardo Vinícius que participaram da construção e implementação dessa arquitetura.

--

--

Thiago Heron
Warren Tech

Engenheiro de Dados na Warren Brasil | AWS Certified | Databricks 3x Certified | Airflow Certified | LinkedIn: in/thiagoheron