Usar uma entidade de serviço com o conector Spark 3 para o Azure Cosmos DB para NoSQL
Neste artigo, você aprenderá a criar um aplicativo e uma entidade de serviço do Microsoft Entra 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 a partir do Spark 3.
Pré-requisitos
- Uma conta existente do Azure Cosmos DB para NoSQL.
- Se você tiver uma assinatura existente do Azure, crie uma nova conta.
- Não há assinatura do Azure? Você pode experimentar o Azure Cosmos DB gratuitamente sem necessidade de cartão de crédito.
- Um espaço de trabalho existente do Azure Databricks.
- Aplicativo Microsoft Entra registrado e entidade de serviço.
- 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 credenciais
Nesta seção, você cria um segredo do cliente e registra o valor para uso posterior.
Abra o portal do Azure.
Vá para o seu aplicativo Microsoft Entra existente.
Vá para a página Certificados & segredos . Em seguida, crie um novo segredo. Salve o valor Segredo do Cliente para usar mais adiante neste artigo.
Vá para a página Visão geral . Localize e registre os valores para ID do aplicativo (cliente), ID do objeto e ID do diretório (locatário). Você também usa esses valores mais adiante neste artigo.
Vá para sua conta existente do Azure Cosmos DB para NoSQL.
Registre o valor de URI na página Visão geral . Registe também os valores de ID de Subscrição e Grupo de Recursos. Você usa esses valores posteriormente neste artigo.
Criar uma definição e uma atribuição
Nesta seção, você cria uma definição de função de ID do Microsoft Entra. Em seguida, você atribui essa função com permissões para ler e gravar itens nos contêineres.
Crie uma função usando o
az role definition create
comando. Passe o nome da conta do Azure Cosmos DB para NoSQL e o grupo de recursos, seguido por um corpo de JSON que define a função personalizada. A função também tem como escopo o nível da conta usando/
. Certifique-se de fornecer um nome exclusivo para sua função usando aRoleName
propriedade 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
id
valor 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>
id
pelo valor obtido ao executar oaz cosmosdb sql role definition list
comando 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 essas permissões de função à sua conta do Azure Cosmos DB para NoSQL, você deve ser capaz de executar um bloco de anotações.
Abra seu espaço de trabalho do Azure Databricks.
Na interface do espaço de trabalho, crie um novo cluster. Configure o cluster com estas configurações, no mínimo:
Versão Value Versão em tempo de execução 13.3 LTS (Scala 2.12, Spark 3.4.1)
Use a interface do espaço de trabalho para procurar pacotes Maven do Maven Central com uma ID de Grupo de
com.azure.cosmos.spark
. Instale o pacote especificamente para o Spark 3.4 com uma ID de artefato prefixada comazure-cosmos-spark_3-4
o cluster.Por fim, crie um novo bloco de anotações.
Gorjeta
Por padrão, o bloco de anotações é anexado ao cluster criado recentemente.
No bloco de anotações, defina as definições de configuração do conector do Azure Cosmos DB Spark para o ponto de extremidade da conta NoSQL, o nome do banco de dados e o nome do contêiner. Use os valores ID de Assinatura, Grupo de Recursos, ID de Aplicativo (cliente), ID de 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 de 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
o . 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 especificados.
# 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 OLTP (processamento de transações online) salvas anteriormente para adicionar dados de amostra 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()
Gorjeta
Neste exemplo de início rápido, as credenciais são atribuídas a variáveis em texto não criptografado. Por motivos de segurança, recomendamos que utilize segredos. Para obter mais informações sobre como configurar segredos, consulte Adicionar segredos à configuração do Spark.