{"id":245,"date":"2024-06-12T06:55:30","date_gmt":"2024-06-12T06:55:30","guid":{"rendered":"https:\/\/dotnetconfig.org\/blog\/?p=245"},"modified":"2024-07-01T07:26:49","modified_gmt":"2024-07-01T07:26:49","slug":"managing-net-configuration-settings-in-a-multi-cloud-environment","status":"publish","type":"post","link":"https:\/\/dotnetconfig.org\/blog\/managing-net-configuration-settings-in-a-multi-cloud-environment\/","title":{"rendered":"Managing .NET Configuration Settings in a Multi-Cloud Environment"},"content":{"rendered":"<h3><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-246  alignleft\" src=\"https:\/\/dotnetconfig.org\/blog\/wp-content\/uploads\/2024\/07\/th-29.jpeg\" alt=\"Multi-Cloud Environment\" width=\"422\" height=\"422\" srcset=\"https:\/\/dotnetconfig.org\/blog\/wp-content\/uploads\/2024\/07\/th-29.jpeg 1024w, https:\/\/dotnetconfig.org\/blog\/wp-content\/uploads\/2024\/07\/th-29-300x300.jpeg 300w, https:\/\/dotnetconfig.org\/blog\/wp-content\/uploads\/2024\/07\/th-29-150x150.jpeg 150w, https:\/\/dotnetconfig.org\/blog\/wp-content\/uploads\/2024\/07\/th-29-768x768.jpeg 768w\" sizes=\"auto, (max-width: 422px) 100vw, 422px\" \/><\/h3>\n<h3><b>Leveraging Configuration Management Tools<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">In a multi-cloud environment, effective configuration management is crucial for ensuring that applications remain flexible, scalable, and consistent. Microsoft\u2019s .NET platform provides several tools and practices that simplify this process, helping developers manage configuration settings effectively.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">A popular tool for managing .NET Configuration is Azure App Configuration, though it\u2019s essential to note that it can be integrated into various cloud solutions, including Azure, AWS, and Google Cloud. This tool provides a centralized repository for storing all application settings in a hierarchical structure. By leveraging configuration management tools like Azure App Configuration, teams can achieve uniformity and simplify change management across environments.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For instance, consider the following code example that showcases how to integrate Azure App Configuration in a .NET application:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">public class Program<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public static void Main(string[] args)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var configuration = new ConfigurationBuilder()<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.AddAzureAppConfiguration(options =&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0options.Connect(Environment.GetEnvironmentVariable(&#8220;AZURE_APP_CONFIG_CONNECTION_STRING&#8221;))<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.Select(KeyFilter.Any, LabelFilter.Null);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.Build();<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var host = CreateHostBuilder(args, configuration).Build();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0host.Run();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public static IHostBuilder CreateHostBuilder(string[] args, IConfiguration configuration) =&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Host.CreateDefaultBuilder(args)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.ConfigureAppConfiguration((hostingContext, config) =&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0config.AddConfiguration(configuration);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.ConfigureWebHostDefaults(webBuilder =&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0webBuilder.UseStartup&lt;Startup&gt;();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">This snippet demonstrates how seamless it is to integrate Azure App Configuration, aiding the dynamic retrieval of configuration settings.<\/span><\/p>\n<h3><b>Efficient Handling of Sensitive Information<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">In a multi-cloud environment, securing sensitive configuration information is paramount. Utilizing services like Azure Key Vault or AWS Secrets Manager can significantly bolster your security posture. These services are designed to store secrets, keys, and certificates securely, ensuring that sensitive data such as API keys and connection strings are kept away from prying eyes.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Here is an example demonstrating how to access secrets from Azure Key Vault within a .NET application:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">public class Startup<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public void ConfigureServices(IServiceCollection services)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var builtConfig = new ConfigurationBuilder()<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.AddAzureKeyVault(new Uri(Environment.GetEnvironmentVariable(&#8220;KEY_VAULT_URL&#8221;)), new DefaultAzureCredential())<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.Build();<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0services.Configure&lt;KeyVaultOptions&gt;(builtConfig);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">This code outlines how to configure Azure Key Vault, securing sensitive information and ensuring compliance with data protection regulations.<\/span><\/p>\n<h3><b>Flexible Configuration with Environmental Variables and JSON Files<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">One of the advantages of .NET Configuration is its flexibility in supporting various configuration sources, including JSON files, environmental variables, and command-line arguments. A strategy to maintain flexible configuration is to use a combination of these sources, allowing for environment-specific settings and easy overrides without modifying the codebase.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Typically, appsettings.json and environment-specific JSON files (e.g., appsettings.Development.json) are used for base configurations, while environmental variables are leveraged for values that change frequently or vary by deployment environment.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Here&#8217;s how this setup can be achieved:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8220;Logging&#8221;: {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0&#8220;LogLevel&#8221;: {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;Default&#8221;: &#8220;Information&#8221;,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;Microsoft&#8221;: &#8220;Warning&#8221;,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&#8220;Microsoft.Hosting.Lifetime&#8221;: &#8220;Information&#8221;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0},<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0&#8220;AllowedHosts&#8221;: &#8220;*&#8221;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">An example JSON configuration file.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">public class Program<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public static void Main(string[] args)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var builder = new ConfigurationBuilder()<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.SetBasePath(Directory.GetCurrentDirectory())<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.AddJsonFile(&#8220;appsettings.json&#8221;, optional: false, reloadOnChange: true)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.AddJsonFile($&#8221;appsettings.{Environment.GetEnvironmentVariable(&#8220;ASPNETCORE_ENVIRONMENT&#8221;)}.json&#8221;, optional: true)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.AddEnvironmentVariables();<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0IConfiguration configuration = builder.Build();<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CreateHostBuilder(args, configuration).Build().Run();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public static IHostBuilder CreateHostBuilder(string[] args, IConfiguration configuration) =&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Host.CreateDefaultBuilder(args)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.ConfigureAppConfiguration((hostingContext, config) =&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0config.AddConfiguration(configuration);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.ConfigureWebHostDefaults(webBuilder =&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0webBuilder.UseStartup&lt;Startup&gt;();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Combining multiple configuration sources ensures flexibility and caters to various environments, providing a scalable configuration approach.<\/span><\/p>\n<h3><b>Implementing Version Control for Configuration Files<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">In multi-cloud environments, keeping track of changes across various configuration files can be daunting. Implementing version control mechanisms is a best practice that ensures traceability and allows for rollback capabilities if issues arise.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Using services like Git for version control of configuration files ensures that changes are documented, reviewed, and approved before being deployed. By tagging and branching specifically for configurations, organizations can maintain an audit trail and collaboratively manage changes.<\/span><\/p>\n<h3><b>Dynamic Configuration and Feature Flags<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">Dynamic configuration plays a pivotal role in enabling real-time changes without redeploying applications. Feature flags, also known as feature toggles, allow selective enabling or disabling of functionality. This is especially significant in a multi-cloud environment where changes might need to be tested across different platforms.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">.NET applications can leverage libraries such as Microsoft.FeatureManagement to implement feature flags efficiently:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">public class Startup<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public void ConfigureServices(IServiceCollection services)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0services.AddFeatureManagement();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IFeatureManager featureManager)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (featureManager.IsEnabledAsync(&#8220;NewFeature&#8221;).Result)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseMiddleware&lt;NewFeatureMiddleware&gt;();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Implementing feature flags enhances application agility, allowing for incremental changes, A\/B testing, and blue-green deployments without extensive reconfigurations.<\/span><\/p>\n<h3><b>Centralized Logging and Monitoring<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">Consistent and centralized logging and monitoring are essential for gaining visibility into application performance and issues across multi-cloud deployments. Using platforms like Azure Monitor, AWS CloudWatch, or Google Cloud Operations Suite facilitates centralized log aggregation and monitoring.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Here&#8217;s how to configure centralized logging using Azure Monitor with a .NET application:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">public class Startup<\/span><\/p>\n<p><span style=\"font-weight: 400;\">{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public void ConfigureServices(IServiceCollection services)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0services.AddApplicationInsightsTelemetry(Configuration[&#8220;ApplicationInsights:InstrumentationKey&#8221;]);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0public void Configure(IApplicationBuilder app, IWebHostEnvironment env)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (env.IsDevelopment())<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseDeveloperExceptionPage();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseExceptionHandler(&#8220;\/Home\/Error&#8221;);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseHsts();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseHttpsRedirection();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseStaticFiles();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseRouting();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseAuthorization();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app.UseEndpoints(endpoints =&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0endpoints.MapControllerRoute(<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name: &#8220;default&#8221;,<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pattern: &#8220;{controller=Home}\/{action=Index}\/{id?}&#8221;);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Centralized logging mechanisms provide a unified view and facilitate swift resolution of issues, maintaining application consistency across multiple clouds.<\/span><\/p>\n<h3><b>Automated Deployment Pipelines<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">Automated deployment pipelines streamline the process of pushing configuration changes and application updates across various environments. Utilizing Continuous Integration (CI) and Continuous Deployment (CD) tools like Azure Pipelines, Jenkins, or GitHub Actions ensures that configuration updates are applied consistently and reliably.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Consider a pipeline definition using Azure Pipelines:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">trigger:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">&#8211; main<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">pool:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0vmImage: &#8216;ubuntu-latest&#8217;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">steps:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">&#8211; task: UseDotNet@2<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0inputs:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0packageType: &#8216;sdk&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0version: &#8216;5.x&#8217;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">&#8211; task: DotNetCoreCLI@2<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0inputs:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0command: &#8216;restore&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0projects: &#8216;**\/*.csproj&#8217;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">&#8211; task: DotNetCoreCLI@2<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0inputs:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0command: &#8216;build&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0projects: &#8216;**\/*.csproj&#8217;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">&#8211; task: DotNetCoreCLI@2<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0inputs:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0command: &#8216;publish&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0projects: &#8216;**\/*.csproj&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0arguments: &#8216;&#8211;configuration Release &#8211;output $(Build.ArtifactStagingDirectory)&#8217;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">&#8211; task: CopyFiles@2<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0inputs:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0SourceFolder: &#8216;$(Build.ArtifactStagingDirectory)&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0Contents: &#8216;**&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0TargetFolder: &#8216;$(Build.ArtifactStagingDirectory)&#8217;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">&#8211; task: PublishBuildArtifacts@1<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0inputs:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0pathToPublish: &#8216;$(Build.ArtifactStagingDirectory)&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0artifactName: &#8216;drop&#8217;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0publishLocation: &#8216;Container&#8217;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">Automating deployments ensures coherence and mitigates human error, enhancing the overall reliability of applications.<\/span><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Leveraging Configuration Management Tools In a multi-cloud environment, effective configuration management is crucial for ensuring that applications remain flexible, scalable, and consistent. Microsoft\u2019s .NET platform provides several tools and practices that simplify this process, helping developers manage configuration settings effectively. A popular tool for managing .NET Configuration is Azure App Configuration, though it\u2019s essential to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-245","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/posts\/245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/comments?post=245"}],"version-history":[{"count":1,"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/posts\/245\/revisions"}],"predecessor-version":[{"id":247,"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/posts\/245\/revisions\/247"}],"wp:attachment":[{"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/media?parent=245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/categories?post=245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dotnetconfig.org\/blog\/wp-json\/wp\/v2\/tags?post=245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}