使用托管标识将函数应用程序连接到 CosmosDB

时间:2021-05-13 01:16:42

标签: python azure azure-functions azure-cosmosdb

我正在尝试在函数应用程序中编写一个函数来操作 CosmosDB 中的数据。如果我在环境变量中删除读写密钥,我就可以正常工作。为了使其更强大,我希望它可以作为托管身份应用程序运行。该应用在 Cosmos DB 上具有“DocumentDB Account Contributor”角色。

但是,CosmosClient 构造函数不接受 Credential 并且需要读写密钥。我一直在寻找 azure.mgmt.cosmosdb.operations 的兔子洞,那里有一个带有 DatabaseAccountsOperations 方法的 list_keys() 类。不过,我找不到访问该功能的简洁方法。如果我尝试创建该对象(这需要从我的 dbmgmt 对象中挖取配置、序列化器和反序列化器),它仍然需要 resourceGroupNameaccountName

我不禁想到我在某个地方走错了路,因为这必须以更直接的方式成为可能。特别是考虑到 JavaScript SDK 引用了一个更符合逻辑的类 CosmosDBManagementClient,与 SubscriptionClient 一致。但是,我在 python 端的任何地方都找不到那个类。 有什么指点吗?

from azure.identity import DefaultAzureCredential
from azure.cosmos import CosmosClient
from azure.mgmt.resource import SubscriptionClient
from azure.mgmt.cosmosdb import CosmosDB
from .cred_wrapper import CredentialWrapper

def main(req: func.HttpRequest) -> func.HttpResponse:
    request_body = req.get_body()
    # credential = DefaultAzureCredential()
    # https://gist.github.com/lmazuel/cc683d82ea1d7b40208de7c9fc8de59d
    credential = CredentialWrapper()  

    uri = os.environ.get('cosmos-db-uri')
    # db = CosmosClient(url=uri, credential=credential)  # Doesn't work, wants a credential that is a RW/R key
    # Does work if I replace it with my primary / secondary key but the goal is to remove dependence on that.

    subscription_client = SubscriptionClient(credential)
    subscription = next(subscription_client.subscriptions.list())

    dbmgmt = CosmosDB(credential, subscription.subscription_id)  # This doesn't accept the DB URI??
    operations = list(dbmgmt.operations.list())  # I see the list_keys() Operation there...

编辑

一位乐于助人的人在这里提供了回复,但在我做出反应或接受它作为答案之前将其删除。他们指出有一个等价的 python SDK 并且 from azure.mgmt.cosmosdb import CosmosDBManagementClient 可以解决问题。

从那里开始,我就靠自己了

ImportError: cannot import name 'CosmosDBManagementClient' from 'azure.mgmt.cosmosdb'

我认为问题的根源在于包 azure-mgmt 不兼容。从我的 azure-mgmt 中删除 requirements.txt 并仅加载 cosmos 和 identiy 相关包后,导入错误已解决。

这解决了 90% 的问题。

dbmgmt  = CosmosDBManagementClient(credential, subscription.subscription_id, c_uri)
print(dbmgmt.database_accounts.list_keys())
TypeError: list_keys() missing 2 required positional arguments: 'resource_group_name' and 'account_name'

真的需要收集这些参数中的每一个吗?与 example that reads a secret from a Vault 相比,它似乎太复杂了。

1 个答案:

答案 0 :(得分:1)

对于其他希望通过托管身份访问 CosmosDB 的不幸用户,截至 2021 年 5 月,这似乎还不可能。

来源:关于 Github

的讨论