Triggering Azure Functions with Queue messages
TypeScriptAzure Functions is a serverless compute service that enables you to run code on-demand without having to explicitly provision or manage infrastructure. Queue messages are a scalable manner to trigger executions in Azure Functions, with Azure Queue Storage providing the message queueing mechanism. When a message is put into a queue, it can automatically trigger an Azure Function to execute. This is an event-driven architecture that can make your applications more scalable and responsive.
Below is a Pulumi program written in TypeScript that sets up an Azure Function triggered by Azure Queue Storage messages. The program includes comments to help you understand each part of the process.
First, the program creates a storage account and a queue within that account. Then it sets up an Azure Function App, which includes defining the App Service Plan (serverless in this case), the storage connection string, and the function itself, configured to be triggered by the queue we created earlier.
import * as pulumi from "@pulumi/pulumi"; import * as storage from "@pulumi/azure-native/storage"; import * as web from "@pulumi/azure-native/web"; import * as insights from "@pulumi/azure-native/insights"; import * as resources from "@pulumi/azure-native/resources"; // Create an Azure Resource Group const resourceGroup = new resources.ResourceGroup("resourceGroup"); // Create an Azure resource (Storage Account) const storageAccount = new storage.StorageAccount("storageaccount", { resourceGroupName: resourceGroup.name, kind: "StorageV2", sku: { name: "Standard_LRS", }, }); // Create a message queue in the storage account const queue = new storage.Queue("queue", { resourceGroupName: resourceGroup.name, accountName: storageAccount.name, queueName: "functionqueue", }); // Create an Application Insights instance for monitoring const appInsights = new insights.Component("appInsights", { resourceGroupName: resourceGroup.name, kind: "web", applicationType: "web", }); // Create an App Service Plan const appServicePlan = new web.AppServicePlan("appserviceplan", { resourceGroupName: resourceGroup.name, kind: "functionapp", sku: { name: "Y1", // This is the sku for Dynamic (serverless) plans }, }); // Define the Connection String for the Storage Account const storageConnectionString = pulumi.all([resourceGroup.name, storageAccount.name]).apply(([resourceGroupName, accountName]) => storage.listStorageAccountKeys({ resourceGroupName, accountName }).keys[0].value .apply(accountKey => `DefaultEndpointsProtocol=https;AccountName=${accountName};AccountKey=${accountKey};EndpointSuffix=core.windows.net`) ); // Create a Function App const functionApp = new web.WebApp("functionapp", { resourceGroupName: resourceGroup.name, serverFarmId: appServicePlan.id, kind: "functionapp", siteConfig: { appSettings: [ { name: "AzureWebJobsDashboard", value: storageConnectionString }, { name: "AzureWebJobsStorage", value: storageConnectionString }, { name: "FUNCTIONS_EXTENSION_VERSION", value: "~3" }, { name: "FUNCTIONS_WORKER_RUNTIME", value: "dotnet" }, // Assuming you're using .NET runtime { name: "WEBSITE_RUN_FROM_PACKAGE", value: "1" }, // Enables running from a package file { name: "ApplicationInsights:InstrumentationKey", value: appInsights.instrumentationKey }, { name: "WEBSITE_NODE_DEFAULT_VERSION", value: "10.14.1" }, // If using Node.js { name: "MyQueueConnection", // Custom setting to connect to the Azure Queue value: pulumi.interpolate`DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageConnectionString}` }, ], }, siteConfig: { cors: { allowedOrigins: ["https://functions.azure.com", "https://functions-staging.azure.com", "https://functions-next.azure.com"], } }, identity: { type: "SystemAssigned", }, httpsOnly: true, }); // Export the connection string and the endpoint of the Function App export const connectionString = storageConnectionString; export const endpoint = pulumi.interpolate`https://${functionApp.defaultHostName}/api/{functionname}`;
In this script, we create a
resourceGroup
that serves as a logical container for our Azure resources. Then we set up astorageAccount
and aqueue
, where the messages that trigger the function will be stored.An Application Insights resource
appInsights
is provisioned to enable monitoring of the function's executions and performance.The
appServicePlan
defines the hosting model for the function. Azure Functions can run on a Consumption Plan, which is a serverless plan that scales based on demand.The
storageConnectionString
is built from the storage account's access keys; this connection string is necessary for the function to interact with the queue.The
functionApp
resource defines the function itself. Note that you'll need to replace the placeholders for the runtime and other settings based on your specific scenario and the language you're using for your function. For example, if your function code is written in Node.js, use the appropriateFUNCTIONS_WORKER_RUNTIME
value. ThesiteConfig
includes all necessary application settings, including the storage connection strings and the specific runtime settings.To complete this setup, you will also need to deploy the actual function code which is expected to read from the queue and perform actions accordingly. You can deploy the app code using FTP, local Git, GitHub, Bitbucket, or other supported methods. Ensure that the code is deployed to the created function app.
Lastly, the script exports the storage connection string and the endpoint URL for the function app. With these exported values, you can easily interact with your resources and monitor the output of your Azure Functions.