Synchronising Keys for Multiple Function Apps
    • Dark
      Light
    • PDF

    Synchronising Keys for Multiple Function Apps

    • Dark
      Light
    • PDF

    Article Summary

    #ServerlessTips - Azure Functions
    Author: Michael Stephenson Azure MVP

    In the real world, it's common to want to develop a solution with Functions where the solution runs over multiple data centres to improve availability. An example of this architecture may look like the below diagram.

    solution-architecture

    In this architecture, we have a combination of global services and region-specific services in terms of physical deployment. For example, Traffic Manager is a global service out of the box. CosmosDB can easily be configured to run as a worldwide service with replication across multiple regions, which is transparent to the outside consumers.

    Other services are region-specific. In this example, Azure Functions will be physically deployed to one region.

    It is possible, however, when we combine Azure Functions and Traffic Manager to have the function in multiple regions and then to route the traffic across both regions in several different routing options

    At this point, we have two function apps, and traffic manager will route traffic across the two instances, but the challenge here is that by default, the two function apps will be set up with different keys. The scenario we want is to have both apps use the same key so it doesn’t matter which app traffic manager routes the call to we can supply the same key as a consumer.

    Setting the Key on a Function App

    There are several different ways that we can set the key, but I
    have found that the easiest way to do it is using the REST admin API for Functions and to use the master key as the credential. The steps to do this are:

    1. Create a json object to send to the API; you need to supply the new key name and value
    {
           "name" = “$(NewKeyName)”
           "value" = "$(NewKeyValue)"
    } 
    
    1. Next, we need to work out the URL to use. We need the name of the function app, the name for the new key and the master key for the function app which you can get from the function app settings. You can then use this URL format.

    2. We will then do an HTTP Post with the content type of application/json to the URL with the body being our json. This action will create a new key with the key name we supplied.

    3. We would then repeat this process on the 2nd Function App, so we create the same unique key on both Function apps.

    a. Remember the URL will change for the 2nd Function app as the name and master key will be different.

    At this point, we could now make a call to our function via Traffic Manager, and regardless of which Function App instance it hits the key will be the same, and it will just work.

    Automate with Powershell

    Next to many people will want to automate this with CD/CI pipelines or Powershell to setup keys for lots of function apps. I had to do this for 20 pairs of Function Apps and used the below Powershell script.

    Set-ExecutionPolicy -ExecutionPolicy Unrestricted
    cls
    
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    
    
    function SetFunctionKey([string] $functionAppName, [string] $masterKey, [string] $newKeyName, [string] $newKeyValue)
    {
        Write-Host 'Updating Key for App = ' $functionAppName
        
        $data = @{
            "name" = $newKeyName
            "value" = "$newKeyValue"
            } | ConvertTo-Json;
    
        $baseUrl = "https://$functionAppName.azurewebsites.net/admin/host/keys/"
        $url = $baseUrl + $newKeyName + '?code=' + $masterKey
    
        Write-Host $url
        Write-Host $data
    
        $response = Invoke-WebRequest -Method POST -Uri $url -Body $data -ContentType "application/json" -ErrorAction Stop
        Write-Host $response                                                                                                                                                 
    }
     
    SetFunctionKey -functionAppName "Acme-API-NE-ReferenceData" -masterKey "<master key goes here>" -newKeyName "trafficMgr" -newKeyValue ""<New key goes here>"
    SetFunctionKey -functionAppName "Acme-API-WE-ReferenceData" -masterKey "<master key goes here>" -newKeyName " trafficMgr" -newKeyValue "<New key goes here>”
    
    

    The above script will setup the function apps in the North Europe and West Europe data centres so that they both have the same key called TrafficManager which could be supplied as the x-functions-key header from the client and it would be routed to the function and authenticate in both cases.

    The one thing that is a little bit of a pain with this is getting the master keys, but maybe you can add them as properties to your CI/CD process etc.

    You can also write more scripting to go and parse out the master keys from the function apps, and I had a play around with that but found it equally as painful getting that script right when all I wanted to do was set the keys. This approach is a great halfway house to get you going, and if you have a lot of keys, then you may benefit from extending the PowerShell script further.

    Azure-functions.png


    Was this article helpful?