Implementing MSI in Azure Functions Step-by-step
MSI for Azure Functions

Implementing MSI in Azure Functions Step-by-step

Introduction

The management of secrets, credentials, certificates, and keys used to secure communication between services is a common obstacle for developers. Developers are no longer required to manage these credentials with managed identities.

Services need a way to access Azure Key Vault, even though developers can safely store secrets there. Applications can use managed identities to connect to resources that support Azure AD authentication by using an automatically managed identity in Azure Active Directory (Azure AD). Without having to manage any credentials, applications can obtain Azure AD tokens using managed identities.

In this tutorial blog, we will take a look at how we can implement the Managed System Identity (MSI) on an Azure Function from scratch using Azure Key Vault and Azure Storage Account. To elaborate further, we will create an Azure Function from scratch and try reading some data from Azure blob storage by connecting to it using the account key first, and then replacing the same with the MSI using Key vault. This will help you understand the difference between two and show how MSI accounts for the following benefits:

  • Credential management is not required of you. You cannot even access credentials.
  • Managed identities can be used to authenticate to any Azure AD-supported resource, including your own applications.
  • Utilizing managed identities is free of charge.


Creating the Azure Functions

In the Portal

Let us get started by creating an Azure Function by navigating to the Azure Portal as shown below:

No alt text provided for this image
Create an Azure Function from Portal

This takes a couple of minutes. While this happens, pull up your Visual Studio (2022 preferred). Ensure you have .NET 6 installed to go ahead. If you don't have any of them, refer this and follow the steps before moving further.

Locally

Once ready with Visual Studio and .NET 6, open up your Visual Studio and click on new project as shown:

No alt text provided for this image
Create New Project

Search for Azure Function as shown and then choose the one indicated below and click Next:

No alt text provided for this image
Choose Azure function

Select the options as shown and click on Create to create the new Azure Function:

No alt text provided for this image
Create the Azure Function



Executing the Function locally

Replace the code in the Run method of the Azure Function with the below code:

            string name = req.Query["name"]


? ? ? ? ? ? string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
? ? ? ? ? ? dynamic data = JsonConvert.DeserializeObject(requestBody);
? ? ? ? ? ? name = name ?? data?.name;


? ? ? ? ? ? string accountName = Environment.GetEnvironmentVariable("SA_Name");
? ? ? ? ? ? string accountKey = Environment.GetEnvironmentVariable("SA_Key");
? ? ? ? ? ? string accountURL = "https://" + Environment.GetEnvironmentVariable("SA_Name") + ".blob.core.windows.net";? ? ? ? ? ??
? ? ? ? ? ?
? ? ? ? ? ? StorageSharedKeyCredential sk = new StorageSharedKeyCredential(accountName, accountKey);


? ? ? ? ? ? Uri uri = new Uri(accountURL);


? ? ? ? ? ? DataLakeServiceClient serviceclient = new DataLakeServiceClient(uri,sk);
? ? ? ? ? ? DataLakeFileSystemClient container =? serviceclient.GetFileSystemClient("test");
? ? ? ? ? ? DataLakeFileClient file = container.GetFileClient(name);


? ? ? ? ? ? return new OkObjectResult(file.OpenReadAsync().Result);;        

Please note that I have renamed the name of the .cs file to TestMSI and hence I see the same while running the code. You may see Function1 or similar.

You may see some errors when you paste the above code. To fix them, follow the below steps:

Install the below nuget packages as shown:

No alt text provided for this image
Install nuget packages

To learn how to do the same, refer this blog.

Add the following using statements in the Function1.cs file if they are missing:

using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Azure.Storage;
using Azure.Storage.Files.DataLake;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;        

Now, go to the Azure Portal and create a storage account or use an existing one. Upload a simple .txt file to any of the containers as shown:

No alt text provided for this image
Add a text file to Storage Account

Make sure the name of the container is test for the code to work seamlessly. If not, please update the below line in the code:

DataLakeFileSystemClient container =? serviceclient.GetFileSystemClient("YOUR_CONTAINER_NAME");        

Get the Storage account name and Key and update the local.settings.json file as shown below in the code:

No alt text provided for this image
Update credentials in configuration file

Try running the code and you shall see the below screen:

No alt text provided for this image
Debugging the code

Navigate to the URL shown above in any browser. To run the code, enter the name of the file that you uploaded in Azure Storage Account container with the right path and click Execute. You shall receive the contents of the file as indicated in Response Body.

No alt text provided for this image
Running the code locally



Deploying the Azure Function

Now, we need to deploy this code, which works fine locally, to the Azure Function that we created.

In?Solution Explorer in Visual Studio, right-click the project and select?Publish. In?Target, select?Azure?then?Next.

No alt text provided for this image
Choose the Target

Follow the steps as shown:

No alt text provided for this image
Specify the Type

Make sure you are logged in with the same Microsoft account in Visual Studio that you are using in the portal. If yes, then you should see the target Azure Function resource:

No alt text provided for this image
Choose the Target Resource

Skip the API Management for now as shown and proceed:

No alt text provided for this image
Skip the API Management

Select Publish and wait for it to succeed as shown:

No alt text provided for this image
Publishing

Once done, you should see something similar:

No alt text provided for this image

To verify whether the deployment succeeded, go back to the portal and you must see your function name as shown:

No alt text provided for this image
Verify the deployment



Running the Azure Function

To test the Azure Function, copy the URL from the Overview pane of the Azure Function in the portal, paste in any browser of your choice and append "api/swagger/ui#/name/Run" to the same in the end. You should see the following screen. Try running the API endpoint as you did earlier in the localhost as shown:

No alt text provided for this image
Test the API

You might face a 401 Unauthorized error because the Function key is missing and hence it does not allow you to make a call directly without passing it. To counter this, open the Azure function in the portal and go to Functions and choose your Function. Inside it, go to Function Keys as shown in the below image and copy the key.

No alt text provided for this image
Get the Function Keys

Switch back to the browser and click on Authorize in the Swagger UI as shown:

No alt text provided for this image
Authorize the Swagger UI

Paste the keys as shown and click on Authorize.

No alt text provided for this image
Authorize

Try rerunning the API and you shall see the 500 error this time indicating something is wrong with the code. Now, if you scroll a couple of steps back, we had used few values in the local.settings.json file while running the code in the local machine. The same values are missing from the Function App configuration after deployment. To fix this, go back to the Azure Function in the Portal and navigate as shown:

No alt text provided for this image
Missing Configuration settings

Add SA_Name and SA_Key as keys and their corresponding values as values from the local.settings.json to the application setting one-by-one as shown for a sample value SA_ConnectionString:

No alt text provided for this image
Add the configuration values

Click OK and do not forget to click Save after the settings are added.

Now, if you run the API, it should work as expected.

No alt text provided for this image
Successful API Run

Implementing MSI

Now that we are able to build and deploy an Azure Function, we need to understand how the Azure Function is interacting with the Storage Account to get the contents of the specified file. As you would have guessed by now, it is the Account Key.

Now, the idea of MSI is to avoid using it directly in the Configuration of the Azure resource(Azure Function, in this case) without affecting the functioning of the applications. This is done by registering the Azure function resource in Azure Active Directory by turning on the Managed System Identity, creating a secret for the same in an Azure key Vault and then finally creating the reference for the same in the Configuration settings.

To implement the above, head over to the Azure Function in the portal and search for Identity in the left pane. Turn on the System Managed Identity as shown below:

No alt text provided for this image
Enable the System Assigned Managed Identity

Open any existing Azure Key Vault or create a new one and go to Secrets under the Objects section in the left pane. Click on Generate/Import and add the SA_Key configuration setting value as the value with the secret name as shown below and click on Create:

No alt text provided for this image
Add the Secret to the key Vault

Once done, navigate to the Access policies section in the left pane of the Key vault and then click on Create. Choose the below fields and click Next:

No alt text provided for this image
Adding permissions in Key vault Access policies

Choose the Select a Service Principal option and search for the name of the Azure function and select it as shown below:

No alt text provided for this image
Add the System Identity to the Access Policy

Keep on clicking next and Create the same. Verify as shown below:

No alt text provided for this image
Verify the Access policy

Now, copy the Secret Identifier value from the newly created Secret as shown below:

No alt text provided for this image
Copy the Secret Identifier from Key Vault

Replace the value of the SA_Key Configuration setting in the Azure Function as shown below:

No alt text provided for this image
Update the Configuration Setting

Refer the below snippet to understand it better:

????"name":?"SA_Key"
????"value":?"@Microsoft.KeyVault(SecretUri=PASTE_THE_COPIED_VALUE_HERE)",        

Once this is updated, you should see the green tick indicating it is able to access the Key vault reference.

With this in place, you are all set to run the API!

As we see, the same application shall run without using the account key and specifying it anywhere in the Azure Function. The Key Vault secret and access policy takes care of the authentication internally.


Hope you enjoyed the article and learnt something new! Follow me and Stay tuned for the next one!

If you wish to read about something specific, do let me know in the comments and I shall be more than happy to deliver it and grow along!

Please like and share this article, if you find it useful. You can find my other articles on?Medium.

Subscribe to the newsletter to get my latest articles in your inbox.

Should you be having any queries feel free to reach out to me via?LinkedIn?or drop an email [email protected].

Code reference: https://github.com/Naman786sinha/.NET-Core-Development-with-Azure-and-Swagger/tree/master/MSI



Moses Blehmans

Lead Software Engineer/Architect (Remote) - .NET, Azure, AWS

1 年

Why do you need KeyVault if you use MSI? The whole point of MSI should be to stop using any keys and secrets altogether. Better go deep into using MSI instead.

回复
Amrit Jain

Student at Indian Institute of Science (IISc)

1 年

Useful stuff!

Nishika Tiku

SDE3 @ Morgan Stanley

1 年

Very well explained in simple steps.. Keep contributing ????

要查看或添加评论,请登录

NAMAN SINHA的更多文章

  • Time Travel — Possible?

    Time Travel — Possible?

    On 28th June 2009, a party was about to start at England’s Cambridge University. English theoretical physicist Dr…

社区洞察

其他会员也浏览了