Get Function & Host Keys of Azure Function In Powershell
Asked Answered
B

7

11

I have deployed Azure function using Arm template. I need the Function Key & host Key of deployed Azure Function in Powershell. Currently I am trying to get the keys From Output Section of ARM template

 "outputs": {
"FunctionAppName": {
  "type": "string",
  "value": "[variables('functionAppName')]"
},
"Key": {
  "type": "string",
  "value": "[listKeys(resourceId('Microsoft.Web/sites', '[variables('functionAppName')]'),'2015-08-01').keys]"
}

}

I tried different combinations But it failing. Is there any way to retrieve keys in Powershell?

Blueprint answered 6/4, 2017 at 11:11 Comment(1)
yes. It throws Bad Request as errorBlueprint
R
15

I got it working by using the following:

    "outputs": {
    "FunctionAppName": {
        "type": "string",
        "value": "[parameters('functionName')]"
    },
    "Key": {
        "type": "string",
        "value": "[listsecrets(resourceId('Microsoft.Web/sites/functions', parameters('existingFunctionAppName'), parameters('functionName')),'2015-08-01').key]"
    },        
    "Url": {
        "type": "string",
        "value": "[listsecrets(resourceId('Microsoft.Web/sites/functions', parameters('existingFunctionAppName'), parameters('functionName')),'2015-08-01').trigger_url]"
    }        
}

I couldn't find any examples either. But by using the above, a quickstart sample at GitHub and the documentation of resource functions along with a some trial and error, I got it to out.

Please note the variables/parameters and names have been changed.

Rattly answered 22/5, 2017 at 16:26 Comment(6)
How does the ARM template know what functions exist in the function app? If the code is not deployed until after the ARM template has run (to give it somewhere to deploy to)?Patience
@DanielEarwicker There is a "default" host-level key that is set at the function's service level. This wouldn't give you back the individual function's key, just the common host-level one (that works for all functions in the app).Woodrow
@Woodrow awesome, I'd got the idea that Function-level auth meant that you had to use a different key per function.Patience
@Woodrow - okay, turns out not so awesome. Not only is listsecrets seemingly undocumented, but also someone claims here that "this approach has a restriction. This can only access to individual function keys, not host key nor master key."Patience
This does not work for Functions after version 2.0.12050.0-alpha. Today you'll receive: System.InvalidOperationException: Runtime keys are stored on blob storage. This API doesn't support this configuration. Please change Environment variable AzureWebJobsSecretStorageType value to 'Files'. For more info, visit https://aka.ms/funcsecretsJanise
You'll need to switch to listkeys('function-resource-id', '2018-11-01') to get the function-specific keys. See Robb's answer for the host keys (when the if functions aren't deployed yet/separately).Janise
C
12

I could not get the accepted answer to work to retrieve the default host key. @4c74356b41's answer is very close. You can get the keys out using the code below. The default host key will be in Outputs.functionKeys.Value.functionKeys.default.Value.

  "outputs": {
    "functionKeys": {
      "type": "object",
      "value": "[listkeys(concat(resourceId('Microsoft.Web/sites', variables('functionAppName')), '/host/default'), '2018-11-01')]"
    }
  }
Christoper answered 7/8, 2019 at 15:21 Comment(3)
Worth noting that this is the right answer for V2 runtime, whereas V1 used listsecrets. This drove me crazy for a while earlier in the year, especially as the API version didn't seem to have been released when I first started trying to do this.Lineament
You're missing a closing parenthesis here.Preen
Wayward parenthesis put back in placeChristoper
A
5

Question doesn't seem to be answered as it was requesting to get the Function key from Powershell and not ARM templates. I'm using the script below to get the function key from Powershell in Azure DevOps.

$accountInfo = az account show
$accountInfoObject = $accountInfo | ConvertFrom-Json
$subscriptionId  = $accountInfoObject.id

$resourceGroup = "your-resource-group"
$functionName = "your-function-name"

$functionkeylist = az rest --method post --uri "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/sites/$functionName/host/default/listKeys?api-version=2018-11-01"
$keylistobject = $functionkeylist | ConvertFrom-Json
$functionKey = $keylistobject.functionKeys.default

Hope this helps.

Abomination answered 21/2, 2020 at 13:41 Comment(1)
See also here stackoverflow.com/a/62058134 for the cleanest Az Powershell one-liner I've seen for doing this Get-AzResource -Name RESOURCE-NAME | Invoke-AzResourceAction -Action host/default/listkeys -ForceTswana
S
4

Using Azure PowerShell

I'd like to offer a another way to solve this, using an as close to pure Azure PowerShell as I could manage to find. It still relies on composing an Azure "Operation" but can be done in only a few lines of code.

Note: This assumes that you have a PowerShell session that is already authenticated. If you do not see: Connect-AzAccount for more information.

Option 1 - Retrieve key for function app for use with all functions

This example is based on this operation: Web Apps - List Host Keys and using this PowerShell cmdlet to execute the operation: Invoke-AzRestMethod

## lookup the resource id for your Azure Function App ##
$resourceId = (Get-AzResource -ResourceGroupName $rg -ResourceName $functionAppName -ResourceType "Microsoft.Web/sites").ResourceId

## compose the operation path for listing keys ##
$path = "$resourceId/host/default/listkeys?api-version=2021-02-01"

## invoke the operation ##
$result = Invoke-AzRestMethod -Path $urlPath -Method POST
if($result -and $result.StatusCode -eq 200)
{
   ## Retrieve result from Content body as a JSON object ##
   $contentBody = $result.Content | ConvertFrom-Json

   ## Output the default function key. In reality you would do something more ##
   ## meaningful with this ##
   Write-Host $contentBody.functionKeys.default
}

Option 2 - Retrieve a key for a specific function

This example is based on this operation to retrieve a key specific to the function. This is generally better practice so that you don't have a one-key for all functions. But there are valid reasons why you might want either. See this operation here: Web Apps - List Function Keys

## Lookup function name here ##
$functionName = "MyFunction"

## lookup the resource id for your Azure Function App ##
$resourceId = (Get-AzResource -ResourceGroupName $rg -ResourceName $functionAppName -ResourceType "Microsoft.Web/sites").ResourceId

## compose the operation path for listing keys ##
$path = "$resourceId/functions/$functionName/listkeys?api-version=2021-02-01"

## invoke the operation ##
$result = Invoke-AzRestMethod -Path $urlPath -Method POST
if($result -and $result.StatusCode -eq 200)
{
   ## Retrieve result from Content body as a JSON object ##
   $contentBody = $result.Content | ConvertFrom-Json

   ## Output the default function key. In reality you would do something more ##
   ## meaningful with this. ##
   Write-Host $contentBody.default
}
Signalment answered 7/12, 2021 at 18:3 Comment(0)
I
0

First of all, you have an error in your syntax:

  "value": "[listKeys(resourceId('Microsoft.Web/sites', variables('functionAppName')),'2015-08-01').keys]"

but that won't help, I don't think its implemented for Azure Functions, I'm not 100% sure on this, but my efforts to retrive the keys were futile

Inlaw answered 6/4, 2017 at 13:32 Comment(0)
I
0

So to get this working for the function specific key for MyHttpFunction in the app MyFunctionApp, I had to use the following in the Outputs section of the ARM template:

"MyHttpFunctionKey": {
    "type": "string",
    "value": "[listkeys(resourceId('Microsoft.Web/sites/functions', 'MyFunctionApp', 'MyHttpFunction'), '2019-08-01').default]"
}

If that is called from Powershell using New-AzResourceGroupDeployment with a parameter -OutVariable arm then the following Powershell command will print the key: $arm.Outputs.myHttpFunctionKey.Value

Ironist answered 17/6, 2021 at 12:31 Comment(0)
S
0

Following code will get exact key in string format i used this key for availability test creation.

"outputs": {
      "Key":{
             "type": "string", 
             "value": "[listkeys(concat(resourceId('Microsoft.Web/sites', 'functionAppName'), '/functions', '/FunctionName'), '2018-11-01').default]"    
             }
            }
Scopophilia answered 5/11, 2021 at 16:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.