Usar uma entidade de serviço com o conector do Spark 3 no Azure Cosmos DB para NoSQL
Neste artigo, você aprenderá a criar um aplicativo do Microsoft Entra e uma entidade de serviço que podem ser usados com controle de acesso baseado em função. Em seguida, você pode usar essa entidade de serviço para se conectar a uma conta do Azure Cosmos DB para NoSQL do Spark 3.
Pré-requisitos
- Uma conta existente do Azure Cosmos DB for NoSQL.
- Se você tiver uma assinatura existente do Azure, crie uma nova conta.
- Nenhuma assinatura do Azure? Você pode experimentar o Azure Cosmos DB gratuitamente sem necessidade de cartão de crédito.
- Um workspace existente do Azure Databricks.
- Entidade de serviço e aplicativo do Microsoft Entra registrados.
- Se você não tiver uma entidade de serviço e um aplicativo, registre um aplicativo usando o portal do Azure.
Criar um segredo e registrar as credenciais
Nesta seção, crie um segredo do cliente e registre o valor para uso posterior.
Abra o Portal do Azure.
Acesse seu aplicativo existente do Microsoft Entra.
Acesse a página Certificados e segredos. Em seguida, crie um novo segredo. Salve o valor do Segredo do Cliente para ser usado posteriormente neste artigo.
Vá para a página Visão geral. Localize e registre os valores da ID do aplicativo (cliente), ID do Objetoe ID do Diretório (locatário). Você também usará esses valores mais adiante neste artigo.
Acesse sua conta existente do Azure Cosmos DB for NoSQL.
Registre o valor do URI na página Visão Geral. Registre também os valores da ID da Assinatura e Grupo de Recursos. Você usará esses valores mais adiante neste artigo.
Criar uma definição e uma atribuição
Nesta seção, você criará uma definição de função do Microsoft Entra ID. Em seguida, atribua a essa função permissões de leitura e gravação de itens nos contêineres.
Crie uma função usando o comando
az role definition create
. Passe o nome da conta e o grupo de recursos do Azure Cosmos DB para NoSQL, seguido de um corpo de JSON que define a função personalizada. A função também tem escopo no nível da conta usando/
. Certifique-se de fornecer um nome exclusivo para sua função usando a propriedadeRoleName
do corpo da solicitação.az cosmosdb sql role definition create \ --resource-group "<resource-group-name>" \ --account-name "<account-name>" \ --body '{ "RoleName": "<role-definition-name>", "Type": "CustomRole", "AssignableScopes": ["/"], "Permissions": [{ "DataActions": [ "Microsoft.DocumentDB/databaseAccounts/readMetadata", "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*", "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*" ] }] }'
Liste a definição de função que você criou para buscar seu identificador exclusivo na saída JSON. Registre o valor
id
da saída JSON.az cosmosdb sql role definition list \ --resource-group "<resource-group-name>" \ --account-name "<account-name>"
[ { ..., "id": "/subscriptions/<subscription-id>/resourceGroups/<resource-grou-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/sqlRoleDefinitions/<role-definition-id>", ... "permissions": [ { "dataActions": [ "Microsoft.DocumentDB/databaseAccounts/readMetadata", "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*", "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*" ], "notDataActions": [] } ], ... } ]
Use
az cosmosdb sql role assignment create
para criar uma atribuição de função. Substitua<aad-principal-id>
pela ID do objeto que você registrou anteriormente neste artigo. Além disso, substitua<role-definition-id>
pelo valorid
buscado da execução do comandoaz cosmosdb sql role definition list
em uma etapa anterior.az cosmosdb sql role assignment create \ --resource-group "<resource-group-name>" \ --account-name "<account-name>" \ --scope "/" \ --principal-id "<account-name>" \ --role-definition-id "<role-definition-id>"
Usar uma entidade de serviço
Agora que você criou um aplicativo e uma entidade de serviço do Microsoft Entra, criou uma função personalizada e atribuiu permissões de função à sua conta do Azure Cosmos DB for NoSQL, você poderá executar um notebook.
Abra o workspace do Azure Databricks.
Na interface do workspace, crie um cluster. Defina o cluster com estas configurações, no mínimo:
Versão Valor Versão de runtime 13.3 LTS (Scala 2.12, Spark 3.4.1)
Use a interface do workspace para pesquisar pacotes do Maven na Central do Maven com uma ID de grupo de
com.azure.cosmos.spark
. Instale o pacote especificamente para o Spark 3.4 com uma ID de artefato prefixado comazure-cosmos-spark_3-4
no cluster.Por fim, crie um notebook.
Dica
Por padrão, o notebook é anexado ao cluster criado recentemente.
No notebook, defina as configurações do conector Spark do Azure Cosmos DB para o ponto de extremidade da conta NoSQL, o nome do banco de dados e o nome do contêiner. Use os valores de ID da Assinatura, Grupo de Recursos, ID do Aplicativo (cliente), ID do Diretório (locatário) e Segredo do Cliente registrados anteriormente neste artigo.
# Set configuration settings config = { "spark.cosmos.accountEndpoint": "<nosql-account-endpoint>", "spark.cosmos.auth.type": "ServicePrincipal", "spark.cosmos.account.subscriptionId": "<subscription-id>", "spark.cosmos.account.resourceGroupName": "<resource-group-name>", "spark.cosmos.account.tenantId": "<entra-tenant-id>", "spark.cosmos.auth.aad.clientId": "<entra-app-client-id>", "spark.cosmos.auth.aad.clientSecret": "<entra-app-client-secret>", "spark.cosmos.database": "<database-name>", "spark.cosmos.container": "<container-name>" }
// Set configuration settings val config = Map( "spark.cosmos.accountEndpoint" -> "<nosql-account-endpoint>", "spark.cosmos.auth.type" -> "ServicePrincipal", "spark.cosmos.account.subscriptionId" -> "<subscription-id>", "spark.cosmos.account.resourceGroupName" -> "<resource-group-name>", "spark.cosmos.account.tenantId" -> "<entra-tenant-id>", "spark.cosmos.auth.aad.clientId" -> "<entra-app-client-id>", "spark.cosmos.auth.aad.clientSecret" -> "<entra-app-client-secret>", "spark.cosmos.database" -> "<database-name>", "spark.cosmos.container" -> "<container-name>" )
Configure a API do Catálogo para gerenciar a API para recursos NoSQL usando o Spark.
# Configure Catalog Api spark.conf.set("spark.sql.catalog.cosmosCatalog", "com.azure.cosmos.spark.CosmosCatalog") spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.accountEndpoint", "<nosql-account-endpoint>") spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.auth.type", "ServicePrincipal") spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.account.subscriptionId", "<subscription-id>") spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.account.resourceGroupName", "<resource-group-name>") spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.account.tenantId", "<entra-tenant-id>") spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.auth.aad.clientId", "<entra-app-client-id>") spark.conf.set("spark.sql.catalog.cosmosCatalog.spark.cosmos.auth.aad.clientSecret", "<entra-app-client-secret>")
// Configure Catalog Api spark.conf.set(s"spark.sql.catalog.cosmosCatalog", "com.azure.cosmos.spark.CosmosCatalog") spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.accountEndpoint", "<nosql-account-endpoint>") spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.auth.type", "ServicePrincipal") spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.account.subscriptionId", "<subscription-id>") spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.account.resourceGroupName", "<resource-group-name>") spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.account.tenantId", "<entra-tenant-id>") spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.auth.aad.clientId", "<entra-app-client-id>") spark.conf.set(s"spark.sql.catalog.cosmosCatalog.spark.cosmos.auth.aad.clientSecret", "<entra-app-client-secret>")
Crie um novo banco de dados usando
CREATE DATABASE IF NOT EXISTS
. Certifique-se de fornecer o nome do banco de dados.# Create a database using the Catalog API spark.sql("CREATE DATABASE IF NOT EXISTS cosmosCatalog.{};".format("<database-name>"))
// Create a database using the Catalog API spark.sql(s"CREATE DATABASE IF NOT EXISTS cosmosCatalog.<database-name>;")
Crie um novo contêiner usando o nome do banco de dados, o nome do contêiner, o caminho da chave de partição e os valores de taxa de transferência que você especificar.
# Create a products container using the Catalog API spark.sql("CREATE TABLE IF NOT EXISTS cosmosCatalog.{}.{} USING cosmos.oltp TBLPROPERTIES(partitionKeyPath = '{}', manualThroughput = '{}')".format("<database-name>", "<container-name>", "<partition-key-path>", "<throughput>"))
// Create a products container using the Catalog API spark.sql(s"CREATE TABLE IF NOT EXISTS cosmosCatalog.<database-name>.<container-name> using cosmos.oltp TBLPROPERTIES(partitionKeyPath = '<partition-key-path>', manualThroughput = '<throughput>')")
Crie um conjunto de dados de exemplo.
# Create sample data products = ( ("68719518391", "gear-surf-surfboards", "Yamba Surfboard", 12, 850.00, False), ("68719518371", "gear-surf-surfboards", "Kiama Classic Surfboard", 25, 790.00, True) )
// Create sample data val products = Seq( ("68719518391", "gear-surf-surfboards", "Yamba Surfboard", 12, 850.00, false), ("68719518371", "gear-surf-surfboards", "Kiama Classic Surfboard", 25, 790.00, true) )
Use
spark.createDataFrame
e a configuração do OLTP (processamento de transações online) salva anteriormente para adicionar dados de exemplo ao contêiner de destino.# Ingest sample data spark.createDataFrame(products) \ .toDF("id", "category", "name", "quantity", "price", "clearance") \ .write \ .format("cosmos.oltp") \ .options(config) \ .mode("APPEND") \ .save()
// Ingest sample data spark.createDataFrame(products) .toDF("id", "category", "name", "quantity", "price", "clearance") .write .format("cosmos.oltp") .options(config) .mode("APPEND") .save()
Dica
Neste exemplo de início rápido, as credenciais são atribuídas a variáveis em texto não criptografado. Por segurança, é recomendável usar segredos. Para obter mais informações sobre como configurar segredos, confira Adicionar segredos à sua configuração do Spark.