2
votes

I'm currently setting up a multiple publisher/single subscriber architecture, using Azure Storage Queues to buffer events and Azure Functions as the subscriber.

Publisher -> Queue -> Function

Creating the function is no problem, the part I am trying to work out is how to set up a development and a production deployment of the same function. I have created the function in Visual Studio, and the connection is a constant string literal:

public static class FooAdded
{
    [FunctionName("FooAdded")]
    public static void Run([QueueTrigger("tracker-readings", Connection = "https://foo.queue.core.windows.net/?sv=...")]string myQueueItem, TraceWriter log)
    {
        log.Info($"C# Queue trigger function processed: {myQueueItem}");
    }
}

How can I provide a different value for the connection, depending on whether I deploy to the development environment or the live environment?

5

5 Answers

4
votes

To set up local debug environment

You can use local.settings.json file to define the local settings. The prerequisite for using Azure storage locally is that you need to have Azure Storage Emulator running on your machine. In the local.settings.json file define the Azure Storage Account connection string as UseDevelopmentStorage=true. The file should look something like this:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "AzureWebJobsDashboard": "UseDevelopmentStorage=true"
  }
}

By default, if no value is provided for the Connection property of the QueueTrigger attribute, it will use the AzureWebJobsStorage setting:

public static class FooAdded
{
    [FunctionName("FooAdded")]
    public static void Run([QueueTrigger("tracker-readings")]string myQueueItem, TraceWriter log)
    {
        log.Info($"C# Queue trigger function processed: {myQueueItem}");
    }
}

Alternatively, if you want to explicitly specify a connection string, then you can set the Connection to the name of the connection string (not the connection string itself), and add an entry for it in the Values section of the configuration file:

QueueTrigger("tracker-readings", Connection = "CustomConnection")

In the local.settings.json file:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "AzureWebJobsDashboard": "UseDevelopmentStorage=true",
    "CustomConnection": "Some custom connection string"
  }
}

For more details refer to the official documentation:

To set up an Azure environment:

The values in local.settings.json do not get published to Azure, and so a value for each setting needs to be defined in the Azure environment that you are deploying to. Note that the values for AzureWebJobsStorage and AzureWebJobsDashboard are set automatically based off the storage account you choose when creating the function.

The easiest way to define settings is through the Azure portal. Go to Application Settings in the Function App and define the actual value of the storage account connection string. You do not need to make any code changes to the azure function, it will automatically pick up the connection string from application settings.

enter image description here

Alternatively, you can use Azure Resource Manager templates, to deploy and update the environment settings programmatically.

Each function app you create in Azure has its own environment, so after providing values for the relevant settings, you can deploy your function to multiple environments in Azure (Dev/Test/Prod etc.) as well as debug your code locally without changing connection strings everytime.

1
votes

Have the connection string in an environment variable(or an app setting in app services). You can then have the app setting set to to different values in different environments.

0
votes

I am trying to work out is how to set up a development and a production deployment of the same function.

I am not clear why you want to create a function both as production and development.

Actually, Azure billing is based on your app service plan, so you create one more azure function may not cost more. You could create two function to distinguish them more clearly.

If you still want to use a single function, as Travis said, you could set two connection string in app settings for different environment.

0
votes

This is a well known scenario and fully supported. All you need to do manage you deployment with the ARM Template and a Parameter File.

Deploy resources with Resource Manager templates and Azure PowerShell

The connection string, along with any other Sub/Resource Group dependent settings are just parameters.

0
votes

You can set Connection to a config value (something like Connection=AppSettingsKey.DatabaseConnectionString) and then have different settings for different platforms (dev, staging, prod).

Depending on your tooling for build and deployment, you can inject config values for connection strings during one of these steps.

Another option would be to use a Keyvault secret that stores the connection string.