Search code examples
c#amazon-web-services.net-coreamazon-systems-manager

Is it possible to add to IConfiguration after the WebHost has started?


I am using AWS Systems Manager Parameter Store to hold database connection strings which are used to dynamically build a DbContext in my .NET Core Application

I am using the .NET Core AWS configuration provider (from https://aws.amazon.com/blogs/developer/net-core-configuration-provider-for-aws-systems-manager/) which injects my parameters into the IConfiguration at runtime.

At the moment I am having to keep my AWS access key/secret in code so it can be accessed by the ConfigurationBuilder but would like to move this out of the code base and stored it in appsettings or similar.

Here is my method to create the webhost builder called at startup

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
    var webHost = WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();

    AWSCredentials credentials = new BasicAWSCredentials("xxxx", "xxxx");

    AWSOptions options = new AWSOptions()
    {
        Credentials = credentials,
        Region = Amazon.RegionEndpoint.USEast2
    };

    webHost.ConfigureAppConfiguration(config =>
    {
        config.AddJsonFile("appsettings.json");
        config.AddSystemsManager("/ParameterPath", options, reloadAfter: new System.TimeSpan(0, 1, 0)); // Reload every minute
    });

 return webHost;
}

I need to be able to inject the BasicAWSCredentials parameter from somewhere.


Solution

  • You need to access an already built configuration to be able to retrieve the information you seek.

    Consider building one to retrieve the needed credentials that would have been stored in the appsettings file

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) {
        IWebHostBuilder builder = WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
    
        //build configuration 
        IConfiguration configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json") // or where ever the settings are stored
            .Build();
    
        //extract credentials
        string access_key = configuration.GetValue<string>("access_key:path_here");
        string secret_key = configuration.GetValue<string>("secret_key:path_here");
    
        //use credentials as desired
        AWSCredentials credentials = new BasicAWSCredentials(access_key, secret_key);
        
        AWSOptions options = new AWSOptions() {
            Credentials = credentials,
            Region = Amazon.RegionEndpoint.USEast2
        };
    
        builder.ConfigureAppConfiguration(config => {
            config.AddJsonFile("appsettings.json");
            config.AddSystemsManager("/ParameterPath", options, reloadAfter: new System.TimeSpan(0, 1, 0)); // Reload every minute
        });
    
        return builder;
    }
    

    I would also suggest reviewing Configuring AWS Credentials from the docs to use the SDK to find a possible alternative way to storing and retrieving the credentials.