如何在 ARM 模板中创建一个 azure 功能键?
how to create an azure function key in ARM template?
我整天都在为这个问题苦苦挣扎,我正在尝试从 ARM 模板创建一个 Function App 功能键。
到目前为止,我已经能够使用以下模板在主机级别创建我的功能键:
{
"type": "Microsoft.Web/sites/host/functionKeys",
"apiVersion": "2018-11-01",
"name": "[concat(parameters('appServiceName'), '/default/PortalFunctionKey')]",
"properties": {
"name": "PortalFunctionKey"
}
然后我找到了几篇文章 link 表明可以通过 API 实现:
https://github.com/Azure/azure-functions-host/wiki/Key-management-API
而且我能够通过这个 API 发布到:
https://{myfunctionapp}.azurewebsites.net/admin/functions/{MyFunctionName}/keys/{NewKeyName}?code={_masterKey}
但我实在想不出如何在我的 ARM 模板中做到这一点!
我尝试了各种类型和名称的组合,例如:
{
"type": "Microsoft.Web/sites/host/functionKeys",
"apiVersion": "2018-11-01",
"name": "[concat(parameters('appServiceName'), '/{myfunctionName}/PortalFunctionKey')]",
"properties": {
"name": "PortalFunctionKey"
}
或/functions/{myfunctionName}/PortalFunctionKey
正如某些文章中所建议的那样,我无法正常工作,找不到关于 ARM Microsoft 的太多文档。Web/sites/host/functionKeys 也一样。
有没有人成功在 ARM 模板中创建功能键(不是主机)?我很乐意听听您是如何到达那里的:)!
基本上:
非常感谢,
伊曼纽尔
要解决这个问题,你可以参考这个github问题。 First issue and second issue,这些issues都有关于如何获取ARM模板中的function key的问题
目前获取键值的示例如下所示:
"properties": {
"contentType": "text/plain",
"value": "[listkeys(concat(variables('functionAppId'), '/host/default/'),'2016-08-01').functionKeys.default]"
}
或使用下面的方法获取关键对象。
"functionkeys": {
"type": "object",
"value": "[listkeys(concat(variables('functionAppId'), '/host/default'), '2018-11-01')]" }
}
你可以试试看,希望对你有帮助。
因此目前无法在 ARM 模板中创建功能级功能键。
因此,我创建了一个功能请求,如果您对此感兴趣,可以投票:
https://feedback.azure.com/forums/169385-web-apps/suggestions/39789043-create-function-level-keys-for-azure-functions-in
虽然现在,我们正在通过 powershell 部署任务步骤创建功能级功能键。方法如下。
将输出参数添加到您的 ARM 模板:
"outputs": {
"masterKey": {
"type": "string",
"value": "[listkeys(concat(resourceId(resourceGroup().name, 'Microsoft.Web/sites', parameters('appServiceName')), '/host/default'), '2018-11-01').masterKey]"
},
"appServiceName": {
"type": "string",
"value": "[parameters('appServiceName')]"
},
"functionKeys": {
"type": "array",
"value": [
{
"functionName": "myFunctionName",
"keys": [ "FunctionKeyName1", "FunctionKeyName2" ]
}
]
}
}
将以下 PS 脚本文件添加到您的部署项目中:
param (
[Parameter(Mandatory=$true)]
[string]
$armOutputString
)
Write-Host $armOutputString
$armOutputObj = $armOutputString | convertfrom-json
Write-Host $armOutputObj
$masterKey = $armOutputObj.masterKey.value
$appServiceName = $armOutputObj.appServiceName.value
$httpHeaders = @{
"x-functions-key" = $masterKey
}
$contentType = "application/json; charset=utf-8"
foreach($function in $armOutputObj.functionKeys.value){
$retryCount = 5;
while ($true) {
try {
$uriBase = "https://$($appServiceName).azurewebsites.net/admin/functions/$($function.functionName)/keys"
$existingKeys = Invoke-RestMethod -Method Get -Uri $uriBase -Headers $httpHeaders -ContentType $contentType
break;
}
catch {
if ($_.Exception.Response.StatusCode.value__ -eq 502) {
if ($retryCount-- -eq 0) {
throw;
}
else {
Write-Output ("Retry" + ": " + $_.Exception.Response.StatusCode + "; attempts=$retryCount")
[System.Threading.Thread]::Sleep(1000);
continue;
}
}
else {
throw;
}
}
}
foreach ($keyname in $function.keys){
$keyExists = 0
foreach($exstingKey in $existingKeys.keys){
if($exstingKey.name -eq $keyname){
$keyExists = 1
Write-Host "key $($keyname) already exists"
}
}
if($keyExists -eq 0){
$uri = "$($uriBase)/$($keyname)?code=$($masterKey)";
Write-Host "Adding $($keyname) key"
Invoke-RestMethod -Method Post -Uri "$($uriBase)/$($keyname)" -Headers $httpHeaders -ContentType $contentType;
}
}
}
脚本确保如果密钥已经存在则不会被覆盖,如果失败将重试(函数必须存在并且 运行 才能使 API 工作)。
在您的“Azure 资源组部署”任务中,在“高级”下设置“部署输出”到“armDeployOutput”。
添加一个 Powershell 任务,您的脚本路径到部署项目中的 powershell 文件,并将“Arguments”设置为“-armOutputString '$(armDeployOutput )'".
就是这样。
这可能会解决现在的问题:https://docs.microsoft.com/en-us/azure/templates/microsoft.web/2020-06-01/sites/functions/keys
我能够通过传递如下所示的 ARM 模板资源来创建功能键:
{
"type": "Microsoft.Web/sites/functions/keys",
"apiVersion": "2020-06-01",
"name": "{Site Name}/{Function App Name}/{Key Name}",
"properties": {
"value": "(optional)-key-value-can-be-passed-here"
}
}
看来就算属性里没有'value',那也至少得传一个空的属性对象吧
我整天都在为这个问题苦苦挣扎,我正在尝试从 ARM 模板创建一个 Function App 功能键。
到目前为止,我已经能够使用以下模板在主机级别创建我的功能键:
{
"type": "Microsoft.Web/sites/host/functionKeys",
"apiVersion": "2018-11-01",
"name": "[concat(parameters('appServiceName'), '/default/PortalFunctionKey')]",
"properties": {
"name": "PortalFunctionKey"
}
然后我找到了几篇文章 link 表明可以通过 API 实现: https://github.com/Azure/azure-functions-host/wiki/Key-management-API
而且我能够通过这个 API 发布到:
https://{myfunctionapp}.azurewebsites.net/admin/functions/{MyFunctionName}/keys/{NewKeyName}?code={_masterKey}
但我实在想不出如何在我的 ARM 模板中做到这一点! 我尝试了各种类型和名称的组合,例如:
{
"type": "Microsoft.Web/sites/host/functionKeys",
"apiVersion": "2018-11-01",
"name": "[concat(parameters('appServiceName'), '/{myfunctionName}/PortalFunctionKey')]",
"properties": {
"name": "PortalFunctionKey"
}
或/functions/{myfunctionName}/PortalFunctionKey 正如某些文章中所建议的那样,我无法正常工作,找不到关于 ARM Microsoft 的太多文档。Web/sites/host/functionKeys 也一样。
有没有人成功在 ARM 模板中创建功能键(不是主机)?我很乐意听听您是如何到达那里的:)!
基本上:
非常感谢,
伊曼纽尔
要解决这个问题,你可以参考这个github问题。 First issue and second issue,这些issues都有关于如何获取ARM模板中的function key的问题
目前获取键值的示例如下所示:
"properties": {
"contentType": "text/plain",
"value": "[listkeys(concat(variables('functionAppId'), '/host/default/'),'2016-08-01').functionKeys.default]"
}
或使用下面的方法获取关键对象。
"functionkeys": {
"type": "object",
"value": "[listkeys(concat(variables('functionAppId'), '/host/default'), '2018-11-01')]" }
}
你可以试试看,希望对你有帮助。
因此目前无法在 ARM 模板中创建功能级功能键。
因此,我创建了一个功能请求,如果您对此感兴趣,可以投票: https://feedback.azure.com/forums/169385-web-apps/suggestions/39789043-create-function-level-keys-for-azure-functions-in
虽然现在,我们正在通过 powershell 部署任务步骤创建功能级功能键。方法如下。
将输出参数添加到您的 ARM 模板:
"outputs": {
"masterKey": {
"type": "string",
"value": "[listkeys(concat(resourceId(resourceGroup().name, 'Microsoft.Web/sites', parameters('appServiceName')), '/host/default'), '2018-11-01').masterKey]"
},
"appServiceName": {
"type": "string",
"value": "[parameters('appServiceName')]"
},
"functionKeys": {
"type": "array",
"value": [
{
"functionName": "myFunctionName",
"keys": [ "FunctionKeyName1", "FunctionKeyName2" ]
}
]
}
}
将以下 PS 脚本文件添加到您的部署项目中:
param (
[Parameter(Mandatory=$true)]
[string]
$armOutputString
)
Write-Host $armOutputString
$armOutputObj = $armOutputString | convertfrom-json
Write-Host $armOutputObj
$masterKey = $armOutputObj.masterKey.value
$appServiceName = $armOutputObj.appServiceName.value
$httpHeaders = @{
"x-functions-key" = $masterKey
}
$contentType = "application/json; charset=utf-8"
foreach($function in $armOutputObj.functionKeys.value){
$retryCount = 5;
while ($true) {
try {
$uriBase = "https://$($appServiceName).azurewebsites.net/admin/functions/$($function.functionName)/keys"
$existingKeys = Invoke-RestMethod -Method Get -Uri $uriBase -Headers $httpHeaders -ContentType $contentType
break;
}
catch {
if ($_.Exception.Response.StatusCode.value__ -eq 502) {
if ($retryCount-- -eq 0) {
throw;
}
else {
Write-Output ("Retry" + ": " + $_.Exception.Response.StatusCode + "; attempts=$retryCount")
[System.Threading.Thread]::Sleep(1000);
continue;
}
}
else {
throw;
}
}
}
foreach ($keyname in $function.keys){
$keyExists = 0
foreach($exstingKey in $existingKeys.keys){
if($exstingKey.name -eq $keyname){
$keyExists = 1
Write-Host "key $($keyname) already exists"
}
}
if($keyExists -eq 0){
$uri = "$($uriBase)/$($keyname)?code=$($masterKey)";
Write-Host "Adding $($keyname) key"
Invoke-RestMethod -Method Post -Uri "$($uriBase)/$($keyname)" -Headers $httpHeaders -ContentType $contentType;
}
}
}
脚本确保如果密钥已经存在则不会被覆盖,如果失败将重试(函数必须存在并且 运行 才能使 API 工作)。
在您的“Azure 资源组部署”任务中,在“高级”下设置“部署输出”到“armDeployOutput”。
添加一个 Powershell 任务,您的脚本路径到部署项目中的 powershell 文件,并将“Arguments”设置为“-armOutputString '$(armDeployOutput )'".
就是这样。
这可能会解决现在的问题:https://docs.microsoft.com/en-us/azure/templates/microsoft.web/2020-06-01/sites/functions/keys
我能够通过传递如下所示的 ARM 模板资源来创建功能键:
{
"type": "Microsoft.Web/sites/functions/keys",
"apiVersion": "2020-06-01",
"name": "{Site Name}/{Function App Name}/{Key Name}",
"properties": {
"value": "(optional)-key-value-can-be-passed-here"
}
}
看来就算属性里没有'value',那也至少得传一个空的属性对象吧