I kept finding this post in my quest to solve this problem through CI/CD - in case anyone else is running into this same problem - here is how I was able to solve it, albeit in a bit of a HACK way.
To re-summarize the problem - whenever I add the functions directly through the Azure portal, I am able to access them directly through the APIM Gateway just using the Ocp-Apim-Subscription-Key
header. However, when I import them during my pipeline runs using an OpenApi spec APIM is creating the named value that corresponds to the function key but it is not automatically adding the x-functions-key
header/code
param to the inbound requests. This means the imported functions are expecting BOTH the Ocp-Apim-Subscription-Key
header & also the x-functions-key
header or code
parameter.
First - I am using the Azure CLI & OpenApi spec to publish my functions post-deployment.
az apim api import `
--path 'my-function' `
-g 'rg-someresourcegroup' `
--api-id 'MyFunction' `
--description 'This is my function' `
--service-name 'apim-instance' `
--specification-format 'OpenApi' `
--specification-url 'https://func-myfunction.azurewebsites.net/api/openapi/v3.json' `
--display-name 'MyFunction' `
--api-version 'v1' `
--api-version-set-id 'MyFunction-v1' `
--subscription-key-header-name "Ocp-Apim-Subscription-Key" `
--subscription-key-query-param-name "subscription-key" `
--protocols "https"
The named value that gets created in APIM this way uses the Azure Function Resource Name + key
- in the example above that would be func-myfunctionkey
. I am passing this value into my CI/CD task & Powershell script using the parameter $WebAppName
.
Here is the policy snippet I am using to auto-add the x-functions-key
to the function (you can also modify this to use the ?code=
param if desired).
<policies>
<inbound>
<base />
<set-header name="x-functions-key" exists-action="override">
<value>@@function-key@@</value>
</set-header>
<!-- Other policy stuff here -->
</inbound>
<!-- Other policy stuff here -->
</policies>
Then in my pipeline - I'm doing a 'replace tokens'-style task using powershell & uploading this policy document to the APIM endpoint.
Write-Host `n"Creating default inbound policy for Api: $ApiName"
$apimContext = New-AzApiManagementContext -ResourceGroupName $ResourceGroupName -ServiceName $ServiceName
$path = './apim-default-api-policy.xml'
## Replace the @@function-key@@ with the correct value.
$xml = (Get-Content -Raw $path) -Replace "@@function-key@@", "{{$WebAppName-key}}"
Set-AzApiManagementPolicy -Context $apimContext `
-Format 'application/vnd.ms-azure-apim.policy.raw+xml' `
-ApiId $ApiName `
-Policy $xml
Write-Host `n"Set policy for $ApiName"
Note that I'm using the az
CLI for the import & Azure Powershell for the policy update - at the time of writing (05/2023) - the az
CLI does not appear to support policy manipulation like this - hopefully, this feature is added down the line.