Azure Synapse Analytics 専用プールに接続する

Azure DatabricksAzure Synapse Analyticsこのチュートリアルでは、サービスプリンシパル、Azure マネージドサービス Identity (MSI)、およびSQL 認証を使用して から 専用プールに接続するために必要なすべてのステップ説明します。Azure Synapse コネクタでは、次の 3 種類のネットワーク接続が使用されます。

  • Spark ドライバーから Azure Synapse へ

  • Spark driver and エグゼキューター to Azure storage アカウント

  • Azure Synapse から Azure ストレージ アカウントへ

Azure Synapse コネクタ

要件

チュートリアルを開始する前に、次のタスクを完了してください。

サービスプリンシパル を使用して に接続するAzure Synapse Analytics

このチュートリアルの次のステップでは、サービスプリンシパルを使用して Azure Synapse Analytics に接続する方法を示します。

ステップ 1: Create a Microsoft Entra ID サービスプリンシパル for the Azure Data Lake Storage Gen2

サービスプリンシパルを使用して Azure データレイク Gen2 に接続するには、管理者ユーザーが新しい Microsoft Entra ID (旧称 Azure Active Directory) アプリケーションを作成する必要があります。 すでに Microsoft Entra ID サービスプリンシパル をお持ちの場合は、 ステップ 3 に進んでください。 Microsoft Entra ID サービスプリンシパルを作成するには、次の手順に従います。

  1. Azure portal にサインインします。

  2. 複数のテナント、サブスクリプション、またはディレクトリにアクセスできる場合は、トップ メニューの [ディレクトリ + サブスクリプション (フィルター付きディレクトリ)] アイコンをクリックして、サービスプリンシパルをプロビジョニングするディレクトリに切り替えます。

  3. Microsoft Entra ID を検索して選択します。

  4. [管理] で、[アプリの登録] > [新規登録] をクリックします。

  5. [ 名前] に、アプリケーションの名前を入力します。

  6. [サポートされているアカウントの種類] セクションで、[この組織ディレクトリ内のアカウントのみ (Single テナント)] を選択します。

  7. 登録」をクリックします。

(省略可能) ステップ 2: Create a Microsoft Entra ID サービスプリンシパル for the Azure Synapse Analytics

オプションで、ステップ 1 の手順を繰り返すことで、 Azure Synapse Analytics 専用のサービスプリンシパルを作成できます。 サービスプリンシパル クレデンシャルの個別のセットを作成しない場合、接続は同じサービスプリンシパルを使用して Azure データ レイク Gen2 と Azure Synapse Analyticsに接続します。

ステップ 3: Azure のデータレイク Gen2 (and Azure Synapse Analytics) サービスプリンシパルのクライアント シークレットを作成する

  1. 「管理」で、「証明書とシークレット」をクリックします

  2. [ クライアント シークレット ] タブで、[ 新しいクライアント シークレット] をクリックします。

  3. [ クライアントシークレットの追加 ] ペインの [ 説明] に、クライアントシークレットの説明を入力します。

  4. [有効期限] で、クライアントシークレットの有効期限を選択し、[追加] をクリックします。

  5. クライアント シークレットの Value をコピーして安全な場所に保存します (このクライアント シークレットはアプリケーションのパスワードです)。

  6. アプリケーション ページの [概要 ] ページの [要点 ] セクションで、次の値をコピーします。

    • アプリケーション (クライアント) ID

    • ディレクトリ (テナント) ID

注:

Azure Synapse Analyticsのサービスプリンシパル認証情報のセットを作成した場合は、再度ステップに従ってクライアントシークレットを作成します。

ステップ 4: サービスプリンシパルに Azure Data Lake Storage Gen2 へのアクセス権を付与する

ストレージリソースへのアクセス権を付与するには、サービスプリンシパルにロールを割り当てます。 このチュートリアルでは、 Storage Blob Data Contributor を Azure Data Lake Storage Gen2 アカウントのサービスプリンシパルに割り当てます。 特定の要件に応じて、他のロールを割り当てる必要がある場合があります。

  1. Azure portal で、 ストレージ アカウント サービスに移動します。

  2. 使用する Azure ストレージ アカウントを選択します。

  3. 「アクセス制御(IAM)」をクリックします。

  4. [ + 追加 ] をクリックし、ドロップダウン メニューから [ ロールの割り当てを追加 ] を選択します。

  5. [選択] フィールドをステップ 1 で作成した Microsoft Entra ID アプリケーション名に設定し、[ロール] を [ストレージ BLOB データ共同作成者] に設定します。

  6. [保存]をクリックします。

注:

Azure Synapse Analyticsのサービスプリンシパル クレデンシャルのセットを作成した場合は、再度ステップに従って、Azure Data Lake Storage Gen2上のサービスプリンシパルへのアクセス権を付与します。

ステップ 5:Azure Synapse Analytics 専用プール にマスター キーを作成する

Azure Synapse Analytics 専用プールに接続し、 マスター キーを作成します (まだ作成していない場合)。

CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<Password>'

ステップ 6: Azure Synapse Analytics専用プール内のサービスプリンシパルにアクセス許可を付与する

Azure Synapse Analytics専用プールに接続し、 に接続するサービスプリンシパルの 外部ユーザーを作成しますAzure Synapse Analytics 。

CREATE USER <serviceprincipal> FROM EXTERNAL PROVIDER

注:

サービスプリンシパルの名前は、ステップ 2 ( Azure Synapse Analytics専用のサービスプリンシパルの作成をスキップした場合はステップ 1) で作成した名前と一致する必要があります。

サービスプリンシパルに db_owner になる権限を付与するには、次のコマンドを実行します。

sp_addrolemember 'db_owner', '<serviceprincipal>'

既存のテーブルに挿入するために必要な権限を付与します。

GRANT ADMINISTER DATABASE BULK OPERATIONS TO <serviceprincipal>
GRANT INSERT TO <serviceprincipal>

(オプション)新しいテーブルに挿入するために必要な権限を付与します。

GRANT CREATE TABLE TO <serviceprincipal>
GRANT ALTER ON SCHEMA ::dbo TO <serviceprincipal>

ステップ 7: 構文の例: Azure Synapse Analytics でデータをクエリして書き込む

Synapse のクエリは、Scala、Python、SQL、R で行うことができます。次のコード例では、ストレージ アカウント キーを使用し、ストレージ資格情報を Azure Databricks から Synapse に転送します。

次のコード例は、次のことを行う必要があることを示しています。

  • ノートブック セッションでストレージ アカウントのアクセス キーを設定するSet up the storage account access key in the notebook session

  • Azure storage アカウントのサービスプリンシパル credentials を定義します

  • Azure Synapse Analytics に対してサービスプリンシパル資格情報の個別のセットを定義します (定義されていない場合、コネクタは Azure storage アカウント資格情報を使用します)

  • Azure Synapse テーブルからデータを取得する

  • Azure Synapse クエリからデータを読み込む

  • データにいくつかの変換を適用し、データソースAPIを使用してデータをAzure Synapse内の別のテーブルに書き戻します

  import org.apache.spark.sql.DataFrame

// Set up the storage account access key in the notebook session
conf.spark.conf.set(
  "fs.azure.account.key.<your-storage-account-name>.dfs.core.windows.net",
  "<your-storage-account-access-key>")

// Define the service principal credentials for the Azure storage account
spark.conf.set("fs.azure.account.auth.type", "OAuth")
spark.conf.set("fs.azure.account.oauth.provider.type",  "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider")
spark.conf.set("fs.azure.account.oauth2.client.id", "<ApplicationId>")
spark.conf.set("fs.azure.account.oauth2.client.secret", "<SecretValue>")
spark.conf.set("fs.azure.account.oauth2.client.endpoint", "https://login.microsoftonline.com/<DirectoryId>/oauth2/token")

// Define a separate set of service principal credentials for Azure Synapse Analytics (If not defined, the connector will use the Azure storage account credentials)
spark.conf.set("spark.databricks.sqldw.jdbc.service.principal.client.id", "<ApplicationId>")
spark.conf.set("spark.databricks.sqldw.jdbc.service.principal.client.secret", "<SecretValue>")

// Get some data from an Azure Synapse table
val df: DataFrame = spark.read
  .format("com.databricks.spark.sqldw")
  .option("url", "jdbc:sqlserver://<the-rest-of-the-connection-string>")
  .option("tempDir", "abfss://<your-container-name>@<your-storage-account-name>.dfs.core.windows.net/<your-directory-name>")
  .option("enableServicePrincipalAuth", "true")
  .option("dbTable", "dbo.<your-table-name>")
  .load()

// Load data from an Azure Synapse query
val df1: DataFrame = spark.read
  .format("com.databricks.spark.sqldw")
  .option("url", "jdbc:sqlserver://<the-rest-of-the-connection-string>")
  .option("tempDir", "abfss://<your-container-name>@<your-storage-account-name>.dfs.core.windows.net/<your-directory-name>")
  .option("enableServicePrincipalAuth", "true")
  .option("query", "select * from dbo.<your-table-name>")
  .load()

// Apply some transformations to the data, then use the
// Data Source API to write the data back to another table in Azure Synapse
df1.write
  .format("com.databricks.spark.sqldw")
  .option("url", "jdbc:sqlserver://<the-rest-of-the-connection-string>")
  .option("tempDir", "abfss://<your-container-name>@<your-storage-account-name>.dfs.core.windows.net/<your-directory-name>")
  .option("enableServicePrincipalAuth", "true")
  .option("dbTable", "dbo.<new-table-name>")
  .save()

次のコード例は、次のことを行う必要があることを示しています。

  • ノートブック セッションでストレージ アカウントのアクセス キーを設定するSet up the storage account access key in the notebook session

  • Azure storage アカウントのサービスプリンシパル credentials を定義します

  • Azure Synapse Analytics に対してサービスプリンシパル クレデンシャルの個別のセットを定義します

  • Azure Synapse テーブルからデータを取得する

  • Azure Synapse クエリからデータを読み込む

  • データにいくつかの変換を適用し、データソースAPIを使用してデータをAzure Synapse内の別のテーブルに書き戻します

次のコード例は、次のことを行う必要があることを示しています。

  • Azure storage アカウントのサービスプリンシパル credentials を定義します

  • Azure Synapse Analytics に対してサービスプリンシパル クレデンシャルの個別のセットを定義します

  • ノートブック セッションでストレージ アカウントのアクセス キーを設定するSet up the storage account access key in the notebook session

  • SQLを使用したデータの読み取り

  • SQL を使用したデータの書き込み

# Define the Service Principal credentials for the Azure storage account
fs.azure.account.auth.type OAuth
fs.azure.account.oauth.provider.type org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider
fs.azure.account.oauth2.client.id <application-id>
fs.azure.account.oauth2.client.secret <service-credential>
fs.azure.account.oauth2.client.endpoint https://login.microsoftonline.com/<directory-id>/oauth2/token

## Define a separate set of service principal credentials for Azure Synapse Analytics (If not defined, the connector will use the Azure storage account credentials)
spark.databricks.sqldw.jdbc.service.principal.client.id <application-id>
spark.databricks.sqldw.jdbc.service.principal.client.secret <service-credential>
# Set up the storage account access key in the notebook session
conf.SET fs.azure.account.key.<your-storage-account-name>.dfs.core.windows.net=<your-storage-account-access-key>
-- Read data using SQL
CREATE TABLE df
USING com.databricks.spark.sqldw
OPTIONS (
  url 'jdbc:sqlserver://<the-rest-of-the-connection-string>',
  'enableServicePrincipalAuth' 'true',
  dbtable 'dbo.<your-table-name>',
  tempDir 'abfss://<your-container-name>@<your-storage-account-name>.dfs.core.windows.net/<your-directory-name>'
);
-- Write data using SQL
-- Create a new table, throwing an error if a table with the same name already exists:
CREATE TABLE df1
USING com.databricks.spark.sqldw
OPTIONS (
  url 'jdbc:sqlserver://<the-rest-of-the-connection-string>',
  'enableServicePrincipalAuth' 'true',
  dbTable 'dbo.<new-table-name>',
  tempDir 'abfss://<your-container-name>@<your-storage-account-name>.dfs.core.windows.net/<your-directory-name>'
)
AS SELECT * FROM df1

次のコード例は、次のことを行う必要があることを示しています。

  • ノートブック セッションの conf でストレージ アカウントのアクセス キーを設定します

  • Azure storage アカウントのサービスプリンシパル credentials を定義します

  • Azure Synapse Analytics に対してサービスプリンシパル資格情報の個別のセットを定義します (定義されていない場合、コネクタは Azure storage アカウント資格情報を使用します)

  • Azure Synapse テーブルからデータを取得する

  • データにいくつかの変換を適用し、データソースAPIを使用してデータをAzure Synapse内の別のテーブルに書き戻します

# Load SparkR
library(SparkR)

# Set up the storage account access key in the notebook session conf
conf <- sparkR.callJMethod(sparkR.session(), "conf")
sparkR.callJMethod(conf, "set", "fs.azure.account.key.<your-storage-account-name>.dfs.core.windows.net", "<your-storage-account-access-key>")

# Load SparkR
library(SparkR)
conf <- sparkR.callJMethod(sparkR.session(), "conf")

# Define the service principal credentials for the Azure storage account
sparkR.callJMethod(conf, "set", "fs.azure.account.auth.type", "OAuth")
sparkR.callJMethod(conf, "set", "fs.azure.account.oauth.provider.type",  "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider")
sparkR.callJMethod(conf, "set", "fs.azure.account.oauth2.client.id", "<ApplicationId>")
sparkR.callJMethod(conf, "set", "fs.azure.account.oauth2.client.secret", "<SecretValue>")
sparkR.callJMethod(conf, "set", "fs.azure.account.oauth2.client.endpoint", "https://login.microsoftonline.com/<DirectoryId>/oauth2/token")

# Define a separate set of service principal credentials for Azure Synapse Analytics (If not defined, the connector will use the Azure storage account credentials)
sparkR.callJMethod(conf, "set", "spark.databricks.sqldw.jdbc.service.principal.client.id", "<ApplicationId>")
sparkR.callJMethod(conf, "set", "spark.databricks.sqldw.jdbc.service.principal.client.secret", "SecretValue>")

# Get some data from an Azure Synapse table
df <- read.df(
  source = "com.databricks.spark.sqldw",
  url = "jdbc:sqlserver://<the-rest-of-the-connection-string>",
  tempDir = "abfss://<your-container-name>@<your-storage-account-name>.dfs.core.windows.net/<your-directory-name>",
  enableServicePrincipalAuth = "true",
  dbTable = "dbo.<your-table-name>")

# Load data from an Azure Synapse query.
df <- read.df(
  source = "com.databricks.spark.sqldw",
  url = "jdbc:sqlserver://<the-rest-of-the-connection-string>",
  tempDir = "abfss://<your-container-name>@<your-storage-account-name>.dfs.core.windows.net/<your-directory-name>",
  enableServicePrincipalAuth = "true",
  query = "Select * from dbo.<your-table-name>")

# Apply some transformations to the data, then use the
# Data Source API to write the data back to another table in Azure Synapse
write.df(
  df,
  source = "com.databricks.spark.sqldw",
  url = "jdbc:sqlserver://<the-rest-of-the-connection-string>",
  tempDir = "abfss://<your-container-name>@<your-storage-account-name>.dfs.core.windows.net/<your-directory-name>",
  enableServicePrincipalAuth = "true",
  dbTable = "dbo.<new-table-name>")

トラブルシューティング

次のセクションでは、発生する可能性のあるエラーメッセージとその考えられる意味について説明します。

サービスプリンシパル credential がユーザーとして存在しません

com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user '<token-identified principal>'

上記のエラーは、サービスプリンシパル クレデンシャルが Synapse アナリティクス ワークスペースにユーザーとして存在しないことを意味している可能性があります。

Azure Synapse Analytics 専用プールで次のコマンドを実行して、外部ユーザーを作成します。

CREATE USER <serviceprincipal> FROM EXTERNAL PROVIDER

サービスプリンシパル credential に十分なSELECTアクセス許可がありません

com.microsoft.sqlserver.jdbc.SQLServerException: The SELECT permission was denied on the object 'TableName', database 'PoolName', schema 'SchemaName'. [ErrorCode = 229] [SQLState = S0005]

上記のエラーは、サービスプリンシパル クレデンシャルに Azure Synapse Analytics 専用プールに十分な SELECT アクセス許可がないことを意味している可能性があります。

Azure Synapse Analytics 専用プールで次のコマンドを実行して、SELECT アクセス許可を付与します。

GRANT SELECT TO <serviceprincipal>

サービスプリンシパル credential には、COPY を使用する権限がありません

com.microsoft.sqlserver.jdbc.SQLServerException: User does not have permission to perform this action. [ErrorCode = 15247] [SQLState = S0001]

上記のエラーは、サービスプリンシパル credential に、COPY を使用するための十分なアクセス許可が Azure Synapse Analytics 専用プールにないことを意味している可能性があります。 サービスプリンシパルには、操作 (既存のテーブルへの挿入または新しいテーブルへの挿入) に応じて異なるアクセス許可が必要です。 サービスプリンシパルに必要なAzure Synapse権限があることを確認します。

注:

サービスプリンシパルは、 Azure Synapse Analytics専用プールの db_owner ではありません。

Azure Synapse Analytics 専用プールで次のコマンドを実行して、 db_owner アクセス許可を付与します。

sp_addrolemember 'db_owner', 'serviceprincipal'

専用プールにマスター キーがありません

com.microsoft.sqlserver.jdbc.SQLServerException: Please create a master key in the database or open the master key in the session before performing this operation. [ErrorCode = 15581] [SQLState = S0006]

上記のエラーは、Azure Synapse Analytics 専用プールにマスター キーが存在しないことを意味している可能性があります。

この問題を解決するには、Azure Synapse Analytics でマスター キーを作成します

サービスプリンシパル credential に十分な書き込み権限がありません

com.microsoft.sqlserver.jdbc.SQLServerException: CREATE EXTERNAL TABLE AS SELECT statement failed as the path name '' could not be used for export. Please ensure that the specified path is a directory which exists or can be created, and that files can be created in that directory. [ErrorCode = 105005] [SQLState = S0001]

上記のエラーは、おそらく次のことを意味します。