You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+12-8Lines changed: 12 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,9 +7,11 @@ Custom Configuration Providers is a collection of configuration providers for .N
7
7
8
8
### Overview
9
9
10
-
Using this custom configuration provider, you can put AWS Secrets Manager keys into your appsettings files and the values stored in AWS Secrets Manager will be loaded into the config at startup time as if they were in the appsettings file already. What this auto-population of the secret configuration values allow us to do is to leverage the [Options pattern in .Net](https://docs.microsoft.com/en-us/dotnet/core/extensions/options) along with Dependency Injection to automatically load these settings into the classes that need them. In addition, having the settings pre-loaded at startup time means we can eliminate the need to mock an AwsSecretsManager and try to fake the settings at execution time. We can simply use a test version of our appsettings file or in-memory configuration provider with the test values pre-populated and leave AWS Secrets Manager out of our unit tests completely.
10
+
Using this custom configuration provider, you can put AWS Secrets Manager keys into your appsettings files and the values stored in AWS Secrets Manager will be loaded into the config at startup time as if they were in the appsettings file already. Using single AWS secrets keys we can selectively load just the secrets our app needs.
11
11
12
-
So, here are the values in the "/dev/db/options" AWS secret:
12
+
By resolving the secret values are startup allows us to do is to leverage the [Options pattern in .Net](https://docs.microsoft.com/en-us/dotnet/core/extensions/options) along with Dependency Injection to automatically load these settings into the classes that need them, meaning our code can be written in a way that it doesn't care where the settings come from. This simplifies our testing because our unit tests can use an in-memory configuration provider with the test values pre-populated leaving them without the need to mock Secrets Manager or make connections from our CI/CD pipeline to a test instance of Secrets Manager.
13
+
14
+
So, here is an example of some values stored in the "/dev/db/options" key of our AWS Secrets Manager instance:
13
15
14
16
```json
15
17
{
@@ -21,7 +23,7 @@ So, here are the values in the "/dev/db/options" AWS secret:
21
23
}
22
24
```
23
25
24
-
Here are the appsettings:
26
+
Here are our appsettings:
25
27
26
28
```json
27
29
{
@@ -31,7 +33,7 @@ Here are the appsettings:
31
33
}
32
34
```
33
35
34
-
Here is what our IConfiguration values look like before and after we call .AddAwsSecretsManager:
36
+
Here is what our IConfiguration values look like before and after we call .AddAwsSecretsManager, specifying "AwsSecret" as our placeholder key:
35
37
36
38
| IConfiguration before | IConfiguration after |
37
39
|---|---|
@@ -43,7 +45,9 @@ Here is what our IConfiguration values look like before and after we call .AddAw
43
45
44
46
### How it works
45
47
46
-
Add the provider along with an AwsSecretsManager client (this is to allow for injecting mock versions or other versions of the client) and the name of the placeholder key you chose to put in your appsettings (e.g. "AwsSecret"):
48
+
Custom configuration providers work as extension methods for ConfigurationBuilder. As long as the custom provider is included in your source and it's namespace is in your "using" statements, you should be able to just call ".AddAwsSecretsManager(...)".
49
+
50
+
In your app's startup code, add the provider to your configuration builder along with an AwsSecretsManager client (this is to allow for injecting mock versions or other versions of the client) and the name of the placeholder key you chose to put in your appsettings (e.g. "AwsSecret"):
@@ -61,7 +65,7 @@ Add the provider along with an AwsSecretsManager client (this is to allow for in
61
65
> * We're supplying an AmazonSecretsManagerClient to simplify testing and to choose the region in our app startup.
62
66
> * In `AddAwsSecretsManager()` we're specifying the placeholder key to search and replace (e.g. "AwsSecret") with AWS Secrets Manager values. You can choose whatever string you want.
63
67
64
-
When you build the config builder, the custom configuration provider will look in the appsettings files you've loaded for the placeholder key you specified (e.g. "AwsSecret") take it's value "/dev/db/options" and replace the value with the values retrieved from AWS Secrets Manager (i.e. in the IConfiguration tree in memory, not the appsettings file) like so:
68
+
When you call "Build" on the config builder, the custom configuration provider will look in the appsettings files you've loaded for the placeholder key you specified (e.g. "AwsSecret") take it's value "/dev/db/options" and replace the value with the values retrieved from AWS Secrets Manager (i.e. in the IConfiguration tree in memory, not the appsettings file) like so:
65
69
66
70
| IConfiguration before | IConfiguration after |
67
71
|---|---|
@@ -90,7 +94,7 @@ public class DatabaseOptions
90
94
91
95
> Note:
92
96
>
93
-
> Since AWS Secrets Manager stores key-value pairs as <string,string> options classes should contain strings. It is possible to add code to the Configuration Provider that parses the JSON into proper types, but it complicates the code that I think has more cost than benefit.
97
+
> Since AWS Secrets Manager stores key-value pairs as <string,string> options classes should contain strings. It is possible to add code to the Configuration Provider that parses the JSON into proper types, but it complicates the code in a way that I think has more cost than benefit. Simpler to treat them as strings and convert them to the needed types by the classes that consume them.
94
98
95
99
#### Inject them into a Dependency Injection collection
96
100
@@ -144,7 +148,7 @@ public DependencyInjectionMockUnitTests()
0 commit comments