28 June, 2019

Using Azure Managed Identity

If we want to access protected resources from our apps, we usually have to ship a key and secret in our app. This traditionally meant registering an application/service principal in Azure AD, getting an id and secret, then granting permissions to that principal in things like Key Vaults. At runtime, our code would use that ID + secret to authenticate to AAD and get an access token to use to connect to the other service. Now using the same keys and secrets from your Key Vaults for a long time is also a security breach. You need to renew any certificates, roll keys regularly, ensure the security of the keys and so on. This is pretty embarrassing and frustrating at times.

Now what if there's a way where Azure would handle all the authentication and authorization mess for accessing a service so that we simply do not bother about storing secrets in code, configuration files, code repositories and headache of key rotations.

The answer is Azure Managed Identities. In the rest of this article we will see how we can store secrets in Azure Key Vaults and access the same from our code and Azure Web App without storing  a single credential anywhere. Cool! Let's dive

Prerequisites:
  • Azure Subscription (Free subscription of 30 days will also do)
  • Microsoft Visual Studio 2017 (Asp.Net Core)
We will create a Key Vaults first in Azure portal, create a key/value, will access it from our C# code. Then we will deploy the app in Azure Web App and would access the same key/value from there.

  • Login to Azure (If you do not have any subscription already then create one else login to your existing one)
  • Search for Key Vault in the search bar and select the service
  • Click "+Add" in the top left to start the journey

  • Fill up the Name, Resource Group, Location as per your choice. Leave other settings as default.
If you click the Access Policy property in the blade, you will see that your user is already selected by default. Click on "Create" to initiate the service provisioning. It will take few seconds if not minutes.


  • Now lets add a secret value to our Key Vaults. Enter into the resource and go to its "Secrets" blade. Click on the "+Generate/Import" to add a secret and its value.
  • Give your Secret name and value and leave others as default. I have given name as "HighSecret" and value as "Abradacabra!!!" (sound magical to me 😊). Click Create.
Within seconds it will be created and saved in your Key Vault


Perfect! Great going 👏 We are done with the Key Vault part. Now lets write some code and try accessing this secret without any service principal credentials.

Visual Studio Application – To see the action

  • Fire up Visual Studio and select File >> New >> Project. Select “ASP.NET Core Web Application” as your project type. Choose the project name as per your choice (I have given keyvaultmsidemo-webapp). Click OK
  • Select "MVC" from the next window. You can also un-check the "Configure for HTTPS" support as this is not a requirement for this demo. Click OK
  • We need to add to packages in our project (one for working with KeyVault and another for the Managed identity). The packages are:
    Microsoft.Azure.KeyVault
    Microsoft.Azure.Services.AppAuthentication
    
  • Inorder to add, right click on your project >> Manage NuGet Packages
  • Go to the Browse section and type/paste Microsoft.Azure.KeyVault in the search bar. The system will display the result. Select the service and click "Install" on the right. Repeat the same step to install package Microsoft.Azure.Services.AppAuthentication
  • First lets add a label and a button to the Index.cshtml page under Views>>Home. On this button click we will show the secret value in that label. Place your cursor in front of the very first "div" and press enter; then copy paste the below code there
<hr />
<label style="font-size:xx-large">@ViewData["HighSecret"]</label>
<button id="btnShowSecret" onclick="location.href='@Url.Action("ShowSecret", "Home")'" )">
    Show secret to the world
</button>
<hr />
The view should look similar to this. You can see the onclick event of the button is pointing to a ShowSecret action of the Home controller which we will define next.


  • Open the HomeController.cs under Controller folder of your solution and add the below two namespaces in the using section at the top
using Microsoft.Azure.KeyVault;
using Microsoft.Azure.Services.AppAuthentication;
  • Now scroll down at the bottom of the file and add the below code. 
public IActionResult ShowSecret()
{
   var tokenProvider = new AzureServiceTokenProvider();
   var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(tokenProvider.KeyVaultTokenCallback));
   var secretValue = keyVaultClient.GetSecretAsync($"https://keyvaultmsi-demo.vault.azure.net/", "HighSecret").Result;

   ViewData["HighSecret"] = secretValue.Value;

   return View("Index");
}
This is our ShowSecret() action which will return the secret value. Note that I have hard-coded the KeyVault Url (The DNS Name value which you can easily get from the overview blade of the KeyVault  service we created in Azure portal) and the secret Name in the code. In real project these two should come from some configuration file.

The major point to notice here is that we haven't mentioned any authentication/authorization credential anywhere till now for accessing the Key Vault. The Managed Identity will take care of all these in the background. Really? lets check it out. Hit F5 and run the project. 

The browser will launch your application and the default .Net Core web app will display along with our button "Show secret to the world" at the top

Hit the button and Voila! our secret value from the Key Vault is displayed. OMG moment 👌


Well Done! You have done everything right so far and the output is as expected. No hard-coded credentials anywhere anymore. Mission Accomplished. 👍 Ahhhh! not yet. Let's deploy our web application in Azure as till now it's running in our local box.

Right click on the project and hit "Publish" in the context menu. Select "App Service" as publish target and hit the Publish button at the bottom. Now check the default data populated by the system for you. If it looks all good the go-ahead and hit "Create".


Wait for few minutes for Azure to provision your service. Once done it will automatically load it in your browser. Check the browser url; it will change to the endpoint of your web app in Azure.


Hit the "Show secret to the world" button. Boom 💥 Errrrrrooooor!


Oh No, what went wrong? Don't worry, it leads us to a very important point. Our web application is now running in Azure and this application do not have permission to access the Key Vault with Managed Identity. Then how come it's working in local environment? This is working because of the user account we are using to access the Vault has permission by default. Check it out. Go to your keyvault service in Azure and open the "Access Policy' blade.


Our Azure web application is not in the list and hence the error. Security! right. So let's add the web application. Click "+Add new" at the top. Select "Key & Secret Management" from the Configure template dropdown list. Hit the Secret principal option and then type your web application name (typing few words would also do). The system will auto populate all the services starting with the name. Select you web application from the list. Hit "Select" and then hit "OK".

The application will now show up in the Access policy list. Hit "Save" and we are done.


Now go back the browser url. You can find the URL from the App Service overview page.


Click the link to launch the web page in a browser.  Hit the "Show secret to the world" button now and Hurray! the secret is displayed. Fantastic 👋👋


Hope this article will help to have a good understanding on Managed Identity and would encourage you to dig further. Do share with me about your experience and what you have built upon this foundation and also let me know if you want me to cover other areas of this service.

 I would love to hear from you. 

12 June, 2019

Azure Web App for Containers : a hidden gem

Web App for Containers lets you run your custom Docker image packaging your web application. It's a great Azure offering that helps developers to package their application and all related dependencies in a container and then host the container on the Azure Web App.

It's a win-win situation for many organization where they can bundle their application in a container and then leverage the full power of Azure App Service platform to do the hosting, security, networking, auto scaling, load balancing, CDN, A/B  testing, deployment slots, alerts and monitoring. What else do you need! 🙏

But there's a limitation. You can deploy only one docker image to an App Service as of today (Docker Compose and Kubernetes options of web app for containers are still in preview while writing this post). So this allows you to use Docker as a Service, but isn't intended for deploying Microservices.  For such requirement you must check Azure Service Fabric or Azure Kubernetes Service which are specially tuned to deal with microservice deployments at scale.

OK! Let's deploy our containerized web application into Azure web app for containers. 

Prerequisites:
  • Azure Subscription (Free subscription of 30 days will also do)
  • Basic docker knowledge (If you want to create your own containerized app, else not required)

For the sake of making this article short I had already created an happyegg application  (my favourite 😊) in Asp.Net Core, packaged it inside a Linux image and pushed it to docker hub repository. As this image is publicly available, you are free to use it if you want. Else you can go ahead and create your own application in a language of your choice and dockerize it inorder to get going. 
  • Login to Azure (If you do not have any subscription already then create one else login to your existing one)
  • Search for "Web App for Containers'
  • Fill up the basic details. I have selected "Linux" as OS since my happyegg app is a linux based image. Fill up the details as per your choice and click on "Configure container" 
  • Select "Single Container" (default) tab. Select "Docker Hub" as Image source since my image is available there, "Public" as Repository Access and put the image as "atanudochub/happyegg:latest" (If you want to use my happyegg image). For private registry you need to provide your username/password. Apart from that Azure Container Registry can also be your source. 
         Click "Apply"

  • Click "Create" to kickoff the service creation process. This will create an App Service Plan along with your App Service.

  • Open the happyegg App Service and hit the URL. 

  • A cute little smiling and dancing egg will pop up in your browser. Voila! Our App Service had successfully downloaded the happyegg image from the docker hub repository and running it in Azure. Auto Magic 👋
Moreover, If you go to the "Container settings" in the Settings blade of your web app, it will also show you a nice little log of what happened  behind the scene to run our image. Awesome!


Well Done! and congratulations for coming this far.

Hope this article will help to have a good understanding on the topic and would encourage you to dig further. Do share with me about your experience and what you have built upon this foundation.

 I would love to hear from you. 

10 June, 2019

Azure Front Door Service : Hands-On Learning!

Azure Front Door Service is a pretty new service added in the Azure ecosystem recently with some great features towards scalability, availability and security entry point for faster delivery of your global applications. It works at Layer 7 or HTTP/HTTPS layer and uses anycast protocol with split TCP and Microsoft's global network for improving global connectivity. The icing on the cake is it's support for WAF which is a must nowadays for any public facing applications.

In this article we won't go much into theory, rather dive straight into a hands-on demo where we would deploy one simple 'hello world' web application in two different Azure regions which are distant apart and would place an Azure Front Door service as a entry gate to achieve high availability and automatic fail-over in case of regional failure.

Region:
West US - Primary
West Europe - Secondary

If you want to read more about this service and its advanced features you can always refer to the Microsoft documentation

Please note that I have purposefully left out some complex areas or haven’t gone deep into details somewhere. This is just to make this article easy to follow and help as a quick launching pad for further exploration.

Prerequisites:
  • Microsoft Visual Studio 2017 (Though you can try with VS2015, but this demo is on VS2017)
  • Azure Subscription (Free subscription of 30 days will also do)
  • Basic HTML programming knowledge.
Jump In: 👍

Lets create two App Service in Azure (one in West US and another in West Europe region).
  • Login to Azure (If you do not have any subscription already then create one else login to your existing one)
  • Search for "App Services' if it's not already pinned to your left blade.

  • Create an web app and enter the basic information. Make sure you have selected the region as "West US". This is important. For other information you have your choice but I have suffixed as "-westus" for easy identification.

I do not need ApplicationInsights for this demo as hence disabled that feature in the "Monitoring" tab. Click "Review and create" and then "Create". This will kick-off the service creation process and our web app will be up and running in minutes. 

Now let's create another app service. This time make sure you have selected the region as "West Europe". This is important. For other information you have your choice but I have suffixed as "-westeurope" for easy identification.

Kick off the creation process and after a while you would have 2 web app running in two geographic regions.

Perfect! Great going 👏

Let's go ahead and create a simple helloworld html page and deploy that to the above app services in both the regions. I have selected Visual Studio for this inorder to publish the web page straight from the IDE. Nothing else. You can make your own choice.
  • Fire up Visual Studio and select File >> New >> Project. Select “ASP.NET Web application (.Net Framework)” as your project type. Choose the project name as per your wish (I have given HelloWorld)

Select "Empty" in the next window and click "OK"
  • Right click on the solution and add an HTML page. Give the name "index.html"
  • Replace the code of the index page with the following. 
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Hello World !!</title>
</head>
<body>
    <h1>This is a hello world wish from West U.S.</h1>
</body>
</html>

Nothing great in the code. Just a simple hello world wish.
  • Publish the page directly from the IDE. Right click on the solution and click "Publish". Make sure you are already logged to your Azure subscription from Visual Studio IDE.  Hit "Start" and select the "App Service" and "Select Existing"
  • Hit "Publish".  Here make sure you select the correct app service. Since our greeting message is from West US, hence select the hello world app service of West US app. This is important.
  • Click "OK" and deploy the application to the West US region. The browser url will confirm the correct deployment.
  • Now open the index page and change the message to "This is a hello world wish from West Europe" and publish it to the West Europe region the same way you did for US region. This time select the West Europe app service. The browser url will again confirm the correct deployment.
Cool! So now we have our web app running in two different region. 

Now let's configure Azure Front Doors Service. Ah! this is what we are waiting for.. right!
  • Search for "Front Doors' if it's not already pinned to your left blade.
  • Enter the basic information. Select the region as "West US"
  • In the "Configuration" blade first configure the Frontend hosts. Click the "+" icon at the top right corner of the blade and enter the host name of your choice. I have given "helloworld-frontdoors". Keep the Session Affinity and Web Application Firewall settings as default disabled. Click "Add"

  • Now configure the "backend pools". Click the "+" icon at the top right corner of the blade and provide the name of the pool of your choice. I have given "helloworld-backendpools".

  • Click the "+ Add a backend" link and configure the backend app services. Select "App service" from the Backend host type dropdown, your West US app endpoint from the Backend host name dropdown and "Priority" as 1 (signifying primary region). Rest accept as default. Click Add
  • Repeat the above step to add another backend pool but this time select your West Europe endpoint as the "Backend host name" and set the "Priority" as 2 (signifying secondary/fail-over region)  
  • After the setup your backend pool configuration should look similar to the below. Click "Add" to finish the configuration.
  • Now let's configure the route. Click the "+" icon at the top right corner of the blade and provide the rule name of your choice. I have given "helloworld-routes". Select "HTTPS only" from the Accepted protocol dropdown. Notice the system has picked up the front-end hosts name automatically. Accept all other defaults and click "Add"

  • The diagram should show similar to this after all the above configurations are in place.
  • Click the "Review + create" blade and hit "Create" to finish the Front Doors configuration. Wait for few minutes till it completes.

Notice the frontend host url. That is your front doors entry point to the backend world. You might get an 404 error if you hit the url as soon as it is created. Don't worry.. Wait for few moments as its takes some minutes to propagate the effect globally.

Hitting the front doors url we can see that the hello world message from West US is getting displayed. This means the page is getting served from the West US backend region and we have also made this as our primary region while configuring the front doors service. Great! its working as expected.

Hitting the front doors url multiple times will result in the same result. Our primary region is serving all the user request.

Now lets simulate a fail-over scenario. What if the West US region goes down? The Front Door should automatically fail over to the secondary region (in this case West Europe region) and serve the user request from there; thus ensuring high availability and disaster recovery. We have configured it to behave that way, right!

Go to the West US web app and stop the application. This will simulate the West US outage scenario which we are trying to accomplish.


Now go back to your Front Doors endpoint and hit refresh. You may see that it's still serving from the West US region. This is because the outage has not yet propagated globally. Wait for few minutes. Have patience, it's really quick. 😊

You will see that now the hello world message is getting served from the West Europe region.


Well Done! You have done everything right and the output is as expected. Mission Accomplished. 👍

Hope this article will help to have a good understanding on the Front Doors service and would encourage you to dig further. Do share with me about your experience and what you have built upon this foundation and also let me know if you want me to cover other areas of this service.

 I would love to hear from you.