Search code examples
azureazure-functionsazure-data-factory

Azure Data Factory will not allow the Azure Function to initiate the run using managed ID


I'm trying to get a Function App to call a Data Factory, and it seems no matter what I do, The Data Factory tells me that I am not allowed:

2024-06-06T11:17:08Z   [Error]   (AuthorizationFailed) The client 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' with object id 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' does not have authorization to perform action 'Microsoft.DataFactory/factories/pipelines/createRun/action' over scope '/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/MyResourceGroup/providers/Microsoft.DataFactory/factories/my_factory/pipelines/get_file' or the scope is invalid. If access was recently granted, please refresh your credentials.
Code: AuthorizationFailed
Message: The client 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' with object id 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' does not have authorization to perform action 'Microsoft.DataFactory/factories/pipelines/createRun/action' over scope '/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/ZM-D365-Integration-DEV/providers/Microsoft.DataFactory/factories/zm-predev-danaostoazureinvoice-df/pipelines/get_invoive_from_danaos' or the scope is invalid. If access was recently granted, please refresh your credentials.
2024-06-06T11:17:08Z   [Error]   Failed to create data factory job Failed to run pipeline get_invoive_from_danaos
2024-06-06T11:17:08Z   [Error]   Executed 'Functions.invoice' (Failed, Id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, Duration=1849ms)

But I've even made the managed identity Data Factory Contriburot AND Contributor, just to see if I could get past this issue


Solution

  • Follow the below step by step process using Azure Python SDK to achieve your requirement.

    First enable the Managed identity in the Function app and give the Contributor role to it in ADF like below.

    enter image description here

    I have used some code from this source by @surasahoo and modified it as per the managed identity like below. It uses http trigger.

    function_app.py

    import azure.functions as func
    
    import logging
    from azure.identity import DefaultAzureCredential 
    from azure.mgmt.resource import ResourceManagementClient
    from azure.mgmt.datafactory import DataFactoryManagementClient
    from azure.mgmt.datafactory.models import *
    
    
    
    app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
    
    @app.route(route="http_trigger", auth_level=func.AuthLevel.FUNCTION)
    def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
        logging.info('Python HTTP trigger function processed a request.')
    
        sub_id = "<subscription_id>"
        rg_name = "<RG_name>"
        ADF_name = "<ADF_name>"
    
        credential = DefaultAzureCredential()
        resource_client = ResourceManagementClient(credential, sub_id)
        adf_client = DataFactoryManagementClient(credential, sub_id)
    
        myparams = {"parm1" : "Hello Rakesh"}
    
        pipeline_name = "<pipeline_name>"
    
        run_response = adf_client.pipelines.create_run(rg_name, ADF_name, pipeline_name,parameters=myparams)
    
        if run_response:
            return func.HttpResponse(f"{run_response}, Called pipeline successfully")
        else:
            return func.HttpResponse(
                 "Failed - This HTTP triggered function executed unsuccessfully",)
    

    Give the below packages in the requirement.txt.

    azure-functions
    azure-mgmt-resource
    azure-mgmt-datafactory
    azure-identity
    

    Make sure you publish your ADF pipeline to your recent changes as only last published pipeline only will be triggered.

    Run the code and ADF pipeline will be triggered like below.

    enter image description here

    Pipeline run:

    enter image description here

    enter image description here