Saturday, September 21, 2019

Asp.net Core 2.2–Integrating Azure Keyvault into AppSettings

Prerequisites

Azure Keyvaults – you will need two Azure Keyvaults setup. One for staging and one for production.  For this post I will be using Azure Keyvaults named:

  • blog-staging (stores staging secrets)
  • blog-production (stores production secrets)

Secrets – in each keyvault there should be a secret by the name of “TestSecret” and the value will be “staging” in the blog-staging keyvault and “production” in the blog-production keyvault.

Azure Web Apps – just like Azure Keyvault you will need a staging and production versions of a Web App.  For this post I will be using the Web Apps named:

  • devdave-blog-staging
  • devdave-blog-production

Asp.net Core Web Application – for this example use the template “Web Application (Model-View-Controller)”


Getting the code setup and running locally

The following nuget packages need to be installed:

Microsoft.Azure.Services.AppAuthentication
This package enables the ability to use Managed Service Identities.  When running locally it uses your credentials to validate against resources (Azure Keyvault in this post).  When running in Azure it uses the web apps service principal to validate against resources.

Microsoft.Extensions.Configuration.AzureKeyVault
This package adds the ability to intercept configuration requests to get app settings and route them to keyvault.

The code modifications:

Add the apsettings files for staging and production. Should look like this:

In Asp.net core 2.2 the convention is to use the value set in the environment variable “ASPNETCORE_ENVIRONMENT” to determine the appsettings file used for settings.  For example if the “ASPNETCORE_ENVIRONMENT” environment variable was set to “Foo” then the system would try and load settings from a file named “appsettings.Foo.json”.  If the “ASPNETCORE_ENVIRONMENT” environment variable is not set it defaults to the value “Production”.

Add a config setting to point at the correct keyvault based on environment by adding the following settings to the appsettings.Development.json and appsettings.Staging.json files.

Modify the appsettings.Production.json by adding the following settings.

Modify the program.cs file like so.

This will configure all future requests to confgi[“<key>”] to first look in the appsettings.json file, then the appsettings.<Environment>.json file and then look in the Azure Keyvault for the <key>.

Modify the HomeController like so

Then modify the Views\Home\Index.cshtml like so

The last thing is to add our user account that we login to visual studio with to the access policies of the staging and production keyvault.

You should now be able to run the Web App from your local machine.  When viewing the https://localhost:####/ website you should see the value “Test Secret = staging” on the home page.


Getting the code running in Azure

Setting the environment variable
For both staging and production Web Apps set the “ASPNETCORE_ENVIRONMENT” to the correct value.

Setting up the Managed Identity for the Web App
For both staging and production go to the Identity section and turn it on.  Click the Save button. Choose yes when asked if you want to create a service principal in Active Directory. Note the Object Id since you will need it in the next section.

Giving the Web App permissions in Keyvault
The last step is to allow the service principal created in the previous step to access Keyvault.  Go to the staging keyvault and select the access policies and give the web apps service principal access. Best practice would be to allow the staging site access to the staging keyvault only and the production site access to the production keyvault only. 

Configuration complete
The code deployed to the web app will now be able to access the key vault using its service principal.  All this is using Managed Service Identity which means you no longer have to maintain any application id/secrets or certificates to access azure resources.  Also none of the secrets need to be checked into source control, they can all live in keyvault where they are secure.

Sunday, May 7, 2017

Building an Achievement engine with Azure Service Fabric - 02

Previous Achievement Post

So here is the basic plan of what is needed to get going.  Like all plans this may change as we get going and learn more.  The general components that are needed are:

A Website to display a users view of the achievements.
This will allow a user to view the available achievements, the achievements they have earned, and hopefully the progress towards specific achievements.

A console application simulating activity that will generate achievements.
This console application will simulate the activity that will trigger achievement progression.  Ideally there would be another service that would watch a service bus for these events, since that is outside the scope of this blog series this console application will take the place of that service.

An API used to interact with the achievement engine.
This will be used by multiple components.  The website will use the API to get information about a users achievements.  A console application will use the API to trigger achievement events.

Actors for the individual achievement types.
This is where things get interesting.  Each achievement type (Daily Goal, Daily Fuel, Total Fuel, Streaks, and Date based) will have its own actor.  Each user will have their own instance of each of the achievement actors.  For example, given two separate users the following instances of the achievement actors would be instantiated.

User1:DailyGoal User2:DailyGoal
User1:DailyFuel User2:DailyFuel
User1:TotalFuel User2:TotalFuel
User1:Streaks User2:Streaks
User1:DateBased User2:DateBased

Actor for each user.
This actor will maintain the state of the achievements for the user.  This will stop the need to query each of the achievement types for the status of that specific achievement.


Why Actors?
The reason to use actors will make more sense as we write the code but for more information please go here:  Reliable Actors Introduction.  Pay close attention to the following sections:

  • Actor Lifetime
  • Distribution and Failover
  • Concurrency

The concurrency section is the most important one to check out.  The volume of events that could pass through this achievement engine could easily create a huge concurrency issue in the system.  The actor pattern solves this for the most part.

Another nice thing about using the actor pattern here is the actor itself is very specific.  For example when we build the Streaks achievement actor we will only need to concentrate on what that specific actor needs to do.

Monday, May 1, 2017

Building an Achievement engine with Azure Service Fabric - 01

First if you don't know what Azure Service Fabric is, go here to learn more.  I have been playing around with Azure Service Fabric and I felt that the virtual actor pattern used in Azure Service Fabric would be a good fit for building an achievement system.  For this series I will be basing the achievement engine off of the Nike Fuel trophies system.  I will not be implementing all the trophies just the ones I have grouped and referenced at the end of this post.

What is Nike Fuel?
Nike fuel is a proprietary unit of measurement for tracking fitness activity developed by Nike.  The algorithm is the same for everyone, so everyone is on an even playing field.

How to get Nike Fuel?
All products under the brand allow the user to earn Nike Fuel. Products include the Nike+ FuelBand accelerometer wristband; other wristbands such as SportWatch and SportBand; etc...

Goals
Most of the products that generate Nike Fuel allow the user to set a goal.  Example; reach 5,000 Nike Fuel in a day.

What is Going Green?
Going green means you completed your goal.  Example; earning 5,000 Nike Fuel in a single day would complete the goal referenced above.

Nike Fuel Trophies (Achievements)
It was difficult to get accurate information about the different trophies provided by Nike.  That being said I found several sources on the internet not affiliated with Nike that referenced information about the different Nike trophies that are available.  The trophy information below while it may not be 100% accurate is good enough to use as an example for this blog series.

Daily Goal Trophies

Water Beat Daily goal by 50%
Ice Double your daily goal
Fire Beat daily goal by 150%
Rainbow Triple your daily goal
Supernova Quadruple your daily goal

Daily Fuel Trophies

8k day Earn 8,000 fuel in a day
10k day Earn 10,000 fuel in a day
15k day Earn 15,000 fuel in a day
20k day Earn 20,000 fuel in a day

Total Fuel Trophies

5k Earned 5k fuel total
10k Earned 10k fuel total
25k Earned 25k fuel total
50k Earned 50k fuel total
75k Earned 75k fuel total
100k Earned 100k fuel total
150k Earned 150k fuel total
200k Earned 200k fuel total
300k Earned 300k fuel total
400k Earned 400k fuel total
500k Earned 500k fuel total
600k Earned 600k fuel total
700k Earned 700k fuel total
800k Earned 800k fuel total
900k Earned 900k fuel total
1M Earned 1M fuel total
1.15m Earned 1.15M fuel total
1.2M Earned 1.2M fuel total
1.5M Earned 1.5M fuel total
2M Earned 2M fuel total

Streak Trophies

7 days Get to green 7 days in a row
14 days Get to green 14 days in a row
30 days Get to green 30 days in a row
50 days Get to green 50 days in a row
100 days Get to green 100 days in a row
365 days Get to green 365 days in a row

Date Based Trophies

Jack O Lantern Get to green on Halloween
Uncle Sam Get to green on the 4th of July
Chocolate Heart Get to green on Valentine's Day
La Fiesta Get to green on Cinco de Mayo
Resolution Get to green on New Years Day

The plan for code
As part of this series I will be sharing the code in my GitHub account.  I am planning on making a branch for each blog post.  This way you will be able to follow along from post to post.  Also you should be able to access new branches before the corresponding blog post as I am writing the code over the coming months.

Next Achievement Post

Wednesday, December 21, 2016

Tuple Dictionary Key ???

The other day myself and some coworkers where going over some ideas on refactoring a process.  In this conversation the idea of a dictionary key of a tuple came up.  I thought this has to work especially after my last post about dictionaries => Fun with Dictionaries – Replacing ugly switch and if statements

So below is some code showing my findings.  Also here is the link to my github with all the code (https://github.com/devdaves/FunWithDictionaries2)

Here is an example factory where the dictionary with a tuple key is instantiated and used.

Using the Tuple as a key you can actually take some extremely complicated logic with multiple options and turn it into a simple dictionary lookup.

Tuesday, November 1, 2016

Building objects for your Unit Tests

When creating unit tests I prefer to use the AAA pattern (Arrange, Act and Assert).  During the Arrange part you usually end up instantiating objects to use for the test.  Depending on the complexity of the objects you are creating this can get to be a little bit of code.  Lets look at the code below:

Note the method BuildContact.  It takes a parameter of an Action<Contact> which would allow you to pass in a lambda expression to further define the properties you want to change on the Contact object for each unit test individually.  This centralizes the logic needed to create the Contact which is helpful but another benefit is what if there was a default value used by every test.  Look at this version of the BuildContact method:

Note the defaults are before the invoking of the action.  This way if a test wanted to override the default values it can.  Normally I create a separate test class for each of the methods I am writing unit tests for.  Using this method above to create the item I am using allows me to create the object with many defaults already set.It wouldn’t be unusual to have several BuildContact methods in different test classes each specific to the needs of that class (method) specifically.

Friday, October 28, 2016

Fun with Dictionaries – Replacing ugly switch and if statements

Recently I have been using a new technique to replace those ugly if statements and switch statements with a dictionary.  Lets get started with some code first:

So that Build method with all the if statements isn’t very appealing.  Lets make it better by using a switch statement instead:

That is better but I have started to prefer using a dictionary instead.  I think this code looks better:

Adding new items is one line now instead of several with the if and switch statements.

Tuesday, December 1, 2015

Singleton Azure WebJob

I have an Azure website project I have been working on.  This project required a scheduled task to run so I decided to give Azure WebJobs a try.  Creation of the job and getting it to deploy was pretty straight forward.  One of the things that is nice is for each instance your website uses the WebJob is duplicated.  For some WebJobs this can be be a really nice feature. 

The WebJob I am using does some data import and manipulation.  Having multiple instances of this WebJob running is not what I wanted.  After some searching I found that you can make your WebJob run on a single instance no matter how many instances your website is using.

To do this you will need to do the following.

  1. Add a “settings.job” file to the root of your WebJob project
  2. Modify the properties of the file and set the:
    • Build Action = Content
    • Copy to Output Directory = Copy always
  3. The contents of the “settings.job” file should contain the following json:
    { "is_singleton": true }

This should be all that is needed to get your WebJob running as a single instance when installed on many instances.