I have two functions in a function app. Sometimes multiple instances of the functions run simultaneously. The functions run in a tenant that has many subscriptions.
Because the functions do configurations on virtual networks in these subscriptions, the script has to set context to the subscription a specific network is in. The Get/Set/New-AzVirtualNetwork cmdlets have no -SubscriptionId parameter, so they depend on the context that is set.
I found that when context is set in an instance of the function the context in the other instance(s) is changed as well, causing errors and/or operations performed in the wrong context
I created two simple function scripts that prove my assertion. HttpTrigger1 sets a different context every 60 seconds. HttpTrigger2 gets the context every 60 seconds. Both functions run in the same function app.
HttpTrigger1
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
Get-AzContext
Set-AzContext -SubscriptionName 'test1'
Start-Sleep -seconds 60
Set-AzContext -SubscriptionName 'test2'
Start-Sleep -seconds 60
Set-AzContext -SubscriptionName 'test3'
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = $body
})
HttpTrigger2
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
Get-AzContext
Start-Sleep -seconds 60
Get-AzContext
Start-Sleep -seconds 60
Get-AzContext
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = $body
})
When I trigger the first function, and trigger the second function a few seconds after the first function is triggered, the functions show this output:
HttpTrigger1
onnected!
2023-08-08T08:39:22Z [Information] Executing 'Functions.HttpTrigger1' (Reason='This function was programmatically called via the host APIs.', Id=78060401-7388-4c41-9639-9cce01e888c1)
2023-08-08T08:39:22Z [Vercose] Sending invocation id: '78060401-7388-4c41-9639-9cce01e888c1
2023-08-08T08:39:22Z [Vercose] Posting invocation id:78060401-7388-4c41-9639-9cce01e88444 on workerId:74cdc1af-1f11-439a-889d-3d81616f2222
2023-08-08T08:39:34Z [Information] OUTPUT:
2023-08-08T08:39:34Z [Information] OUTPUT: Account SucscriptionName TenantId Environment
2023-08-08T08:39:34Z [Information] OUTPUT: ------- ---------------- -------- -----------
2023-08-08T08:39:34Z [Information] OUTPUT: 22222222-2222-2222-9e94-3fc108fa96a8 mngmnt 11111111-1111-1111-96cc-8736a88e4a8e AzureCloud
2023-08-08T08:39:34Z [Information] OUTPUT:
2023-08-08T08:39:38Z [Information] OUTPUT:
2023-08-08T08:39:38Z [Information] OUTPUT: Name Account SucscriptionName Environment TenantId
2023-08-08T08:39:38Z [Information] OUTPUT: ---- ------- ---------------- ----------- --------
2023-08-08T08:39:38Z [Information] OUTPUT: mngmnt (fa918aed-3cc9-4ca8-a… 22222222-2222-2222… mngmnt AzureCloud 11111111-1111-1111…
2023-08-08T08:39:36Z [Information] OUTPUT: test1 (1476c99c-8864-4837-c… 22222222-2222-2222… test1 AzureCloud 11111111-1111-1111…
2023-08-08T08:40:36Z [Information] OUTPUT: test2 (88dafc79-731c-48a8-9… 22222222-2222-2222… test2 AzureCloud 11111111-1111-1111…
2023-08-08T08:41:36Z [Information] OUTPUT: test3 (cc0d1dea-3f43-46cc-c… 22222222-2222-2222… test3 AzureCloud 11111111-1111-1111…
2023-08-08T08:41:36Z [Information] OUTPUT:
2023-08-08T08:41:36Z [Information] Executed 'Functions.HttpTrigger1' (Succeeded, Id=78060401-7388-4c41-9639-9cce01e88555, Duration=133803ms)
HttpTrigger2
Connected!
2023-08-08T08:39:39Z [Information] Executing 'Functions.HttpTrigger2' (Reason='This function was programmatically called via the host APIs.', Id=16f66ac8-1edc-4615-8c25-fff5c4c80605)
2023-08-08T08:39:39Z [Verbose] Sending invocation id: '16f66ac8-1edc-4615-8c25-fff5c4c80605
2023-08-08T08:39:39Z [Verbose] Posting invocation id:16f66ac8-1edc-4615-8c25-fff5c4c80444 on workerId:74bdc1af-1f11-439a-889d-3d51616f2222
2023-08-08T08:39:44Z [Information] OUTPUT:
2023-08-08T08:39:44Z [Information] OUTPUT: Account SubscriptionName TenantId Environment
2023-08-08T08:39:44Z [Information] OUTPUT: ------- ---------------- -------- -----------
2023-08-08T08:39:44Z [Information] OUTPUT: 22222222-2222-2222-9e94-3fb108fa96a5 mngmnt 11111111-1111-1111-96cb-5736a55e4a5e AzureCloud
2023-08-08T08:39:44Z [Information] OUTPUT:
2023-08-08T08:39:44Z [Information] OUTPUT:
2023-08-08T08:39:44Z [Information] OUTPUT: Name Account SubscriptionName Environment TenantId
2023-08-08T08:39:44Z [Information] OUTPUT: ---- ------- ---------------- ----------- --------
2023-08-08T08:39:44Z [Information] OUTPUT: mngmnt (fa918aed-3cc9-4ca8-a… 22222222-2222-2222… mngmnt AzureCloud 11111111-1111-1111…
2023-08-08T08:40:44Z [Information] OUTPUT: test2 (88dafc79-731c-48a8-9… 22222222-2222-2222… test2 AzureCloud 11111111-1111-1111…
2023-08-08T08:41:44Z [Information] OUTPUT: test3 (cc0d1dea-3f43-46cc-c… 22222222-2222-2222… test3 AzureCloud 11111111-1111-1111…
2023-08-08T08:41:44Z [Information] OUTPUT:
2023-08-08T08:41:44Z [Information] Executed 'Functions.HttpTrigger2' (Succeeded, Id=16f66ac8-1edc-4615-8c25-fff5c4c80444, Duration=124521ms)
When comparing the timestamps and output it can be observed that the context set in HttpTrigger1 is also set in HttpTrigger2
I assume this behaviour is by design. Can anyone explain why this is? This is not how pwsh works on my machine.
I figured out I can avoid the context switches by not using the -AzVirtualNetwork cmdlets and do virtual network operations through the REST api and avoid the AZ. modules that depend on Set-AzContext
My question is: is there a way to prevent/change this behaviour in Azure functions, alowing me to change context without the risk of other instances interfering?