Vivendi
Vivendi

Reputation: 21027

Where to store Azure ConnectionString in Azure Functions app

I made an Azure Functions app that connects to a CosmosDB. I made the following class to retrieve a CosmosClient instance:

public static class CosmosClientContext
{
    private static readonly CosmosClient CosmosClient = GetCosmosClient();

    public static CosmosClient GetCosmosClient()
    {
        return CosmosClient
               //?? new CosmosClient("AccountEndpoint=https://mycosmosdb.documents.azure.com:443/;AccountKey=JkLv....etc;");
               ?? new CosmosClient("AccountEndpoint=https://localhost:8081/;AccountKey=C2y6...etc");
    }
}

So as you can see I'm currently hard coding the ConnectionString in the class, which is obviously not optimal.

I noticed that I have a local.settings.json file in my project. Is that the place to store to local connection string in? And if so, do I have to use a specific key name for this? Or how do I read from it?

And how does this then work when I publish my Azure Functions app?

So how can I make it so that it locally uses my local ConnectionString, and when published it automatically uses the remote ConnectionString?

Upvotes: 0

Views: 773

Answers (2)

Noah Stahl
Noah Stahl

Reputation: 7563

If you prefer to access configuration in the idiomatic ASP.NET Core manner with dependency injection, you can use a Startup.cs that looks something like the below. The values are stored in local.settings.json or in hosted App Settings.

[assembly: FunctionsStartup(typeof(MyApp.Functions.Startup))]

namespace MyApp.Functions
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            IServiceCollection services = builder.Services;

            // Read configuration
            var config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddEnvironmentVariables().Build();

            // Pass configuration values to a custom IServiceCollection extension
            services.AddCosmosDb(new CosmosDbOptions
            {
                ConnectionString = config["CosmosDb:ConnectionString"],
                DatabaseId = config["CosmosDb:DatabaseId"]
            });

            // Configuration access
            services.Configure<AzureStorageOptions>(config.GetSection("AzureStorage"));

            // Other setup, add more things to services, etc 
            services.AddMemoryCache();
        }
    }
}

Then in any function, you can constructor-inject any services configured at Startup, including your Cosmos service instance.

Upvotes: 2

Bryan Lewis
Bryan Lewis

Reputation: 5977

You store these as environment variables. Locally these will be in the local.settings.json and on Azure they will be in the Application Settings tab under the Configuration blade of your function app in the Azure Portal.

The name of your variable is arbitrary. Your local.settings.json will look something like this:

{
    "IsEncrypted": false,
    "Values": {
        "CosmosDbConnectionString": "[CONNECTION STRING HERE]"
        "FUNCTIONS_WORKER_RUNTIME": "dotnet"
    }
}

Be sure it goes inside of the "Values" section. The you simply access it using the GetEnvironmentVariable method:

Environment.GetEnvironmentVariable("CosmosDbConnectionString");

So something like:

return new CosmosClient(Environment.GetEnvironmentVariable("CosmosDbConnectionString"));

You don't need any sort of logic to switch between dev and prod. Since the environment variables are different if each place, it will automatically pick up the correct connection string.

Note, in the Portal, make sure you use the "Application Settings" section and NOT the "Connection Strings" section. It's confusing, but the Connections String section is only used for Entity Framework on Functions.enter image description here

Upvotes: 3

Related Questions