Использование субъекта-службы с соединителем Spark 3 для Azure Cosmos DB для NoSQL
В этой статье вы узнаете, как создать приложение Microsoft Entra и субъект-службу, которые можно использовать с управлением доступом на основе ролей. Затем эту службу можно использовать для подключения к учетной записи Azure Cosmos DB для NoSQL из Spark 3.
Необходимые компоненты
- Существующая учетная запись Azure Cosmos DB для NoSQL.
- Если у вас есть подписка Azure, создайте новую учетную запись.
- Нет подписки Azure? Вы можете попробовать Azure Cosmos DB бесплатно без кредитной карты.
- Существующая рабочая область Azure Databricks.
- Зарегистрировано приложение Microsoft Entra и субъект-служба.
- Если у вас нет субъекта-службы и приложения, зарегистрируйте приложение с помощью портал Azure.
Создание секрета и учетных данных записи
В этом разделе вы создадите секрет клиента и запишите значение для последующего использования.
Откройте портал Azure.
Перейдите к существующему приложению Microsoft Entra.
Перейдите на страницу "Сертификаты и секреты ". Затем создайте новый секрет. Сохраните значение секрета клиента для использования далее в этой статье.
Перейдите на страницу Обзор. Найдите и запишите значения для идентификатора приложения (клиента), идентификатора объекта и каталога (клиента). Эти значения также используются далее в этой статье.
Перейдите к существующей учетной записи Azure Cosmos DB для NoSQL.
Запишите значение URI на странице обзора. Также запишите значения идентификатора подписки и группы ресурсов. Эти значения используются далее в этой статье.
Создание определения и назначения
В этом разделе описано, как создать определение роли идентификатора Microsoft Entra. Затем вы назначите эту роль с разрешениями на чтение и запись элементов в контейнерах.
Создайте роль с помощью
az role definition create
команды. Передайте имя учетной записи и группу ресурсов Azure Cosmos DB для NoSQL, а затем текст JSON, определяющий пользовательскую роль. Роль также распространяется на уровень учетной записи с помощью/
. Убедитесь, что вы предоставляете уникальное имя для роли с помощьюRoleName
свойства текста запроса.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/*" ] }] }'
Перечислите определение роли, созданное для получения уникального идентификатора в выходных данных JSON.
id
Запишите значение выходных данных 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": [] } ], ... } ]
Используется
az cosmosdb sql role assignment create
для создания назначения ролей. Замените<aad-principal-id>
идентификатор объекта, записанный ранее в этой статье. Кроме того, замените<role-definition-id>
id
значение, полученное при выполненииaz cosmosdb sql role definition list
команды на предыдущем шаге.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>"
Использование субъекта-службы
Теперь, когда вы создали приложение Microsoft Entra и субъект-службу, создали пользовательскую роль и назначили этим разрешениям роли учетной записи Azure Cosmos DB для NoSQL, вы сможете запустить записную книжку.
Откройте рабочую область Azure Databricks.
В интерфейсе рабочей области создайте новый кластер. Настройте кластер с этими параметрами как минимум:
Версия Значение Версия среды выполнения 13.3 LTS (Scala 2.12, Spark 3.4.1)
Используйте интерфейс рабочей области для поиска пакетов Maven из Maven Central с идентификатором
com.azure.cosmos.spark
группы. Установите пакет специально для Spark 3.4 с префиксом идентификатора артефакта, заданным вazure-cosmos-spark_3-4
кластере.Наконец, создайте новую записную книжку.
Совет
По умолчанию записная книжка подключена к недавно созданному кластеру.
В записной книжке задайте параметры конфигурации соединителя Spark Azure Cosmos DB для конечной точки учетной записи NoSQL, имени базы данных и имени контейнера. Используйте идентификатор подписки, группу ресурсов, идентификатор приложения (клиента), идентификатор каталога (клиента) и значения секрета клиента, записанные ранее в этой статье.
# 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>" )
Настройте API каталога для управления ресурсами API noSQL с помощью 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>")
Создайте новую базу данных с помощью
CREATE DATABASE IF NOT EXISTS
. Убедитесь, что укажите имя базы данных.# 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>;")
Создайте контейнер с помощью имени базы данных, имени контейнера, пути ключа секции и заданных значений пропускной способности.
# 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>')")
Создание примера набора данных.
# 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) )
Используйте
spark.createDataFrame
и ранее сохраненную конфигурацию обработки транзакций (OLTP) для добавления примеров данных в целевой контейнер.# 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()
Совет
В этом кратком руководстве учетные данные назначаются переменным в виде ясного текста. Для безопасности рекомендуется использовать секреты. Дополнительные сведения о настройке секретов см. в разделе "Добавление секретов в конфигурацию Spark".