在部署期间读取 Azure ServiceBus 命名空间连接字符串
Read Azure ServiceBus Namespace connection string during deployment
我正在尝试从 Azure Function (C#) 向 Azure ServiceBus 队列发送消息。为此,我需要服务总线命名空间的 ConnectionString(或者可能传递 Azure.Core.TokenCredential
)。
我在将 ConnectionString 传递给 ServiceBusClient
构造函数时确实起作用了。
string connectionString = "Endpoint=sb://<servicebus-name>.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=<access-key>";
var client = new ServiceBusClient(connectionString);
var sender = client.CreateSender(queueName);
...
sender.SendMessagesAsync()
问题是部署应该是自动化的,Function 和 ServiceBus 是使用资源模板部署的。因此,SharedAccessKey
是在部署时创建的。如果我可以读取资源模板中的 AccessKey,我可以设置一个应用程序设置,然后可以由函数读取。但是,我找不到在资源模板中获取 AccessKey 的方法。可能吗?
我尝试过的另一件事是使用这样的 TokenCredential
创建 ServiceBusClient
:
var credentials = new DefaultAzureCredential();
string[] ss = queueUrl.Split('/', StringSplitOptions.RemoveEmptyEntries);
var fullyQualifiedName = ss[^2];
var queueName = ss[^1];
var client = new ServiceBusClient(fullyQualifiedName, credentials);
var sender = client.CreateSender(queueName);
using ServiceBusMessageBatch messageBatch = sender.CreateMessageBatchAsync().Result;
这样做时我得到:
Unauthorized access. 'Send' claim(s) are required to perform this operation. Resource: 'sb://<servicebus-name>.servicebus.windows.net/<queuename>'.
我不完全理解 DefaultAzureCredential
应该如何工作。是否有可能以某种方式解决此权限问题(这是在 Azure 函数中)?
我的解决方法
我有一个解决方法,它需要在部署资源模板后执行额外的步骤。使用 Azure CLI 读取 ServiceBus 命名空间 ConnectionString,然后使用该值更新应用程序设置。该函数然后从应用程序设置中读取连接字符串。
$ cs=$(az servicebus namespace authorization-rule keys list --namespace-name <Namespace> -n RootManageSharedAccessKey -g <resource-group> -o json | jq -r '.primaryConnectionString')
$ az functionapp config appsettings set --settings ServiceBusNamespaceConnectionStringCLI=$cs -g <resource-group> -n <function-name>
...
- name: ServiceBusNamespaceConnectionStringCLI
slotSetting: false
value: Endpoint=sb://<servicebus-name>.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=<access-key>
我不想使用这个额外的步骤,而是尽可能在模板或代码中完成。有什么想法吗?
感谢这个答案 我找到了如何在资源模板中获取 connectionString。这就是我使用应用程序设置将连接字符串传递给函数的方式。
"appSettings": [
{
"name": "ServiceBusConnectionString",
"value": "[listKeys(resourceId('Microsoft.ServiceBus/namespaces/AuthorizationRules', variables('serviceBusName'), ' RootManageSharedAccessKey'), '2021-06-01-preview').primaryConnectionString]"
}
我正在尝试从 Azure Function (C#) 向 Azure ServiceBus 队列发送消息。为此,我需要服务总线命名空间的 ConnectionString(或者可能传递 Azure.Core.TokenCredential
)。
我在将 ConnectionString 传递给 ServiceBusClient
构造函数时确实起作用了。
string connectionString = "Endpoint=sb://<servicebus-name>.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=<access-key>";
var client = new ServiceBusClient(connectionString);
var sender = client.CreateSender(queueName);
...
sender.SendMessagesAsync()
问题是部署应该是自动化的,Function 和 ServiceBus 是使用资源模板部署的。因此,SharedAccessKey
是在部署时创建的。如果我可以读取资源模板中的 AccessKey,我可以设置一个应用程序设置,然后可以由函数读取。但是,我找不到在资源模板中获取 AccessKey 的方法。可能吗?
我尝试过的另一件事是使用这样的 TokenCredential
创建 ServiceBusClient
:
var credentials = new DefaultAzureCredential();
string[] ss = queueUrl.Split('/', StringSplitOptions.RemoveEmptyEntries);
var fullyQualifiedName = ss[^2];
var queueName = ss[^1];
var client = new ServiceBusClient(fullyQualifiedName, credentials);
var sender = client.CreateSender(queueName);
using ServiceBusMessageBatch messageBatch = sender.CreateMessageBatchAsync().Result;
这样做时我得到:
Unauthorized access. 'Send' claim(s) are required to perform this operation. Resource: 'sb://<servicebus-name>.servicebus.windows.net/<queuename>'.
我不完全理解 DefaultAzureCredential
应该如何工作。是否有可能以某种方式解决此权限问题(这是在 Azure 函数中)?
我的解决方法
我有一个解决方法,它需要在部署资源模板后执行额外的步骤。使用 Azure CLI 读取 ServiceBus 命名空间 ConnectionString,然后使用该值更新应用程序设置。该函数然后从应用程序设置中读取连接字符串。
$ cs=$(az servicebus namespace authorization-rule keys list --namespace-name <Namespace> -n RootManageSharedAccessKey -g <resource-group> -o json | jq -r '.primaryConnectionString')
$ az functionapp config appsettings set --settings ServiceBusNamespaceConnectionStringCLI=$cs -g <resource-group> -n <function-name>
...
- name: ServiceBusNamespaceConnectionStringCLI
slotSetting: false
value: Endpoint=sb://<servicebus-name>.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=<access-key>
我不想使用这个额外的步骤,而是尽可能在模板或代码中完成。有什么想法吗?
感谢这个答案
"appSettings": [
{
"name": "ServiceBusConnectionString",
"value": "[listKeys(resourceId('Microsoft.ServiceBus/namespaces/AuthorizationRules', variables('serviceBusName'), ' RootManageSharedAccessKey'), '2021-06-01-preview').primaryConnectionString]"
}