Ken Muse

Function Trigger Syncing

It’s one of those frustrating moments. You’ve just updated your code in Azure. The moment you leave the portal, the Timer Trigger stops functioning. Perhaps the Function stops responding to change events from storage accounts. In other cases, it simply seems to utilize a single instance and not scale despite an increasing load. The logs don’t seem to help … everything just seems to be stuck.

Most times, these issues share the same root cause — Azure’s infrastructure is no longer in sync with your Function. Part of the magic of Azure Functions is its ability to automatically scale to handle requests, binding events to input triggers. Azure uses metadata from the Function to register appropriate event handlers. This process is normally handled automatically and transparently as part of the deployment process. Unfortunately, in some cases this doesn’t happen. one of the most common reasons is the use of FTP deployments (if you’re doing this, PLEASE consider moving to modern, future-safe approaches, such as using deployment packages!). It can also happen if you’re using a local Git repository, cloud sync, or re-publishing an existing ZIP package being used by the Azure Function.

When you use one of these approaches, Azure may not update the metadata associated with your Function. The new code is deployed, but the internal metadata is not updated. The end result is a Function that does not receive notifications correctly. In some cases, this can be as simple as changing the approach you’re using for deploying the code. If you’re using WEBSITE_RUN_FROM_PACKAGE with an external URL, deploying a new package requires updating an App Setting. This causes the Function to restart and automatically synchronizes the Function triggers. This does not work if you are replacing the remote ZIP or if you’re publishing the package directly to the service.

How do we handle the situation when we are deploying in a way that doesn’t automatically synchronize the triggers? We could restart the Function app manually in the portal, since restarts force the synchronization process to occur. That’s a manual process, and we like to avoid those, right? 😄 We want to automate a solution. Thankfully, Azure provides a RESTful solution.

Azure provides two endpoints that can be called to re-synchronize the Function. Behind the scenes, this will update the scale controller, synchronize trigger metadata to the management database, and register notifications for your Function.

The first option is to send an HTTP POST to https://{functionAppName}{masterKey}. Make sure to use the name of your Function and the Master Key associated with it. Note that this is a privileged operation, so it’s important to protect this key using Key Vault, GitHub Secrets, or Azure DevOps Secret Variables.

The second option utilizes ARM and does not require the master key. Instead, it relies on Azure RBAC to ensure the caller has access to make the appropriate call. For this option, send an HTTP POST request to{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{functionAppName}/syncfunctiontriggers?api-version=2021-02-01. You’ll need to replace {subscriptionId}, {resourceGroupName}, and {functionAppName} with appropriate values for your Function. Calling the Sync Function Triggers API will trigger the resynchronization process.

Either of these will allow you to force Azure Functions to synchronize your triggers, enabling your Functions to properly respond to incoming requests. Microsoft provides documentation on key concepts for Azure Functions which provides important details about all of these aspects. Of course, most of the code is available on GitHub if you want to dive even deeper!