Partilhar via


Provedor de recursos Pulumi Databricks

Nota

Este artigo abrange o Pulumi, que não é fornecido nem suportado pelo Databricks. Para entrar em contato com o provedor, consulte Suporte Pulumi.

Este artigo mostra como usar Python e Pulumi, uma plataforma de infraestrutura como código (IaC) de terceiros que permite criar, implantar e gerenciar recursos do Azure Databricks usando linguagens de programação, ferramentas e práticas de engenharia familiares. Embora este artigo mostre como usar Python e o provedor de recursos Pulumi Databricks, o Pulumi oferece suporte a outras linguagens além do Python para Azure Databricks, incluindo TypeScript, JavaScript, Go e C#.

O provedor de recursos Pulumi Databricks é baseado no provedor Databricks Terraform. Para obter mais informações, consulte Terraform Cloud.

Requisitos

  • Uma conta Pulumi. Inscreva-se no Pulumi, se você ainda não tem uma conta Pulumi. O Pulumi é gratuito para indivíduos e oferece um nível gratuito para equipes.

  • Python 3.6 ou superior. Para verificar se você tem o Python instalado, execute o comando python --version a partir do seu terminal ou com o PowerShell. Instale o Python, se ainda não o tiver instalado.

    Nota

    Algumas instalações do Python podem exigir que você use python3 em vez de python. Em caso afirmativo, substitua python ao python3 longo deste artigo.

  • Sua URL do Azure Databricks por espaço de trabalho, por exemplohttps://adb-1234567890123456.7.azuredatabricks.net.

  • Credenciais de acesso do Azure Databricks. Os projetos Pulumi Databricks suportam os seguintes tipos de autenticação do Azure Databricks:

    • Autenticação de token de acesso pessoal do Azure Databricks (databricks:authType pat)
    • Autenticação de identidades gerenciadas do Azure (databricks:authType azure-msi)
    • Autenticação da entidade de serviço do MS Entra (databricks:authType azure-client-secret)
    • Autenticação da CLI do Azure (databricks:authType azure-cli)

As etapas a seguir mostram como criar um projeto Pulumi Databricks com Python. Para obter um tutorial de uma perspetiva puramente baseada no provedor de nuvem, consulte Introdução ao Azure na documentação do Pulumi. Para obter um tutorial de uma perspetiva de linguagem de programação em primeiro lugar, consulte Python, Node.js (JavaScript, TypeScript), Go e .NET (C#, VB, F#) na documentação do Pulumi.

Etapa 1: Criar um projeto Pulumi

Nesta etapa, em sua máquina de desenvolvimento local, você configura a estrutura de diretórios necessária para um projeto Pulumi. Em seguida, você cria seu projeto Pulumi dentro dessa estrutura de diretórios.

  1. No seu terminal ou com o PowerShell, crie um diretório vazio e alterne para ele, por exemplo:

    Unix, Linux e macOS

    mkdir pulumi-demo
    cd pulumi-demo
    

    Windows

    md pulumi-demo
    cd pulumi-demo
    
  2. Instale o Pulumi executando o seguinte comando, dependendo do seu sistema operacional:

    Unix, Linux

    Instale o Pulumi no Unix ou Linux usando curl:

    curl -fsSL https://get.pulumi.com | sh
    

    MacOS

    Instale o Pulumi no macOS usando o Homebrew:

    brew install pulumi/tap/pulumi
    

    Windows

    Instale o Pulumi no Windows usando o PowerShell com permissões elevadas por meio do gerenciador de pacotes Chocolatey:

    choco install pulumi
    

    Para opções alternativas de instalação do Pulumi, consulte Download e Instalação na documentação do Pulumi.

  3. Crie um projeto Python Pulumi básico executando o seguinte comando:

    pulumi new python
    

    Gorjeta

    Você também pode criar um projeto Pulumi a partir de sua conta Pulumi on-line (Projetos > Criar projeto). No entanto, não há nenhum modelo de projeto para o Azure Databricks.

  4. Se solicitado, pressione a tecla Enter e, em seguida, use seu navegador da Web para entrar em sua conta Pulumi on-line, se você ainda não estiver conectado. Depois de entrar, retorne ao seu terminal ou PowerShell.

  5. Quando for solicitado um nome de projeto, aceite o nome padrão do projeto pressionando pulumi-demo Enter.

  6. Quando for solicitada uma descrição do projeto, digite A demo Python Pulumi Databricks project e pressione Enter.

  7. quando for solicitado um nome de pilha, aceite o nome da pilha padrão pressionando dev Enter. Pulumi cria os seguintes arquivos e subdiretório em seu pulumi-demo diretório:

    • Pulumi.yaml, que é uma lista de configurações para o seu projeto Pulumi.
    • __main__.py, que contém o código Python que você escreve para seu projeto Pulumi.
    • requirements.txt, que é uma lista de pacotes de código Python de suporte que o Pulumi instala para o seu projeto.
    • .gitignore, que é uma lista de arquivos e diretórios que o Git ignora se você quiser enviar este projeto para um repositório Git remoto.
    • O venv subdiretório contém o código de ambiente virtual Python de suporte que o Pulumi usa para seu projeto.
  8. Execute uma implantação inicial da dev pilha do seu projeto executando o seguinte comando:

    pulumi up
    
  9. Quando solicitado a executar essa atualização, pressione a tecla de seta para cima para navegar até sim e, em seguida, pressione Enter.

  10. Copie o link View Live que aparece e cole-o na barra de endereço do seu navegador da web, que o leva à sua conta Pulumi online. Os dev detalhes da atividade da pilha para seu pulumi-demo projeto são exibidos. Não há muito para ver agora, porque não há recursos em sua pilha ainda. Você cria esses recursos na próxima etapa.

Etapa 2: Criar recursos do Databricks

Nesta etapa, você usa o provedor de recursos Pulumi Databricks para criar, em seu espaço de trabalho existente do Azure Databricks, um bloco de anotações e um trabalho para executar esse bloco de anotações.

  1. No arquivo que o __main.py__ Pulumi gerou, use seu editor de texto preferido ou ambiente de desenvolvimento integrado (IDE) para inserir o código a seguir. Este código declara os recursos Pulumi Databricks Notebook e Job e suas configurações:

    """A Python Pulumi program"""
    
    import pulumi
    from pulumi_databricks import *
    from base64 import b64encode
    
    # Get the authenticated user's workspace home directory path and email address.
    # See https://www.pulumi.com/registry/packages/databricks/api-docs/getcurrentuser
    user_home_path     = get_current_user().home
    user_email_address = get_current_user().user_name
    
    # Define the name prefix to prepend to the resource names that are created
    # for the Notebook and Job resources. To do this, you can use a Pulumi
    # configuration value instead of hard-coding the name prefix in this file.
    #
    # To set a Pulumi configuration value, run the following command, which sets
    # a "resource-prefix" configuration value to "pulumi-demo" in the
    # associated "Pulumi.<stack-name>.yaml" configuration file:
    #
    # pulumi config set resource-prefix "pulumi-demo"
    #
    # For more information about defining and retrieving hard-coded values, see
    # https://www.pulumi.com/docs/intro/concepts/config
    config = pulumi.config.Config()
    resource_prefix = config.require('resource-prefix')
    
    # Define cluster resource settings.
    node_type = config.require('node-type')
    
    # Create a Notebook resource.
    # See https://www.pulumi.com/registry/packages/databricks/api-docs/notebook
    # This example adds a single cell to the notebook, which is constructed from
    # a single base64-encoded string. In practice, you would replace this:
    #
    # language       = "PYTHON",
    # content_base64 = b64encode(b"display(spark.range(10))").decode("UTF-8")
    #
    # With this:
    #
    # source         = "path/to/local/my-notebook.py"
    #
    # To provide more notebook content easier and faster. Also, the notebook's language
    # is automatically detected. If you specify a notebook path, be sure that it does
    # not end in .ipynb, as Pulumi relies on the workspace import API, which doesn't
    # rely on any specific extensions such as .ipynb in the notebook path.
    notebook = Notebook(
      resource_name  = f"{resource_prefix}-notebook",
      path           = f"{user_home_path}/Pulumi/{resource_prefix}-notebook.py",
      language       = 'PYTHON',
      content_base64 = b64encode(b"display(spark.range(10))").decode("UTF-8")
    )
    
    # Export the URL of the Notebook, so that you can easily browse to it later.
    # See https://www.pulumi.com/docs/intro/concepts/stack/#outputs
    pulumi.export('Notebook URL', notebook.url)
    
    # Create a Job resource.
    # See https://www.pulumi.com/registry/packages/databricks/api-docs/job
    # This job uses the most recent Databricks Runtime long-term support (LTS)
    # runtime programmatic version ID at the time this article was first published,
    # which is 14.3.x-scala2.12. You can replace this with a later version.
    job = Job(
      resource_name = f"{resource_prefix}-job",
      name = f"{resource_prefix}-job",
      tasks = [
        JobTaskArgs(
          task_key = f"{resource_prefix}-task",
          new_cluster   = JobNewClusterArgs(
            num_workers   = 1,
            spark_version = "14.3.x-scala2.12",
            node_type_id  = node_type
          ),
          notebook_task = JobNotebookTaskArgs(
            notebook_path = f"{user_home_path}/Pulumi/{resource_prefix}-notebook.py"
          )
        )
      ],
      email_notifications = JobEmailNotificationsArgs(
        on_successes = [ user_email_address ],
        on_failures  = [ user_email_address ]
      )
    )
    
    # Export the URL of the Job, so that you can easily browse to it later.
    # See https://www.pulumi.com/docs/intro/concepts/stack/#outputs
    pulumi.export('Job URL', job.url)
    
  2. Defina um valor de configuração chamado resource-prefix, e defina-o com o valor codificado de pulumi-demo, executando o seguinte comando. O Pulumi usa esse valor de configuração para nomear o bloco de anotações e o trabalho:

    pulumi config set resource-prefix "pulumi-demo"
    

    Pulumi cria um arquivo nomeado Pulumi.dev.yaml no mesmo diretório que o __main__.py arquivo e adiciona o seguinte código a este arquivo YAML:

    config:
      pulumi-demo:resource_prefix: pulumi-demo
    

    O uso de valores de configuração permite que seu código seja mais modular e reutilizável. Agora outra pessoa pode reutilizar seu __main__.py arquivo e definir um valor diferente para a resource_prefix variável sem alterar o conteúdo do __main__.py arquivo.

  3. Defina um valor de configuração chamado node-type, e defina-o com o seguinte valor codificado, executando o seguinte comando. O Pulumi usa esse valor de configuração para determinar o tipo de cluster no qual o trabalho é executado.

    pulumi config set node-type "Standard_D3_v2"
    

    O conteúdo do Pulumi.dev.yaml arquivo agora tem esta aparência:

    config:
      pulumi-demo:node-type: Standard_D3_v2
      pulumi-demo:resource-prefix: pulumi-demo
    
  4. Para permitir que o Pulumi se autentique com seu espaço de trabalho do Azure Databricks, defina valores de configuração específicos do Azure Databricks executando os comandos relacionados. Por exemplo, para autenticação de token de acesso pessoal do Azure Databricks, execute os seguintes comandos. Nestes comandos:

    • Substitua <workspace-instance-url> pelo URL por espaço de trabalho, por exemplo https://adb-1234567890123456.7.azuredatabricks.net.

    • Substitua <access-token> pelo valor do seu token de acesso. Certifique-se de especificar a --secret opção. Isso instrui o Pulumi a criptografar seu token de acesso como uma prática recomendada de segurança.

      Nota

      Por padrão, o Pulumi usa uma chave de criptografia por pilha gerenciada pelo Serviço Pulumi e um sal por valor para criptografar valores. Para usar um provedor de criptografia alternativo, consulte Configurando a criptografia de segredos na documentação do Pulumi.

    pulumi config set databricks:host "<workspace-instance-url>"
    pulumi config set databricks:token "<access-token>" --secret
    

    O conteúdo do Pulumi.dev.yaml arquivo agora tem esta aparência:

    config:
      databricks:host: <your-workspace-instance-url>
      databricks:token:
        secure: <an-encrypted-version-of-your-access-token>
      pulumi-demo:node-type: Standard_D3_v2
      pulumi-demo:resource_prefix: pulumi-demo
    

    Para usar um tipo de autenticação diferente do Azure Databricks, consulte os Requisitos. Consulte também Configuração no repositório Pulumi Databricks no GitHub.

Etapa 3: Implantar os recursos

Nesta etapa, você ativa um ambiente virtual Python que o Pulumi fornece para seu projeto como parte da execução do modelo de projeto Python Pulumi. Esse ambiente virtual ajuda a garantir que você esteja usando a versão correta do Python, Pulumi e o provedor de recursos Pulumi Databricks juntos. Existem várias estruturas de ambiente virtual Python disponíveis, como venv, virtualenv e pipenv. Este artigo e o modelo de projeto Pulumi Python usam venv. venv já está incluído no Python. Para obter mais informações, consulte Criando ambientes virtuais.

  1. Ative o ambiente virtual Python executando o seguinte comando a partir do seu pulumi-demo diretório, dependendo do seu sistema operacional e tipo de shell:

    Plataforma Shell Comando para ativar o ambiente virtual
    Unix, Linux, macOS bash/zsh source venv/bin/activate
    peixes source venv/bin/activate.fish
    CSH/TCSH source venv/bin/activate.csh
    PowerShell Core venv/bin/Activate.ps1
    Windows cmd.exe venv\Scripts\activate.bat
    PowerShell venv\Scripts\Activate.ps1
  2. Instale o provedor de recursos Pulumi Databricks do Python Package Index (PyPI) em seu ambiente virtual executando o seguinte comando:

    pip install pulumi-databricks
    

    Nota

    Algumas instalações do pip podem exigir que você use pip3 em vez de pip. Em caso afirmativo, substitua pip ao pip3 longo deste artigo.

  3. Visualize os recursos que o Pulumi criará executando o seguinte comando:

    pulumi preview
    

    Se houver algum erro relatado, corrija-o e execute o comando novamente.

    Para ver um relatório detalhado em sua conta Pulumi on-line do que o Pulumi fará, copie o link View Live que aparece e cole-o na barra de endereço do seu navegador da web.

  4. Crie e implante os recursos em seu espaço de trabalho do Azure Databricks executando o seguinte comando:

    pulumi up
    
  5. Quando solicitado a executar essa atualização, pressione a tecla de seta para cima para navegar até sim e, em seguida, pressione Enter. Se houver algum erro relatado, corrija-o e execute o comando novamente.

  6. Para ver um relatório detalhado em sua conta Pulumi on-line do que Pulumi fez, copie o link View Live que aparece e cole-o na barra de endereço do seu navegador da web.

Passo 4: Interaja com os recursos

Nesta etapa, você executa o trabalho em seu espaço de trabalho do Azure Databricks, que executa o bloco de anotações especificado.

  1. Para exibir o bloco de anotações que o trabalho executará em seu espaço de trabalho, copie o link URL do Bloco de Anotações exibido e cole-o na barra de endereço do navegador da Web.
  2. Para exibir o trabalho que executa o bloco de anotações em seu espaço de trabalho, copie o link URL do trabalho exibido e cole-o na barra de endereço do navegador da Web.
  3. Para executar o trabalho, clique no botão Executar agora na página do trabalho.
  4. Após a conclusão da execução do trabalho, para exibir os resultados da execução do trabalho, na lista Execuções concluídas (últimos 60 dias) na página do trabalho, clique na entrada de hora mais recente na coluna Hora de início. O painel Saída mostra o resultado da execução do código do bloco de anotações, que imprime os números de 1 a 10.

(Opcional) Etapa 5: Fazer alterações em um recurso

Nesta etapa opcional, você altera o código do bloco de anotações, reimplanta o bloco de anotações alterado e usa o trabalho para executar novamente o bloco de anotações alterado.

Se não quiser fazer alterações no bloco de notas, avance para o Passo 6: Limpar.

  1. De volta ao __main.py__ arquivo, altere esta linha de código:

    content_base64 = b64encode(b"display(spark.range(10))").decode("UTF-8")
    

    Para isso e, em seguida, salve o arquivo:

      content_base64 = b64encode(b'''
    data = [
             { "Category": 'A', "ID": 1, "Value": 121.44 },
             { "Category": 'B', "ID": 2, "Value": 300.01 },
             { "Category": 'C', "ID": 3, "Value": 10.99 },
             { "Category": 'E', "ID": 4, "Value": 33.87}
           ]
    
    df = spark.createDataFrame(data)
    
    display(df)
    ''').decode("UTF-8")
    

    Essa alteração instrui o bloco de anotações a imprimir o conteúdo do DataFrame especificado em vez dos números de 1 a 10.

    Nota

    Certifique-se de que as linhas de código que começam com data e terminam com ''').decode("UTF-8") estão alinhadas com a borda do seu editor de código. Caso contrário, o Pulumi inserirá espaço em branco adicional no bloco de anotações que pode fazer com que o novo código Python não seja executado.

  2. Opcionalmente, visualize o recurso que o Pulumi irá alterar executando o seguinte comando:

    pulumi preview
    

    Se houver algum erro relatado, corrija-o e execute o comando novamente.

    Para ver um relatório detalhado em sua conta Pulumi on-line do que o Pulumi fará, copie o link View Live que aparece e cole-o na barra de endereço do seu navegador da web.

  3. Implante a alteração de recursos em seu espaço de trabalho do Azure Databricks executando o seguinte comando:

    pulumi up
    
  4. Quando solicitado a executar essa atualização, pressione a tecla de seta para cima para navegar até sim e, em seguida, pressione Enter. Se houver algum erro relatado, corrija-o e execute o comando novamente.

  5. Para ver um relatório detalhado em sua conta Pulumi on-line do que Pulumi fez, copie o link View Live que aparece e cole-o na barra de endereço do seu navegador da web.

  6. Para exibir o bloco de anotações alterado em seu espaço de trabalho, copie o link URL do Bloco de Anotações exibido e cole-o na barra de endereço do navegador da Web.

  7. Para executar novamente o trabalho com o bloco de anotações alterado, copie o link URL do trabalho exibido e cole-o na barra de endereço do navegador da Web. Em seguida, clique no botão Executar agora na página de trabalho.

  8. Após a conclusão da execução do trabalho, para exibir os resultados da execução do trabalho, na lista Execuções concluídas (últimos 60 dias) na página do trabalho, clique na entrada de hora mais recente na coluna Hora de início. O painel Saída mostra o resultado da execução do código do bloco de anotações, que imprime o conteúdo do DataFrame especificado.

Passo 6: Limpar

Nesta etapa, você instrui o Pulumi a remover o bloco de anotações e o trabalho do seu espaço de trabalho do Azure Databricks, bem como remover o pulumi-demo projeto e sua dev pilha da sua conta Pulumi online.

  1. Remova os recursos do seu espaço de trabalho do Azure Databricks executando o seguinte comando:

    pulumi destroy
    
  2. Quando solicitado a executar essa remoção, pressione a tecla de seta para cima para navegar até sim e, em seguida, pressione Enter.

  3. Remova o projeto Pulumi pulumi-demo e sua dev pilha da sua conta Pulumi on-line executando o seguinte comando:

    pulumi stack rm dev
    
  4. Quando solicitado a executar essa remoção, digite dev e pressione Enter.

  5. Para desativar o venv ambiente virtual Python, execute o seguinte comando:

    deactivate
    

Testar

Você pode testar seu projeto Pulumi antes de implantá-lo. Consulte Testando programas Pulumi na documentação do Pulumi.

Para testes de unidade de projetos Pulumi baseados em Python, você pode escrever e executar testes de unidade usando a estrutura de teste Python unittest junto com o namespace pulumi.runtime do pacote Pulumi. Para executar testes em recursos simulados, substitua chamadas para Pulumi (e para o Azure Databricks) por simulações. Consulte Testes unitários dos programas Pulumi na documentação do Pulumi.

O arquivo de exemplo a seguir denominado infra.py simula uma implementação do bloco de anotações e do trabalho declarado no arquivo deste main.py artigo. Os testes de unidade neste exemplo verificam se o conteúdo codificado em Base64 do bloco de anotações, o nome do trabalho e o destinatário do email para o trabalho bem-sucedido executam todos os valores esperados de retorno. Como tal, apenas as propriedades relacionadas são simuladas aqui com valores de exemplo. Além disso, os valores de propriedade de recurso necessários devem sempre ser fornecidos, mesmo que você não planeje usá-los em seus testes de unidade. Neste exemplo, esses valores necessários são definidos como valores aleatórios my-mock- e esses valores não são testados.

# infra.py

from pulumi_databricks import (
  Notebook,
  Job,
  JobEmailNotificationsArgs
)

notebook = Notebook(
  resource_name  = 'my-mock-notebook-resource-name',
  path           = 'my-mock-notebook-path',
  content_base64 = 'ZGlzcGxheShzcGFyay5yYW5nZSgxMCkp'
)

job = Job(
  resource_name = 'my-mock-job-resource-name',
  name          = 'pulumi-demo-job',
  email_notifications = JobEmailNotificationsArgs(
    on_successes = [ 'someone@example.com' ]
  )
)

O arquivo de test_main.py exemplo a seguir testa se as propriedades relacionadas retornam seus valores esperados.

# test_main.py

import pulumi
from pulumi_databricks import *
import unittest
import infra

# Set up mocking.
class MyMocks(pulumi.runtime.Mocks):
  def new_resource(self, type_, name, inputs, provider, id_):
    return [name + '_id', inputs]

  def call(self, token, args, provider):
    return {}

pulumi.runtime.set_mocks(MyMocks())

class TestNotebookAndJob(unittest.TestCase):
  @pulumi.runtime.test
  def test_notebook(self):
    def check_notebook_content_base64(args):
      content_base64 = args
      # Does the notebook's Base64-encoded content match the expected value?
      self.assertIn('ZGlzcGxheShzcGFyay5yYW5nZSgxMCkp', content_base64)

    # Pass the mocked notebook's content_base64 property value to the test.
    return pulumi.Output.all(infra.notebook.content_base64).apply(check_notebook_content_base64)

  @pulumi.runtime.test
  def test_job(self):
    def check_job_name_and_email_onsuccesses(args):
      name, email_notifications = args
      # Does the job's name match the expected value?
      self.assertIn('pulumi-demo-job', name)
      # Does the email address for successful job runs match the expected value?
      self.assertIn('someone@example.com', email_notifications['on_successes'])

    # Pass into the test the mocked job's property values for the job's name
    # and the job's email address for successful runs.
    return pulumi.Output.all(
      infra.job.name,
      infra.job.email_notifications
    ).apply(check_job_name_and_email_onsuccesses)

Para executar esses testes e exibir seus resultados de teste, execute o seguinte comando no diretório raiz do projeto Pulumi:

python -m unittest

Para obter informações sobre outros tipos de testes que você pode executar, consulte os seguintes artigos na documentação do Pulumi:

Mais recursos