Azure App Configuration and Key Vault
In the pre-cloud era, application configuration data was often stored in traditional ways, such as config files, databases, environment variables, and text files. All these options have pitfalls. For example, it could be the need for redeploying the entire application, difficulties in sharing configurations across different applications, security vulnerabilities and breaches, etc.
With the emergence of Microsoft Azure, developers can leverage powerful tools such as Azure App Configuration and Azure Key Vault Service to better manage and store application configuration settings. These services help avoid hard-coding configurations, improve security, and enable easy configuration sharing, and so on. However, there are also essential nuances that we’ll discuss in more detail.
In this article, we’ll take a closer look at Azure Application Configuration and Azure Key Vault Service, analyze their implementation and usage, and explore their benefits.
External Configuration Store Pattern
As we mentioned earlier, most application runtime environments store configuration info in local files deployed with the app. Any changes in the configuration require re-deployment of the program, leading to additional costs in time, money, and downtime. Managing local configuration changes across multiple running instances of the application is also very difficult.
Additionally, in modern app development, sharing configuration settings across multiple applications could be very helpful. These can be queue URLs, database connection strings, etc.
What is the idea of the External Configuration Store pattern?
The External Configuration Store pattern is a design pattern you can use in Azure to manage application configuration settings. Its main idea is to store configuration settings in an external location rather than hard-coding them into the app.
Basically, it looks like this:
- Move configuration info from the app deployment package to a centralized location for easier data management and control and for sharing configuration data between applications and app instances.
- Separate configuration from code.
- Use the opportunities to simplify configuration settings management and updating (especially convenient when multiple application instances run in different environments). Do not forget about a proper interface for consistent and easy-to-use access.
In the case of a cloud-hosted scenario, you can use a cloud storage service, a hosted database, or a custom system. A backing store interface should provide information in a structured and proper format, so taking care of this is essential. The pattern also includes access authorization to protect configuration data, which we will also talk about later.
What to pay attention to?
- Backing store performance, reliability, and availability.
- Provision of all configuration requirements by backing store, flexibility in the types of information it can store.
- Scope control capabilities and configuration parameter inheritance. Ability to provide configuration data in required formats such as property bags, typed values, key/value pairs, etc.
- Protect configuration data, access only to appropriate users and applications, and strict separation of permissions required to access and change configuration data.
- Application code deployment mechanisms must match mechanisms for deploying, updating, and managing centrally stored configurations.
In cases when the app caches configuration information, it is worth taking care of the configuration change alerts, info periodically updating and refreshing, and recording of any changes.
First of all, you can use the External Configuration Store pattern when there is a need to share configuration parameters between multiple app instances or applications. It can also be useful when the standard configuration system doesn’t support all needed configuration options. In this case, the pattern helps configure the storage of complex data types, provides an additional store for some app settings, etc.
In addition, it should be used when it is necessary to monitor the use and access to configuration options and ensure that all access types are logged.
Azure App Configuration
Most modern programs consist of many components that are distributed in nature. Sharing configuration settings between them could be tricky or lead to errors, and eliminating them during deployment takes a lot of work.
Azure App Configuration is a way to get an independent store of app configuration settings for centralized management. It’s not tied to apps or integration platforms, just Azure. With Azure App Configuration, you can simplify the process of access control, deployment, reconfiguration created by multiple applications, etc. This service supports various platforms and programming languages, making it easy to use for developers.
Benefits of Azure App Configuration
One of the key points in using the External Configuration Store pattern, and Azure App Configuration in particular, is to separate the configuration from the code. This allows configuration settings to be left outside the program’s executable, reading them from its runtime/external source.
Let’s take a look at other benefits:
- Application features availability control in real-time.
- Fully managed service, easy and quick to set up.
- Convenient UI for managing function flags and flexible key mappings.
- Improved security by using Azure-managed identifiers.
- The possibility of native integration with common frameworks, as well as integration with Azure Key Vault.
- Ability to dynamically change program settings without re-deploying or restarting, during the application runtime.
And, of course, Azure App Configuration allows centralizing management and distribution of configuration data for various environments.
Although various types of applications can utilize Azure App Configuration, the following specific examples illustrate how the service can be particularly advantageous for certain scenarios:
- Microservices applications – containerized apps on the Kubernetes cluster.
- Serverless/Stateless apps – Azure Functions.
- Logically related application groups.
- CI/CD scenarios.
So, as you can see, this is a suitable solution for various app types and development scenarios.
Azure App Configuration key values
Azure App Configuration provides support for storing key-value pairs, where the values are simple Unicode strings. They are case-sensitive, and each key-value pair can have a maximum size of 10KB, including all metadata.
Each value can be specified through a content type attribute, providing flexibility in managing different types of configuration data. Thanks to this, Azure App Configuration offers a simple, flexible, and powerful mechanism for storing and retrieving application configuration data.
Azure App Configuration label keys
Very often, applications may require different configurations for different environments. Developers can use labels for fast filtering, differentiation, and searching for the necessary keys. They’re also useful for key logical separation. One key can have several different labels in an arbitrary string with different values, and this approach allows more flexible work with key-value pairs.
Azure App Configuration can be used for each environment separately or be common and shared across them. In the second case, the labels allow you to find the keys you need quickly. They will also be useful when there are two applications (web and Azure Function, for example). In this case, labels help get settings for a specific resource type and result.
Azure App Configuration feature management
This is a software-development practice that decouples feature release from code deployment and helps control the state of the application business features and dynamically administer their lifecycles. Let’s take a look at three basic concepts:
- Feature Flag (feature switches or feature toggles). This is a binary state variable to enable/disable the feature. You can store all flags in Azure App Configuration and administer them from one place. Features flags can be manipulated during the runtime.
- Features Manager. It is a package designed specifically for feature flags: for handling their lifecycle in the application and updating or caching their states.
- Filter. This is a rule for evaluating the state of a feature flag, which can include device types, user groups, geographic data, time windows, etc.
This is an incredibly practical feature that has many different use cases. You can use feature flags to manage availability without redeploying code and rebuilding the app. You also have the ability to use different types of filters:
- feature filters out of the box (created for common scenarios like targeted stage feature rollout);
- custom feature filters for specific conditional processing.
For example, feature flags and filters allow to enable a specific functionality only for some percentage of users (and increase this percentage gradually), users of a particular browser, or those in a specific location. You can also use it to conditionally display content or guard controller action baked in the library.
Azure Key Vault
Azure Key Vault is a service that allows you to securely store and manage your applications’ cryptographic keys, certificates, and secrets. It provides a centralized location for secrets instead of storing them in the application code, configuration files, or source control.
It helps to reduce the risk of exposing sensitive data and simplifies secrets management for applications. Azure Key Vault also integrates with other Azure services, cloud providers, and on-premises systems.
Azure App Configuration and Azure Key Vault are both designed to work together. You can use them in combination to provide a complete solution for securely managing application configuration and secrets.
App Configuration Key Vault Reference
Azure App Configuration provides a feature called Key Vault Reference. This powerful tool allows developers to reference values stored in Azure Key Vault from their application’s configuration.
The Key Vault Reference contains a URI pointing to the Key Vault secret but not the actual secret value. From the application’s perspective, it still works with the App Configuration provider, and the reference enables a secure and flexible approach to managing sensitive configuration data.
One of the main benefits of using Azure App Configuration Key Vault Reference is that it enables centralized management of secrets in Azure Key Vault while still allowing the application to work with the App Configuration provider. However, it is essential to note that the application must authenticate separately to both the App Configuration and Key Vault services.
Let’s take a look at the image below. The web app authenticates to Key Vault and App Configuration separately. In the first case, we can use Azure Active Directory for this; in the second – a connection string or managed identity.
Azure AD has many limitations, which could be a problem. Managed identity helps solve this issue by providing the opportunity to obtain Azure AD tokens and eliminating the need to manage credentials. You can use it to authenticate to any resources protected by Azure AD.
Managed Identity Types
Tied to the application (created as a part of resource), and it can have only one system-assigned identity that can’t be shared.
As the service principal is tied to the Azure resource lifecycle, when it is deleted, the system automatically deletes the managed identity.
You can authorize managed identity to get access to one or more services.
- when workloads require independent identities (programs that run on a single virtual machine);
- when workloads contain within a single resource.
Stand-alone resource with an independent lifecycle, the application can have multiple user-assigned identities.
You manage the service principal independently from the resource; when deleting the resource, you have to delete managed identity as well.
You can authorize managed identity to get access to one or more services.
- when you need to set up pre-authorization to a secure Azure resource;
- when workloads run on multiple resources;
- when resources are recycled frequently but with consistent permissions (multiple virtual machines access the same Azure resource).
Pay attention: system-assigned managed identity represents one particular resource, so when setting up Azure Key Vault authentication, we have to provide access to the object ID of this resource, which, in turn, represents the application.
How to Consume App Configuration and Key Vault
Configuration Provider for .Net
- Out of the box .Net core configuration provider’s pipeline;
- Use it when need basic read settings or secrets capabilities;
- Can be used with minimal code changes.
Azure SDK for .Net
- Use specific library client classes, different libraries for Key Vault, App Configuration, etc;
- Use it when you need full access to service features and capabilities;
- Some code changes may be required to start using it.
Configuration Provider for .Net is a much simpler option. You just need to connect it to Program.cs, and you get access to its capabilities. Azure SDK for .NET provides full access to all services’ features and capabilities (create, delete, get info about the last modification date, etc.).
Connect to Azure App Configuration ASP.Net Core
AddAzureAppConfiguration – extension method, adds Azure App Configuration as an extra configuration source.
options.Connect – here, we indicate where we connect, create an endpoint ([“AppConfoguration:Endpoint”]).
new DefaultAzureCredential() – managed identity.
SetSecretRefreshInterval() – a save mechanism in case something does not work, loads all strings into the cache -> cleans the cache -> loads new changes at certain intervals.
ConfigureRefresh – uses the sentinel key to monitor key value at a specific time interval, in case of changes, refreshes all.
A sentinel key is a key that you update after all other key changes.
The app monitors the sentinel key. When a change is detected, your app refreshes all configuration values. Reduces the overall number of requests made to the App Configuration store.
Azure App Configuration Local Development
There is no local emulator for Azure App Configuration, and it might not be possible to use it locally when Azure App Configuration has Key Vault references (Key Vault requires authentication).
But there is an exception: it is possible to use it on a local machine if you use a connection string and the App Configuration does not have Key Vault references.
Standard config files appsettings.json/appsettings.Development.json can substitute App Configuration locally.
Secrets.json can substitute Key Vault secrets when developing locally for storing sensitive information.
As you can see, Azure App Configuration and Key Vault are complementary services that are used side by side in most application deployments. The External Configuration Store pattern helps store configuration parameters in an external location instead of hard-coding them into the application.
App Configuration helps you use services together by creating keys that reference values stored in Key Vault (stores the URIs of the Key Vault values, not the values themselves). Your application is responsible for proper authentication in your App Configuration and Key Vault. The two services do not communicate directly. Thanks to all these things, you can provide additional security layers.
Azure Key Vault is a powerful solution for securely managing applications and services’ cryptographic keys, secrets, and certificates. By centralizing the management of sensitive information, you have a better chance of avoiding the pitfalls of hard-coding secrets and reducing the risk of accidental disclosure. It also integrates with other Azure services, such as Azure App Service and Azure Functions, which simplify the management of secrets in cloud applications.
Azure App Configuration also has unconditional benefits, including the ability to control application feature availability in real-time, improved security, simple and fast configuration, and centralized management and distribution of configuration data across environments. This can be especially useful for microservices applications, serverless/stateless apps, logically related groups of applications, and CI/CD scenarios.