Access Storage In Azure Function App With Managed Identity

Microsoft Azure Managed Identity is a service that provides Azure resources with an automatically managed identity in Azure Active Directory (Azure AD). You can use this identity to authenticate to any service that supports Azure AD authentication, without having to manage credentials.

Key Features of Azure Managed Identity

  1. Credential Management
    • Azure handles the lifecycle of these identities, ensuring that credentials are automatically managed and rotated.
  2. Two Types of Managed Identities
    • System-assigned Managed Identity: Automatically created when enabled on an Azure service instance. The lifecycle is tied to the lifecycle of this Azure service instance.
    • User-assigned Managed Identity: Created as a standalone Azure resource, independent of any particular service. It can be assigned to multiple Azure service instances.

Benefits

  • Security: Eliminates the need for hardcoded credentials in application code.
  • Ease of Use: Simplifies access to Azure resources by providing a straightforward and secure method of authentication.
  • Automatic Handling: Credentials are managed and rotated by Azure, reducing the administrative overhead.

Use Cases

  • Accessing Azure Key Vault: Retrieve secrets without storing sensitive credentials in code.
  • Connecting to Azure SQL Database: Authenticate and access databases securely.

Use Managed Identity in Azure Function

We have a Python program that would fetch the data from GraphQlAPI and place the file in Azure blob Storage and it would be stored with the help of Managed Identity.

Code that would be used to achieve the Managed Identity Authentication.

from azure.storage.blob import BlobServiceClient
from azure.identity import DefaultAzureCredential

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    try:
        #Input from the ADF body
        req_body = req.get_json()
        Blob_Path = req_body.get('BlobFilePath')
        File_Name = req_body.get('FileName')

    except Exception as e:
        logging.exception(str(e))
        print(e)
        return func.HttpResponse("Unable to parse body input.", status_code=406)

    # Sample function to fetch current user info. This will need to be changed in order to 
    current_user_data = fetch_Users(auth_token, User_List)

    File_Placement(current_user_data, BlobURL, Blob_Path, File_Name)
    File_upload(df_user_csv, blob_url, blob_path, file_name ) 
    return func.HttpResponse(
        # json.dumps(current_user_data),
        status_code=200
    )

#We Would be focusing on File_upload Which would upload the file on Azure Blob location
    
def File_upload(dataframe: pd.DataFrame, bloburl: str,blobpath: str, filename: str ):
    # FilePath creation
    file_nm = blobpath + filename
    try:
        output = dataframe.to_csv(index=False,encoding="utf-8",sep= '|')
    except Exception as e :
        pass
    try:
        # File uploaded to blob
        credential = DefaultAzureCredential()
        blob_service_client = BlobServiceClient(account_url=bloburl, credential=credential)
        container_name = 'Test'
        container_client = blob_service_client.get_container_client(container_name)
        blob_client = container_client.get_blob_client(file_nm)

        blob_client.upload_blob(output, overwrite=True)
        print(f'File {blobpath} uploaded')
    except Exception as e:
        raise Exception(
            f'Failed to upload file {blobpath}: {e}'
        )

We also need to switch on the identity option of Function App so that it can have a ID that would get a System Managed Identity access on Storage.

 Function App

Post We need to provide it access to a storage account which we can do from the Azure storage account giving it RBAC.

RBAC

This would help your Azure function to connect to a storage account without a SAS Token.