3

In my CreateWebHostBuilder() method I've added the AWS Systems Manager Parameter Store as an additional source for Configuration Builder:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        return WebHost.CreateDefaultBuilder(args)
                  .ConfigureAppConfiguration(builder =>
                  {
                      builder.AddSystemsManager("/ConfigureStoreName/");
                  })
                  .UseStartup<Startup>();
    }
}

Instead of hardcoding "/ConfigureStoreName/" I'd like to make this a configuration value.

When I call .ConfigureAppConfiguration() do I have access to the config values from appsettings.json that .CreateDefaultBuilder() uses? If so how would I update my code to call it? If not what is the best approach to avoid using a static value in the CreateWebHostBuilder() method?

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Josh
  • 8,219
  • 13
  • 76
  • 123
  • you could have another setting file with that information and load that up in a configuration to extract the value – Nkosi Jun 02 '19 at 18:10
  • I thought of that, but I was wondering if I had access to a name-value pair already that I could call. But that would be my fall back, create a main-settings.json file pull that value. – Josh Jun 02 '19 at 18:18
  • 1
    Might be worth to consider using an environment variable. – Ofiris Jun 02 '19 at 18:20
  • That is a good idea. Just tried adding it worked. My steps, (1) add to Environment Variable Visual Studio project for debugging, and then add to the serverless.template Environment Variables section and deploy. If you want to make your suggestion an answer I'll mark it as solved. – Josh Jun 02 '19 at 18:52

2 Answers2

3

Pre load setting file with that information.

If for example the setting file contained

{
  //...

  "AWS": {
    "Profile": "local-test-profile",
    "Region": "us-west-2",
    "ConfigureSource": {
      "Path": "/ConfigureStoreName/"
    }
  }

  //...
}

load that up in a configuration to extract the value.

public static IWebHostBuilder CreateWebHostBuilder(string[] args) {

    var configuration = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json") //<-- or whichever file has that information
        .Build();

    string path = configuration.GetValue<string>("AWS:ConfigureSource:Path");
    //Or a strongly typed model with aws options

    return WebHost.CreateDefaultBuilder(args)
              .ConfigureAppConfiguration(builder =>
              {
                  builder.AddSystemsManager(path);
              })
              .UseStartup<Startup>();
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • Valid approach, if I don't have access to a name-value configuration at this point in the workflow. – Josh Jun 02 '19 at 18:19
  • It is kind of a catch-22 because the `AddSystemsManager` is to be called on the builder while you also want to store/extract a needed value in the configuration. – Nkosi Jun 02 '19 at 18:21
  • Exactly. I need metadata about the configuration data that I'm adding! – Josh Jun 02 '19 at 18:26
  • 1
    @Josh they do something similar in the source code to get the AWSOptions. They build a config from the builder, extract what is needed and update the builder before it it built again later in the pipeline. https://github.com/aws/aws-dotnet-extensions-configuration/blob/master/src/Amazon.Extensions.Configuration.SystemsManager/SystemsManagerExtensions.cs#L204 – Nkosi Jun 02 '19 at 18:48
3

The solution I ended up going with was to use an Environment Variable:

public class Program
{
    private static string _parameterStoreNamePath;

    public static void Main(string[] args)
    {
        _parameterStoreNamePath = Environment.GetEnvironmentVariable("AWS_PARAMETER_STORE_NAME");
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        return WebHost.CreateDefaultBuilder(args)
                  .ConfigureAppConfiguration(builder =>
                  {
                      builder.AddSystemsManager(_parameterStoreNamePath); 
                  })
                  .UseStartup<Startup>();
    }
}

Notes:

  1. In the Visual Studio project, create an Environmental Variable named AWS_PARAMETER_STORE_NAME.
  2. For deployed instances, AWS_PARAMETER_STORE_NAME needs to be set in serverless.template or directly added to Lambda via the console.
Nkosi
  • 235,767
  • 35
  • 427
  • 472
Josh
  • 8,219
  • 13
  • 76
  • 123