1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Data Factory から CosmosDB へデータをロード with Managed ID

Posted at

やりたいこと

ADF (Azure Data Factory) から CosmosDB へ Managed ID を使ってデータをロードする際にちょっと詰まったので、記事にしようと思います。

背景

ある案件で、とあるデータソースからデータを CosmosDB へロードするパイプラインを作成した。
当初、CosmosDB への Linked Service では Account Key を使って接続していたが、ADF の Managed ID を使う方針になり、その変更を行った際になかなか接続できなかった。

どういう事象だったか?

Linked Service の設定で、もろもろ設定した後に「Test connection」を試すと以下のメッセージ (一部伏せている)。

Unauthorized to cosmos db endpoint. Please provide a valid credential.
Response status code does not indicate success: Forbidden (403); Substatus: 5301; ActivityId: ****-****-****-****-****; Reason: (Request blocked by Auth ******** : Request is blocked because principal [****-****-****-****-****] does not have required RBAC permissions to perform action [Microsoft.DocumentDB/databaseAccounts/readMetadata] on resource [dbs/****]. Learn more: https://aka.ms/cosmos-native-rbac.
ActivityId: ****-****-****-****-****, Microsoft.Azure.Documents.Common/2.14.0, Microsoft.Azure.Cosmos.Tracing.TraceData.ClientSideRequestStatisticsTraceDatum, Windows/10.0.17763 cosmos-netstandard-sdk/3.19.3);
Activity ID: ****-****-****-****-****-.

要は、Microsoft.DocumentDB/databaseAccounts/readMetadata のアクションを実行するのに必要な権限が無いとのことらしい。

ひとまずエラーメッセージ内のリンク先を確認してみる。

以下の CosmosDB 用の組み込みロールを使って、権限の設定を行う必要があるらしい (おそらく一般的な SQL サーバと同様にユーザ毎に権限を設定するイメージ)。

image.png

組み込みロールのアサイン

エラーメッセージ的に、メタデータへのアクセスが必要なようなので Cosmos DB Built-in Data Reader の権限を ADF の Managed ID に付与する。
上記リンクでは、Azure CLI でロールのアサインを行っているが、Azure リソースは Terraform ですでに管理しているので、Terraformで行う。

上記のドキュメントを参考に以下のように設定した。

resource "azurerm_cosmosdb_sql_role_assignment" "adf_write_cosmos" {
  resource_group_name = azurerm_resource_group.examle.name
  account_name        = azurerm_cosmosdb_account.example.name
  principal_id        = azurerm_data_factory.example.identity[0].principal_id
  role_definition_id  = "/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${azurerm_resource_group.examle.name}/providers/Microsoft.DocumentDB/databaseAccounts/${azurerm_cosmosdb_account.sample.name}/sqlRoleDefinitions/00000000-0000-0000-0000-000000000001"
  scope               = azurerm_cosmosdb_account.sample.id
}

terraform apply して設定を反映させると、CosmosDB への Linked Service が Managed ID を使って接続できるようになった!

ところが‥?

いざパイプラインを実行してみると、CosmosDB への書き込みでエラーが起きる。

Failure happened on 'Sink' side. ErrorCode=CosmosDbSqlApiInvalidCredential,'Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=Unauthorized to cosmos db endpoint. Please provide a valid credential.,Source=Microsoft.DataTransfer.ClientLibrary.CosmosDbSqlApiV3,''Type=Microsoft.Azure.Cosmos.CosmosException,Message=Response status code does not indicate success: Forbidden (403); Substatus: 5301; ActivityId: ****-****-****-****-****; Reason: (Request blocked by Auth cosmos-****-**** : Request is blocked because principal [****-****-****-****-****] does not have required RBAC permissions to perform action [Microsoft.DocumentDB/databaseAccounts/readMetadata] on resource [/]. Learn more: https://aka.ms/cosmos-native-rbac.

さっきと同じようなメッセージ。Microsoft.DocumentDB/databaseAccounts/readMetadata のアクションを実行するのに必要な権限が無いと言っている…

もう1つの組み込みロール Cosmos DB Built-in Data Contributor の方で、許可されているアクションに containers/*items/* があるので、そちらならうまくいくのでは?と思い設定し直してみる。Terraform のコードの role_definition_id の末尾を 1 → 2 にして再度 apply する。

resource "azurerm_cosmosdb_sql_role_assignment" "adf_write_cosmos" {
  resource_group_name = azurerm_resource_group.examle.name
  account_name        = azurerm_cosmosdb_account.example.name
  principal_id        = azurerm_data_factory.example.identity[0].principal_id
  role_definition_id  = "/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${azurerm_resource_group.examle.name}/providers/Microsoft.DocumentDB/databaseAccounts/${azurerm_cosmosdb_account.sample.name}/sqlRoleDefinitions/00000000-0000-0000-0000-000000000002"
  scope               = azurerm_cosmosdb_account.sample.id
}

再度パイプラインを実行してみると、、成功!
想定どおりにデータが CosmosDB へ書き込まれている!:tada:

ドキュメントを読み直すと、以下とのことなので書き込みが必要な場合は Cosmos DB Built-in Data Contributor のロールが必要ということでした。また、この組み込みロールは CosmosDB 内でのみのロールなようで、通常の RBAC とは異なるとのことなので注意です (IAM から設定はできない)。

image.png

ということで

CosmosDB へ Managed ID で接続する際に CosmosDB の組み込みロールをアサインする手順をまとめました。
通常の RBAC とは異なり専用の組み込みロールという点がやや分かりづらく Portal からの設定もできなさそうなので気づきにくい点でした。皆さまご注意ください!

以上です!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?