Azure Function with identity-based connections
Tags: azure, identity, csharp, programming
Published: 2022-06-15 07:11:54

## Table of Contents
1 [Objective](#objective)  
2 [Managed identity](#"managed-identity)  
3 [Azure Table binding](#"azure-table-binding)  

[Configure an identity-based connection](https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference?tabs=blob#configure-an-identity-based-connection)

> Some connections in Azure Functions can be configured to use an identity instead of a secret. Support depends on the extension using the connection. In some cases, a connection string may still be required in Functions even though the service to which you are connecting supports identity-based connections. For a tutorial on configuring your function apps with managed identities, see the creating a function app with identity-based connections tutorial.

[Tutorial: Create a function app that connects to Azure services using identities instead of secrets](https://docs.microsoft.com/en-us/azure/azure-functions/functions-identity-based-connections-tutorial)

> This tutorial shows you how to configure a function app using Azure Active Directory identities instead of secrets or connection strings, where possible. Using identities helps you avoid accidentally leaking sensitive secrets and can provide better visibility into how data is accessed.

Well, this is really awesome :-)

**Please find the my complete code for an identity-based connection at   
 [https://github.com/MarkusMeyer13/azure.functions.tables](https://github.com/MarkusMeyer13/azure.functions.tables)**


## 1 Objective<a id="objective"></a>

Create an Azure Function with identity-based connections to *AzureWebJobsStorage* and a *Table Storage*.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655133146302/rlnLLmlzK.png?auto=compress,format&format=webp align="left")

## 2 Managed identity<a id="managed-identity"></a>

Create an Azure Function with a managed identity:

The following script assigns the *system-assigned* [managed identity](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview) to the new Azure Function app.

```bash
storageAccountFunction='strfunctionmm01'
resourceGroup='eval.table'
functionName='SampleFunctionMM01'

az appservice plan create --resource-group $resourceGroup --name 'samplePlan' 
az functionapp create --name $functionName --resource-group $resourceGroup --storage-account $storageAccountFunction --os-type Linux --functions-version 4 --plan 'samplePlan'

az functionapp identity assign --name $functionName --resource-group $resourceGroup
```

Created managed identity in Azure Function:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655142205644/4rR0g81-I.png?auto=compress,format&format=webp align="left")

Retrieve the *Ids* for managed identity and storage account and assign the *Storage Blob Data Contributor* role.

```bash
functionManagedId=$(az functionapp identity show --name $functionName --resource-group $resourceGroup --query principalId -o tsv)

storageAccountFunctionId=$(az storage account list --resource-group $resourceGroup --query "[?name=='$storageAccountFunction'].id" -o tsv)
az role assignment create --role "Storage Blob Data Contributor" --scope $storageAccountFunctionId --assignee-principal-type ServicePrincipal --assignee-object-id $functionManagedId
```
The *Storage Account* with the assigned role:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655141114112/KncefECwq.png?auto=compress,format&format=webp align="left")

The last step is to remove the default *AzureWebJobsStorage* configuration and set only the storage account name *AzureWebJobsStorage__accountName*:


```bash
az functionapp config appsettings delete --name $functionName --resource-group $resourceGroup --setting-names "AzureWebJobsStorage"
az functionapp config appsettings set --name $functionName --resource-group $resourceGroup --settings AzureWebJobsStorage__accountName=${storageAccountFunction}
```

No connection strings in the Azure Function configuration:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655141288527/cNqu_ds3d8.png?auto=compress,format&format=webp align="left")



[Edit the AzureWebJobsStorage configuration](https://docs.microsoft.com/en-us/azure/azure-functions/functions-identity-based-connections-tutorial#edit-the-azurewebjobsstorage-configuration)
>Update the name from AzureWebJobsStorage to the exact name AzureWebJobsStorage\_\_accountName. This setting tells the host to use the identity instead of looking for a stored secret. The new setting uses a double underscore (\_\_), which is a special character in application settings.

## 3 Azure Table binding<a id="azure-table-binding"></a>

The new [Azure WebJobs Tables extension](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.Tables) is used for the Azure Function binding:


The Azure Function shall add and delete entities in *Table Storage*.
The *Table Storage* is part of a different *Storage Account* than *AzureWebJobsStorage*. So the *Connection* has to be specified in the binding:

```csharp
public static async Task<IActionResult> AddAsync(
    [HttpTrigger(AuthorizationLevel.Function, "post", Route = "sample")] HttpRequest req,
    [Table("Sample", Connection = "SampleTableConnection")] TableClient client,
    ILogger log)
{
// ...
}
```

[Grant permission to the identity - Azure Table API extension](https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference?tabs=table#connecting-to-host-storage-with-an-identity-preview)

| Binding type | Example built-in roles (Azure Storage1)|
|-|-|
| Input binding | Storage Table Data Reader |
| Output binding	| Storage Table Data Contributor |

Therefore the managed identity has to be assigned with the *Storage Table Data Contributor* role for Azure Table Storage. 

```bash
storageAccount='strsample'
resourceGroup='eval.table'
functionName='SampleFunctionMM01'

functionManagedId=$(az functionapp identity show --name $functionName --resource-group $resourceGroup --query principalId -o tsv)

storageAccountId=$(az storage account list --resource-group $resourceGroup --query "[?name=='$storageAccount'].id" -o tsv)
az role assignment create --role "Storage Table Data Contributor" --scope $storageAccountId --assignee-principal-type ServicePrincipal --assignee-object-id $functionManagedId
```

The assigned role *Storage Table Data Contributor*:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655145105658/V1TLX7k7z.png?auto=compress,format&format=webp align="left")

The naming convention for connection:

[Using endpoint and token credential](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.Tables)

> ```<ConnectionName>__endpoint = https://...table.core.windows.net```

```bash
tableEndpoint="https://$storageAccount.table.core.windows.net"
az functionapp config appsettings set --name $functionName --resource-group $resourceGroup --settings SampleTableConnection__endpoint=$tableEndpoint

```
Finally, all Azure Function settings do no longer contain connection strings:



![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1655145922365/uST2YOUP2.png?auto=compress,format&format=webp align="left")

Please get the complete code here:
```bash
git clone https://github.com/MarkusMeyer13/azure.functions.tables.git
```


## Links

[Azure services that can use managed identities to access other services](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/managed-identities-status)

[What’s new in the Azure Functions Tables extension for](https://devblogs.microsoft.com/azure-sdk/whats-new-in-the-azure-functions-tables-extension-for-net-beta)