Skip to content

Commit 5a0e590

Browse files
committed
Merge branch 'main' of https://github.com/MicrosoftDocs/azure-docs-pr into networkover
2 parents f33ea2b + 04a79c2 commit 5a0e590

10 files changed

+433
-439
lines changed

articles/azure-app-configuration/enable-dynamic-configuration-aspnet-core.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ A *sentinel key* is a key that you update after you complete the change of all o
3939

4040
1. Open *Program.cs*, and update the `AddAzureAppConfiguration` method you added previously during the quickstart.
4141

42-
#### [.NET 6.x](#tab/core6x)
42+
#### [.NET 6.0+](#tab/core6x)
4343
```csharp
4444
// Load configuration from Azure App Configuration
4545
builder.Configuration.AddAzureAppConfiguration(options =>
@@ -91,7 +91,7 @@ A *sentinel key* is a key that you update after you complete the change of all o
9191

9292
1. Add Azure App Configuration middleware to the service collection of your app.
9393

94-
#### [.NET 6.x](#tab/core6x)
94+
#### [.NET 6.0+](#tab/core6x)
9595
Update *Program.cs* with the following code.
9696

9797
```csharp
@@ -131,7 +131,7 @@ A *sentinel key* is a key that you update after you complete the change of all o
131131

132132
1. Call the `UseAzureAppConfiguration` method. It enables your app to use the App Configuration middleware to update the configuration for you automatically.
133133

134-
#### [.NET 6.x](#tab/core6x)
134+
#### [.NET 6.0+](#tab/core6x)
135135
Update *Program.cs* withe the following code.
136136

137137
```csharp

articles/azure-app-configuration/enable-dynamic-configuration-dotnet-core.md

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
2-
title: "Tutorial: Use dynamic configuration in a .NET Core app"
2+
title: "Tutorial: Use dynamic configuration in a .NET app"
33
titleSuffix: Azure App Configuration
4-
description: In this tutorial, you learn how to dynamically update the configuration data for .NET Core apps
4+
description: In this tutorial, you learn how to dynamically update the configuration data for .NET apps
55
services: azure-app-configuration
66
documentationcenter: ''
77
author: mcleanbyron
@@ -14,31 +14,70 @@ ms.workload: tbd
1414
ms.devlang: csharp
1515
ms.custom: devx-track-csharp, devx-track-dotnet
1616
ms.topic: tutorial
17-
ms.date: 07/01/2019
17+
ms.date: 07/11/2023
1818
ms.author: mcleans
1919
#Customer intent: I want to dynamically update my app to use the latest configuration data in App Configuration.
2020
---
21-
# Tutorial: Use dynamic configuration in a .NET Core app
21+
# Tutorial: Use dynamic configuration in a .NET app
2222

23-
The App Configuration .NET provider library supports updating configuration on demand without causing an application to restart. This tutorial shows how you can implement dynamic configuration updates in your code. It builds on the app introduced in the quickstart. You should finish [Create a .NET Core app with App Configuration](./quickstart-dotnet-core-app.md) before continuing.
23+
The App Configuration .NET provider library supports updating configuration on demand without causing an application to restart. This tutorial shows how you can implement dynamic configuration updates in your code. It builds on the app introduced in the quickstart. You should finish [Create a .NET app with App Configuration](./quickstart-dotnet-core-app.md) before continuing.
2424

2525
You can use any code editor to do the steps in this tutorial. [Visual Studio Code](https://code.visualstudio.com/) is an excellent option that's available on the Windows, macOS, and Linux platforms.
2626

2727
In this tutorial, you learn how to:
2828

2929
> [!div class="checklist"]
30-
> * Set up your .NET Core app to update its configuration in response to changes in an App Configuration store.
30+
> * Set up your .NET app to update its configuration in response to changes in an App Configuration store.
3131
> * Consume the latest configuration in your application.
3232
3333
## Prerequisites
3434

3535
[!INCLUDE [quickstarts-free-trial-note](../../includes/quickstarts-free-trial-note.md)]
3636

37-
Finish the quickstart [Create a .NET Core app with App Configuration](./quickstart-dotnet-core-app.md).
37+
Finish the quickstart [Create a .NET app with App Configuration](./quickstart-dotnet-core-app.md).
3838

3939
## Activity-driven configuration refresh
4040

41-
Open *Program.cs* and update the code as following.
41+
Open the `Program.cs` file and update the code configurations to match the following:
42+
43+
### [ASP.NET Core 6.0+](#tab/core6x)
44+
45+
```csharp
46+
using Microsoft.Extensions.Configuration;
47+
using Microsoft.Extensions.Configuration.AzureAppConfiguration;
48+
49+
IConfiguration _configuration = null;
50+
IConfigurationRefresher _refresher = null;
51+
52+
var builder = new ConfigurationBuilder();
53+
builder.AddAzureAppConfiguration(options =>
54+
{
55+
options.Connect(Environment.GetEnvironmentVariable("ConnectionString"))
56+
.ConfigureRefresh(refresh =>
57+
{
58+
refresh.Register("TestApp:Settings:Message")
59+
.SetCacheExpiration(TimeSpan.FromSeconds(10));
60+
});
61+
62+
_refresher = options.GetRefresher();
63+
});
64+
65+
_configuration = builder.Build();
66+
67+
Console.WriteLine(_configuration["TestApp:Settings:Message"] ?? "Hello world!");
68+
69+
// Wait for the user to press Enter
70+
Console.ReadLine();
71+
72+
if (_refresher != null)
73+
{
74+
await _refresher.TryRefreshAsync();
75+
Console.WriteLine(_configuration["TestApp:Settings:Message"] ?? "Hello world!");
76+
77+
}
78+
```
79+
80+
### [ASP.NET Core 3.x](#tab/core3x)
4281

4382
```csharp
4483
using Microsoft.Extensions.Configuration;
@@ -85,10 +124,11 @@ namespace TestConsole
85124
}
86125
}
87126
```
127+
---
88128

89129
In the `ConfigureRefresh` method, a key within your App Configuration store is registered for change monitoring. The `Register` method has an optional boolean parameter `refreshAll` that can be used to indicate whether all configuration values should be refreshed if the registered key changes. In this example, only the key *TestApp:Settings:Message* will be refreshed. The `SetCacheExpiration` method specifies the minimum time that must elapse before a new request is made to App Configuration to check for any configuration changes. In this example, you override the default expiration time of 30 seconds, specifying a time of 10 seconds instead for demonstration purposes.
90130

91-
Calling the `ConfigureRefresh` method alone won't cause the configuration to refresh automatically. You call the `TryRefreshAsync` method from the interface `IConfigurationRefresher` to trigger a refresh. This design is to avoid phantom requests sent to App Configuration even when your application is idle. You will want to include the `TryRefreshAsync` call where you consider your application active. For example, it can be when you process an incoming message, an order, or an iteration of a complex task. It can also be in a timer if your application is active all the time. In this example, you call `TryRefreshAsync` every time you press the Enter key. Note that, even if the call `TryRefreshAsync` fails for any reason, your application will continue to use the cached configuration. Another attempt will be made when the configured cache expiration time has passed and the `TryRefreshAsync` call is triggered by your application activity again. Calling `TryRefreshAsync` is a no-op before the configured cache expiration time elapses, so its performance impact is minimal, even if it's called frequently.
131+
Calling the `ConfigureRefresh` method alone won't cause the configuration to refresh automatically. You call the `TryRefreshAsync` method from the interface `IConfigurationRefresher` to trigger a refresh. This design is to avoid phantom requests sent to App Configuration even when your application is idle. You'll want to include the `TryRefreshAsync` call where you consider your application active. For example, it can be when you process an incoming message, an order, or an iteration of a complex task. It can also be in a timer if your application is active all the time. In this example, you call `TryRefreshAsync` every time you press the Enter key. Even if the call `TryRefreshAsync` fails for any reason, your application continues to use the cached configuration. Another attempt is made when the configured cache expiration time has passed and the `TryRefreshAsync` call is triggered by your application activity again. Calling `TryRefreshAsync` is a no-op before the configured cache expiration time elapses, so its performance impact is minimal, even if it's called frequently.
92132

93133
## Build and run the app locally
94134

@@ -186,7 +226,7 @@ Logs are output upon configuration refresh and contain detailed information on k
186226

187227
## Next steps
188228

189-
In this tutorial, you enabled your .NET Core app to dynamically refresh configuration settings from App Configuration. To learn how to use an Azure managed identity to streamline the access to App Configuration, continue to the next tutorial.
229+
In this tutorial, you enabled your .NET app to dynamically refresh configuration settings from App Configuration. To learn how to use an Azure managed identity to streamline the access to App Configuration, continue to the next tutorial.
190230

191231
> [!div class="nextstepaction"]
192232
> [Managed identity integration](./howto-integrate-azure-managed-service-identity.md)

articles/azure-app-configuration/howto-integrate-azure-managed-service-identity.md

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ ms.author: mcleans
77
ms.service: azure-app-configuration
88
ms.custom: devx-track-csharp, fasttrack-edit, subject-rbac-steps, devdivchpfy22
99
ms.topic: conceptual
10-
ms.date: 08/23/2022
10+
ms.date: 07/11/2023
1111
zone_pivot_groups: appconfig-provider
1212
---
1313
# Use managed identities to access App Configuration
1414

1515
Azure Active Directory [managed identities](../active-directory/managed-identities-azure-resources/overview.md) simplify secrets management for your cloud application. With a managed identity, your code can use the service principal created for the Azure service it runs on. You use a managed identity instead of a separate credential stored in Azure Key Vault or a local connection string.
1616

17-
Azure App Configuration and its .NET Core, .NET Framework, and Java Spring client libraries have managed identity support built into them. Although you aren't required to use it, the managed identity eliminates the need for an access token that contains secrets. Your code can access the App Configuration store using only the service endpoint. You can embed this URL in your code directly without exposing any secret.
17+
Azure App Configuration and its .NET, .NET Framework, and Java Spring client libraries have managed identity support built into them. Although you aren't required to use it, the managed identity eliminates the need for an access token that contains secrets. Your code can access the App Configuration store using only the service endpoint. You can embed this URL in your code directly without exposing any secret.
1818

1919
:::zone target="docs" pivot="framework-dotnet"
2020

@@ -45,7 +45,7 @@ To complete this tutorial, you must have:
4545

4646
:::zone target="docs" pivot="framework-dotnet"
4747

48-
* [.NET Core SDK](https://dotnet.microsoft.com/download).
48+
* [.NET SDK](https://dotnet.microsoft.com/download).
4949
* [Azure Cloud Shell configured](../cloud-shell/quickstart.md).
5050

5151
:::zone-end
@@ -128,24 +128,17 @@ The following steps describe how to assign the App Configuration Data Reader rol
128128
using Azure.Identity;
129129
```
130130

131-
1. If you wish to access only values stored directly in App Configuration, update the `CreateWebHostBuilder` method by replacing the `config.AddAzureAppConfiguration()` method (this method is found in the `Microsoft.Azure.AppConfiguration.AspNetCore` package).
131+
1. To access values stored in App Configuration, update the `Builder` configuration to use the the `AddAzureAppConfiguration()` method.
132132
133-
> [!IMPORTANT]
134-
> `CreateHostBuilder` replaces `CreateWebHostBuilder` in .NET Core 3.0. Select the correct syntax based on your environment.
135-
136-
### [.NET Core 5.x](#tab/core5x)
133+
### [.NET 6.0+](#tab/core6x)
137134
138135
```csharp
139-
public static IHostBuilder CreateHostBuilder(string[] args) =>
140-
Host.CreateDefaultBuilder(args)
141-
.ConfigureWebHostDefaults(webBuilder =>
142-
webBuilder.ConfigureAppConfiguration((hostingContext, config) =>
143-
{
144-
var settings = config.Build();
145-
config.AddAzureAppConfiguration(options =>
146-
options.Connect(new Uri(settings["AppConfig:Endpoint"]), new ManagedIdentityCredential()));
147-
})
148-
.UseStartup<Startup>());
136+
var builder = WebApplication.CreateBuilder(args);
137+
138+
builder.Configuration.AddAzureAppConfiguration(options =>
139+
options.Connect(
140+
new Uri(builder.Configuration["AppConfig:Endpoint"]),
141+
new ManagedIdentityCredential()));
149142
```
150143
151144
### [.NET Core 3.x](#tab/core3x)
@@ -163,29 +156,12 @@ The following steps describe how to assign the App Configuration Data Reader rol
163156
.UseStartup<Startup>());
164157
```
165158
166-
### [.NET Core 2.x](#tab/core2x)
167-
168-
```csharp
169-
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
170-
WebHost.CreateDefaultBuilder(args)
171-
.ConfigureAppConfiguration((hostingContext, config) =>
172-
{
173-
var settings = config.Build();
174-
config.AddAzureAppConfiguration(options =>
175-
options.Connect(new Uri(settings["AppConfig:Endpoint"]), new ManagedIdentityCredential()));
176-
})
177-
.UseStartup<Startup>();
178-
```
179-
180159
---
181160
182161
> [!NOTE]
183162
> If you want to use a **user-assigned managed identity**, be sure to specify the `clientId` when creating the [ManagedIdentityCredential](/dotnet/api/azure.identity.managedidentitycredential).
184163
>```csharp
185-
>config.AddAzureAppConfiguration(options =>
186-
> {
187-
> options.Connect(new Uri(settings["AppConfig:Endpoint"]), new ManagedIdentityCredential("<your_clientId>"))
188-
> });
164+
>new ManagedIdentityCredential("<your_clientId>")
189165
>```
190166
>As explained in the [Managed Identities for Azure resources FAQs](../active-directory/managed-identities-azure-resources/known-issues.md), there is a default way to resolve which managed identity is used. In this case, the Azure Identity library enforces you to specify the desired identity to avoid possible runtime issues in the future. For instance, if a new user-assigned managed identity is added or if the system-assigned managed identity is enabled. So, you will need to specify the `clientId` even if only one user-assigned managed identity is defined, and there is no system-assigned managed identity.
191167

articles/azure-app-configuration/howto-labels-aspnet-core.md

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ ms.devlang: csharp
77
author: mcleanbyron
88
ms.topic: conceptual
99
ms.custom: devx-track-csharp
10-
ms.date: 3/12/2020
10+
ms.date: 07/11/2023
1111
ms.author: mcleans
1212

1313
---
@@ -42,28 +42,22 @@ using Microsoft.Extensions.Configuration.AzureAppConfiguration;
4242

4343
Load configuration values with the label corresponding to the current environment by passing the environment name into the `Select` method:
4444

45-
### [.NET Core 5.x](#tab/core5x)
45+
### [ASP.NET Core 6.0+](#tab/core6x)
4646

4747
```csharp
48-
public static IHostBuilder CreateHostBuilder(string[] args) =>
49-
Host.CreateDefaultBuilder(args)
50-
.ConfigureWebHostDefaults(webBuilder =>
51-
webBuilder.ConfigureAppConfiguration((hostingContext, config) =>
52-
{
53-
var settings = config.Build();
54-
config.AddAzureAppConfiguration(options =>
55-
options
56-
.Connect(settings.GetConnectionString("AppConfig"))
57-
// Load configuration values with no label
58-
.Select(KeyFilter.Any, LabelFilter.Null)
59-
// Override with any configuration values specific to current hosting env
60-
.Select(KeyFilter.Any, hostingContext.HostingEnvironment.EnvironmentName)
61-
);
62-
})
63-
.UseStartup<Startup>());
48+
var builder = WebApplication.CreateBuilder(args);
49+
50+
builder.Configuration.AddAzureAppConfiguration(options =>
51+
{
52+
options.Connect(builder.Configuration.GetConnectionString("AppConfig"))
53+
// Load configuration values with no label
54+
.Select(KeyFilter.Any, LabelFilter.Null)
55+
// Override with any configuration values specific to current hosting env
56+
.Select(KeyFilter.Any, builder.Environment.EnvironmentName);
57+
});
6458
```
6559

66-
### [.NET Core 3.x](#tab/core3x)
60+
### [ASP.NET Core 3.x](#tab/core3x)
6761

6862
```csharp
6963
public static IHostBuilder CreateHostBuilder(string[] args) =>
@@ -84,28 +78,8 @@ Load configuration values with the label corresponding to the current environmen
8478
.UseStartup<Startup>());
8579
```
8680

87-
### [.NET Core 2.x](#tab/core2x)
88-
89-
```csharp
90-
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
91-
WebHost.CreateDefaultBuilder(args)
92-
.ConfigureAppConfiguration((hostingContext, config) =>
93-
{
94-
var settings = config.Build();
95-
config.AddAzureAppConfiguration(options =>
96-
options
97-
.Connect(settings.GetConnectionString("AppConfig"))
98-
// Load configuration values with no label
99-
.Select(KeyFilter.Any, LabelFilter.Null)
100-
// Override with any configuration values specific to current hosting env
101-
.Select(KeyFilter.Any, hostingContext.HostingEnvironment.EnvironmentName)
102-
);
103-
})
104-
.UseStartup<Startup>();
105-
```
10681
---
10782

108-
10983
> [!IMPORTANT]
11084
> The preceding code snippet uses the Secret Manager tool to load App Configuration connection string. For information storing the connection string using the Secret Manager, see [Quickstart for Azure App Configuration with ASP.NET Core](quickstart-aspnet-core-app.md).
11185

0 commit comments

Comments
 (0)