aws / aws-dotnet-extensions-configuration

This repository hosts various libraries that help developers configure .NET applications using AWS services.

Home Page:https://aws.amazon.com/developer/language/net/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using SSM parameter as ConfigurationSection

DamirAinullin opened this issue · comments

Is it possible to use SSM parameter as ConfigurationSection?

For example parameter with name /example/settings/Logging
with json value

{
"Level": "Information",
"SomethingElse": "Test"
}

And then use it like this?

public class Logging
{
    public string Level { get; set; }
    public string SomethingElse{ get; set; }
}

...

var configurationSection = configuration.GetSection(nameof(Logging));
services.Configure<Logging>(configurationSection);

I misunderstood the question the first time. I don't think this is possible at the moment, but I think it is something that we could add. I'll ask.

So you can manage this on your own if you target .NET Core 3.0 like follows:

        public void ConfigureServices(IServiceCollection services)
        {
            var loggingConfig = new ConfigurationBuilder().AddJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(Configuration.GetSection("logging").Value))).Build();
            services.Configure<Logging>(loggingConfig);
            ...
        }

I'm not yet sure if we'll be able to support versions lower than that.

Thanks for the response. My target is netcore 2.1 (standard env for AWS lambda). I had to get method AddJsonStream and related sources from net core 3.0 to my code. And your approach works well. Do you know will Reload functionality and configurations.WaitForSystemsManagerReloadToComplete method be worked well in this case? BTW should I close the issue or you are going to make this feature available out of the box in future versions and then close it?

Hey @DamirAinullin, this does work, but the full hirarchy need to exist in the param name

So in your example it would be:

  • Name: /example/settings/Logging/Level Value: Information
  • Name: /example/settings/Logging/SomethingElse Value: Test

There would be too many different ways to anticipate what someone would want to put in a param for their custom hirarchy. You mentioned json in your example, but someone could want yaml, xml, etc.

Since in this case the parameter name is the hirarchy all of this is consistent, and each param is a simple key value pair.

effectively you can think of this the same way as the AddEnvironmentVariables. You can put whatever you want in the variable, but the provider just treats it as a kvp.

Here are the equilivant breakdowns for json, environment variables, and param store. This may help

JsonProvider:

{
  "Logging": {
    "Level": "Information",
    "SomethingElse": "Test"
  }
}

Environment Variables:

Logging:Level = Information
Logging:SomethingElse = Test

Param Store:

/prefix/Logging/Level = Inforamtion
/prefix/Logging/SomethingElse = Test

@KenHundley I understand your approach but it is difficult to manage params from web console when you have a lot of params for example more than hundreed. Probably should be another way how to manage them more convinient.

commented

@DamirAinullin If by manage you mean populate SSM - I'm thinking about this as well. I put a discussion up on reddit for now, but will likely start building something soon. https://www.reddit.com/r/aws/comments/dwrtek/populating_ssm_in_a_sane_way_from_git_via_cicd/

We just starting using this library, and our goal is to have everything in git, ssm would just be the intermediary (or dynamo etc) without having to think too much about that.

@DamirAinullin I also found that this worked for my situation:

public void ConfigureServices(IServiceCollection services)
{
     var logging = new Logging();
     Configuration.GetSection("Logging").Bind(logging);
     services.AddSingleton(Options.Create(logging));
}
commented

I have added an alternative solution, that works for me. Would be nice if something like this could be merged into public solution.

@KenHundley What's not clear in your suggestion of flattening the JSON hierarchy to kvp is how arrays would be represented. For example in this fragment how would the "WriteTo" elements be set?

{
  "Serilog": {
    "Using":  [ "Serilog.Sinks.Console", "Serilog.Sinks.Seq" ],
    "MinimumLevel": "Information",
    "WriteTo": [
      { "Name": "Console" },
      { "Name": "Seq", "Args": { "serverUrl": "http://localhost:5341" } }
    ]

Update: As it turns out, you simply include the array index value as part of the path, so the above would be:
aws ssm put-parameter --name '/WriteTo/0/Name' --value Console
aws ssm put-parameter --name '/WriteTo/1/Name' --value Seq
etc...

We have noticed this issue has not received attention in 1 year. We will close this issue for now. If you think this is in error, please feel free to comment and reopen the issue.