Using AWS Parameter Store for ASP.NET Core Data Protection Keys

Using AWS Parameter Store for ASP.NET Core Data Protection Keys

If you’re using ASP.NET Core in AWS under any type of load balanced scenario, either through Elastic Beanstalk or an ALB with and ECS, etc, you will need to share the data protection keys. This is because each instance of your application needs to be using the exact same keys.

This isn’t an issue if you are using a single instance as the keys will be stored in memory.

If you haven’t yet used the AWS SDK, I highly recommend first checking out my quick start on configuring AWS SDK in ASP.NET Core.

AWS Systems Manager Parameter Store

One option is to use Parameter store to store the data protection keys. Thankfully AWS has released a nice little package to make this really simple.

First, add the Amazon.AspNetCore.DataProtection.SSM package to your csproj.

Now you can use the PersistKeysToAWSSystemsManager method passing the prefix as the parameter.

That’s it! That simple. Now when you run your application, you will see that a new parameter has been created with the prefix you specified followed by key-{GUID}.

ASP.NET Core Data Protection

If you want to persist data protection keys to somewhere like S3, check out this other post.

If you have any questions or comments, please let me know on twitter as I will focus my posts on those questions and comments.

Related Links:

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.

Configuring AWS SDK in ASP.NET Core

Configuring AWS SDK in ASP.NET Core

If you’re using any AWS Services, you’re likely going to be using the AWS SDK via NuGet packages. You don’t need to configure anything to start using the SDK, but there are a few things that can make your life a lot easier. Follow along for a how-to on configuring AWS SDK in ASP.NET Core.

AWS CLI Named Profiles

The AWS Command Line Interface (CLI) is the first thing you’re going to want to have. Beyond controlling AWS services it allows you to configure credential profiles.

Once you have the CLI installed, to configure the default profile simply run and follow the prompt to enter your access key, secret and region.

> aws configure

For the rest of this example, I’m going to be using the default profile that I’ve configured that contains my access key and secret.

AppSettings

The AWS SDK will look for an AWS key in your appsettings.json file. It will use this section for configuration. In this section, you can define which Profile to use as well as many other options including as Region.

Environment Variables

You can also use Environment Variables to define these same settings. Be sure to use colon as hierarchy.

Startup.cs

The AWSSDK.Extensions.NETCore.Setup NuGet package that adds extension methods to IConfiguration and IServiceCollection that makes it simple to retrieve AWS configuration and types.

Now if you inject the IAmazonS3 from a Controller or even if you resolve it from context.RequestServices.GetService<IAmazonS3>() you will get out an instance that is auto-configured with the access key and secret from your Default profile as well as the Region defined in your appsetting or Environment Variable.

AWS SDK in ASP.NET Core

That’s the quick start way of being able to use the AWS SDK without having to specify any of your credentials in your source as well as being able to use dependency injection to have the AWS SDK types resolve pre-configured.

If you have any questions or comments, please let me know on twitter as I will focus my posts on those questions and comments.

Related Links:

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.

CQRS without Multiple Data Sources

One of the most common misconceptions about CQRS is it implies Eventual Consistency. That you must have different data sources for your commands and queries. Meaning you will have a use one data source for commands/writes and an entirely different data source for query/reads. This is simply untrue.

This assumption implies that you’re query/read data source will be eventually consistent with the command/write side. This is because the assumption is your commands will write to its data source, then emit events that will be processed and update your query/read database independently.

If you’re unfamiliar with CQRS, I highly recommend checking some other posts I’ve written about CQRS before reading futher.

Different Models

One of the benefits of applying CQRS is that you can have different representations of your data. Your write model may look very different than your read model.

However, this doesn’t mean you need to have different data sources and use event handlers to build your query model.

Views

If you’re just getting into applying CQRS, you can use the exact same underlying data model for both commands/writes and queries/reads. There’s nothing saying you can’t.

However, if you’re using a relational database you can get all the benefits of tailored query models by mapping your queries/reads models to database views. Or if you database supports it, materialized views.

If you’re using Entity Framework Core, this is pretty straight forward by defining your query types in the OnModelCreating method of your DbContext.

Consistentcy

This means you’re command/write model and query/read models are always 100% consistent. You’re not dealing with eventual consistency.

Another bonus is you’re not writing event handlers to update your read/query database which also eliminates a pile of code and complexity.

From my experience, when applied wrong, eventual consistency can be a giant pain and not at all what you’re users are expecting.

Most often users are expecting to click a button and see the results immediately. Obviously, there are many ways to handle this, but if you’re new to CQRS, my initial recommendation is to keep things as simple as possible and that means keeping data consistent.

Start simple:

  • Create a class that changes state (command) and create a separate class that reads state (queries).
  • Use SQL Views (or materialized views) to map tailored queries.
  • Use something like Automapper for compositing the query result.

Atomic

If using Views isn’t an option, and you’re using the same relational database for both reads and writes another option is to wrap the entire operation in a transaction. This means your operation to modify your database records for the command, as well as modify database records for your queries happen within the same transaction.

I’ll elaborate more on this, eventual consistency, event sourcing and more in coming posts.

Fat Controller CQRS Diet

I’ve blogged a bit about how to implement CQRS without any of the other fluff. You can check out my Fat Controller CQRS Diet blog series as well as a related talk:

If you have any questions or comments, please let me know on twitter as I will focus my posts on those questions and comments.

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.