Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/example-api/bin/Debug/netcoreapp2.0/example-api.dll",
"program": "${workspaceFolder}/src/example-api/bin/Debug/netcoreapp3.1/example-api.dll",
"args": [],
"cwd": "${workspaceFolder}/src/example-api",
"stopAtEntry": false,
Expand Down
2 changes: 1 addition & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"version": "2.0.0",
"tasks": [
{
"taskName": "build",
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
Expand Down
24 changes: 13 additions & 11 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ Enrich your configuration with plain text or secure settings from AWS ParameterS

## Example

Example configuration for a asp.net core project:
Example configuration for an ASP.Net Core project:

public static IWebHost BuildWebHost(string[] args)
public static IHost BuildHost(string[] args)
{

return WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostContext, config)=>
return Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostContext, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
Expand All @@ -37,27 +36,30 @@ Example configuration for a asp.net core project:
parameterStoreConfig.AwsCredential = new Amazon.Runtime.StoredProfileAWSCredentials();
});
})
.UseStartup<Startup>()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.Build();
}

# Alternatively

You can also use parameterStoreConfig.UseDefaultCredentials = true; to let AWS handle this.

# Finding your way in the solution

in /src you find two projects, one example-api and the src for the nuget package itself
in /test you find the unittests
In /src you find two projects, one example-api and the src for the nuget package itself
In /test you find the unit tests

To use the provided samples you have to will have to setup 3 parameters in the ParameterStore

/somenamespace/somekey
/somenamespace/someotherkey
/somenamespace/somesecurekey => This needs to be set up as a secure string, which requires a KMS-Encryption key

You will also have set up and save a local default aws profile on the computer if you want to use StoredProfileAWSCredentials as it is used
in the example above (see http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html)
You will also have set up and save a local default aws profile on the computer if you want to use StoredProfileAWSCredentials as it is used in the example above (see http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html)

# ParameterStore on AWS

see: http://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html
For reference see the [Parameter Store documentation on AWS](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html)
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
using Amazon.SimpleSystemsManagement;
using System;
using System.Collections.Generic;
using System.Linq;
using Amazon.SimpleSystemsManagement;
using Amazon.SimpleSystemsManagement.Model;
using Microsoft.Extensions.Configuration;
using System.Linq;
using System;
using System.Collections.Generic;

namespace ParameterStoreConfigurationProvider
{

public class ParameterStoreConfigurationProvider : ConfigurationProvider
{
private readonly ParameterStoreConfigurationSource configurationSource;
Expand All @@ -21,28 +20,27 @@ public override void Load()
{
IEnumerable<GetParametersResponse> responses;

if (this.configurationSource.UseDefaultCredentials)
if (configurationSource.UseDefaultCredentials)
{
using (var client = new AmazonSimpleSystemsManagementClient(Amazon.RegionEndpoint.GetBySystemName(this.configurationSource.Region)))
using (var client = new AmazonSimpleSystemsManagementClient(Amazon.RegionEndpoint.GetBySystemName(configurationSource.Region)))
{
responses = MappingClientResponseToData(client);
}
}
else
{
using (var client = new AmazonSimpleSystemsManagementClient(this.configurationSource.AwsCredential, Amazon.RegionEndpoint.GetBySystemName(this.configurationSource.Region)))
using (var client = new AmazonSimpleSystemsManagementClient(configurationSource.AwsCredential, Amazon.RegionEndpoint.GetBySystemName(configurationSource.Region)))
{

responses = MappingClientResponseToData(client);
}
}

MapResults(responses);
}

private IEnumerable<GetParametersResponse> MappingClientResponseToData(AmazonSimpleSystemsManagementClient client)
private IEnumerable<GetParametersResponse> MappingClientResponseToData(IAmazonSimpleSystemsManagement client)
{
IEnumerable<GetParametersRequest> requests = PrepareRequests();
var requests = PrepareRequests();
IList<GetParametersResponse> responses = new List<GetParametersResponse>();

foreach (var request in requests)
Expand All @@ -58,8 +56,9 @@ private IEnumerable<GetParametersResponse> MappingClientResponseToData(AmazonSim
private void CheckParametersValidity(GetParametersResponse response)
{
var requiredInvalidParameters = response.InvalidParameters.Where(item =>
this.configurationSource.ParameterMapping.First(pm =>
configurationSource.ParameterMapping.First(pm =>
pm.AwsName == item).Optional == false).ToList();

if (requiredInvalidParameters.Count > 0)
{
var wrongParams = "";
Expand All @@ -72,9 +71,9 @@ private void CheckParametersValidity(GetParametersResponse response)
}
}

internal IEnumerable<GetParametersRequest> PrepareRequests()
private IEnumerable<GetParametersRequest> PrepareRequests()
{
var names = this.configurationSource.ParameterMapping.Select(x => x.AwsName).ToList();
var names = configurationSource.ParameterMapping.Select(x => x.AwsName).ToList();
const int groupSize = 10;

var requests = names
Expand All @@ -83,30 +82,30 @@ internal IEnumerable<GetParametersRequest> PrepareRequests()
.Select(g => new GetParametersRequest
{
Names = g.ToList(),
WithDecryption = this.configurationSource.WithDecryption
WithDecryption = configurationSource.WithDecryption
});

return requests;
}

internal void MapResults(IEnumerable<GetParametersResponse> responses)
private void MapResults(IEnumerable<GetParametersResponse> responses)
{
this.Data = new Dictionary<string, string>();
Data = new Dictionary<string, string>();

foreach (var response in responses)
{
foreach (var parameter in response.Parameters)
{
var parameterMapping =
this.configurationSource.ParameterMapping.First(pm => pm.AwsName == parameter.Name);
this.Data[parameterMapping.SettingName] = parameter.Value;
configurationSource.ParameterMapping.First(pm => pm.AwsName == parameter.Name);
Data[parameterMapping.SettingName] = parameter.Value;
}

foreach (var parameter in response.InvalidParameters)
{
var parameterMapping =
this.configurationSource.ParameterMapping.First(pm => pm.AwsName == parameter);
this.Data[parameterMapping.SettingName] = parameterMapping.Default;
configurationSource.ParameterMapping.First(pm => pm.AwsName == parameter);
Data[parameterMapping.SettingName] = parameterMapping.Default;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>Use AWS ParameterStore to configure your .net core project</Description>
<Description>Use AWS ParameterStore to configure your .Net project</Description>
<PackageProjectUrl>https://github.com/schwamster/ParameterStoreConfigurationProvider</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/schwamster/ParameterStoreConfigurationProvider/blob/master/LICENSE</PackageLicenseUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Copyright>Bastian Töpfer</Copyright>
<PackageTags>AWS ParameterStore Configuration</PackageTags>
<Version>1.1.0</Version>
<Version>2.0.0</Version>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.Core" Version="3.3.19" />
<PackageReference Include="AWSSDK.SimpleSystemsManagement" Version="3.3.14" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.0.0" />
<PackageReference Include="AWSSDK.Core" Version="3.7.102.1" />
<PackageReference Include="AWSSDK.SimpleSystemsManagement" Version="3.7.102.14" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.31" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Amazon.Runtime;
using System.Collections.Generic;
using Amazon.Runtime;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;

namespace ParameterStoreConfigurationProvider
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Microsoft.Extensions.Configuration;
using System;
using System;
using Microsoft.Extensions.Configuration;

namespace ParameterStoreConfigurationProvider
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;

namespace example_api.Controllers
{
[Route("api/[controller]")]
public class ConfigurationController : Controller
[ApiController]
[Route("[controller]")]
public class ConfigurationController : ControllerBase
{
private readonly IConfiguration configuration;

Expand All @@ -17,7 +15,7 @@ public ConfigurationController(IConfiguration configuration)
this.configuration = configuration;
}

// GET api/values/5
// GET Configuration/key
[HttpGet("{key}")]
public string Get(string key)
{
Expand Down
26 changes: 12 additions & 14 deletions src/example-api/Program.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Hosting;
using ParameterStoreConfigurationProvider;

namespace example_api
Expand All @@ -15,14 +11,13 @@ public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
BuildHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args)
public static IHost BuildHost(string[] args)
{

return WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostContext, config)=>
return Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostContext, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
Expand All @@ -36,7 +31,7 @@ public static IWebHost BuildWebHost(string[] args)
};
parameterStoreConfig.Region = "eu-west-1";
parameterStoreConfig.UseDefaultCredentials = true;
// parameterStoreConfig.AwsCredential = new Amazon.Runtime.StoredProfileAWSCredentials();
// parameterStoreConfig.AwsCredential = new Amazon.Runtime.StoredProfileAWSCredentials();
})
.AddParameterStoreConfig(parameterStoreConfig =>
{
Expand All @@ -47,10 +42,13 @@ public static IWebHost BuildWebHost(string[] args)
parameterStoreConfig.WithDecryption = true;
parameterStoreConfig.Region = "eu-west-1";
parameterStoreConfig.UseDefaultCredentials = true;
// parameterStoreConfig.AwsCredential = new Amazon.Runtime.StoredProfileAWSCredentials();
// parameterStoreConfig.AwsCredential = new Amazon.Runtime.StoredProfileAWSCredentials();
});
})
.UseStartup<Startup>()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.Build();
}
}
Expand Down
24 changes: 13 additions & 11 deletions src/example-api/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Hosting;

namespace example_api
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddControllers();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseMvc();
app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
}
7 changes: 3 additions & 4 deletions src/example-api/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
Loading