Table of Contents

    Book an Appointment

    How Did We Discover the Need for Azure Functions in Fabric Pipelines?

    While working on an enterprise data modernization platform for a leading FinTech organization, we encountered a complex integration challenge. The system required pulling daily transaction data from third-party financial REST APIs into Microsoft Fabric for analytics and subsequently pushing aggregated risk models back to internal, highly secured APIs hosted within the same Azure cloud environment.

    Because financial data was in motion, the Chief Information Security Officer (CISO) mandated strict compliance: no API keys, no hardcoded secrets and no shared passwords. All service-to-service communication had to rely exclusively on Entra ID (formerly Azure AD) Managed Identities and Service Principals. We quickly realized that native Microsoft Fabric pipeline activities, at the time of architecture validation, presented limitations when executing complex, custom OAuth2 Entra ID flows against arbitrary external REST endpoints.

    This led our architecture team to design an adapter pattern using Azure Functions to proxy these requests. We are sharing this real-world experience because many teams face similar roadblocks. When companies hire software developer teams from us, they expect secure, compliant architectures. This challenge inspired this article to help other engineering leaders validate this pattern and implement it securely without compromising on enterprise authentication standards.

    Why Was Native REST API Integration Failing in Our Data Architecture?

    The business use case was straightforward on the surface: orchestrate data ingestion and egress via REST APIs natively within a data pipeline. In a traditional Azure Data Factory setup, one might use a Web Activity. In Microsoft Fabric, we attempted the same approach.

    However, the internal and external REST APIs we needed to interact with required specific Service Principal token acquisitions with custom audience scopes. Furthermore, our data egress scenarios required transforming the payload into a specific JSON hierarchy before making a POST request. The native Web Activity in Fabric either lacked the granular Managed Identity token exchange capabilities for these specific external audiences or required exposing credentials in configurations that violated our security policies. The pipelines simply could not authenticate natively to the downstream services using the required enterprise Service Principal standards.

    What Were the Bottlenecks When Connecting Fabric to Enterprise APIs?

    The symptoms surfaced early during the Proof of Concept (PoC) phase. When attempting to use the native pipeline activities, we encountered HTTP 401 Unauthorized and 403 Forbidden errors. The logs indicated that the access tokens being generated by the workspace identity did not match the required audience (aud) claims expected by the downstream APIs.

    Additionally, the egress APIs required pagination logic and rate-limit handling (HTTP 429 retries with exponential backoff) that were far too complex to handle cleanly within a standard declarative pipeline loop. Building massive, deeply nested pipeline logic to handle custom API authentication headers, error handling and payload mapping was becoming an architectural oversight that threatened the maintainability of the entire data platform.

    How Did We Evaluate Azure Functions as an API Adapter for Fabric?

    To resolve this, we evaluated several architectural approaches. Our primary goal was to offload the authentication and payload transformation complexities into a dedicated, scalable compute layer. We considered the following approaches before finalizing our design:

    Should We Use Standard Web Activities with Key Vault Integration?

    We initially explored using a Web Activity to fetch a token from a REST endpoint using client credentials stored in Azure Key Vault. While Fabric integrates with Key Vault, extracting the secret into the pipeline runtime memory to construct a subsequent API call exposed the secret temporarily in pipeline debug logs. This was rejected by the security team. Furthermore, it did not utilize true Managed Identity authentication from end to end.

    Could We Implement Custom Python Notebooks for API Calls?

    We considered using Fabric Notebooks (PySpark) to write custom code for the API calls. While perfectly capable of handling complex authentication using libraries like MSAL (Microsoft Authentication Library), spinning up a Spark compute pool for lightweight API polling and data pushing was massively inefficient. The latency and cost of starting Spark sessions for simple REST transactions made this an unviable pattern for our frequency requirements. Decision-makers who hire python developers for scalable data systems know that matching the compute engine to the workload is critical for cost optimization.

    Is a Logic App Layer More Suitable Than Azure Functions?

    We evaluated Azure Logic Apps, which offer excellent managed connectors. However, the external APIs we integrated with were highly custom, requiring complex C# data transformation logic before egress. Logic Apps would have required nested conditions and complex expression logic, which is difficult to version control and test via CI/CD compared to raw code.

    Ultimately, we chose Azure Functions. It provided serverless, instant-on compute, native support for Managed Identity and allowed us to write clean, unit-testable C# code to handle the API interactions.

    How Did We Implement Managed Identity Between Fabric and Azure Functions?

    The final implementation relied on an “Adapter Pattern” where the Azure Function acts as a secure proxy. But how does Fabric authenticate with the Azure Function?

    The solution involves two distinct layers of Entra ID authentication:

    • Fabric to Azure Function: We secured the Azure Function using Azure App Service Authentication (Easy Auth) tied to an Entra ID App Registration. We then configured the Fabric pipeline’s Web Activity to use Entra ID authentication. We specified the Fabric Workspace Identity (or a designated Service Principal) and targeted the Audience URI of the Azure Function’s App Registration. Fabric automatically fetches the token and passes it in the Authorization header.
    • Azure Function to Downstream REST APIs: The Azure Function runs with a System-Assigned Managed Identity. Inside the C# code, we utilized the DefaultAzureCredential class from the Azure.Identity SDK to seamlessly acquire tokens for the downstream APIs, both internal and external.

    Here is a sanitized snippet demonstrating how the Azure Function securely interacts with a downstream API using its Managed Identity:

    using Azure.Core;
    using Azure.Identity;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.Http;
    using Microsoft.AspNetCore.Http;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Threading.Tasks;
    public class ApiAdapterFunction
    {
        private readonly HttpClient _httpClient;
        public ApiAdapterFunction(IHttpClientFactory httpClientFactory)
        {
            _httpClient = httpClientFactory.CreateClient();
        }
        [FunctionName("ProcessDataEgress")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req)
        {
            // 1. The Function is protected by Azure Easy Auth (Entra ID)
            // Fabric pipeline has already authenticated to reach this point.
            // 2. Obtain Managed Identity token for the downstream API
            var credential = new DefaultAzureCredential();
            var tokenRequestContext = new TokenRequestContext(new[] { "api://downstream-enterprise-api/.default" });
            var tokenResult = await credential.GetTokenAsync(tokenRequestContext);
            // 3. Prepare the outbound request
            var outboundRequest = new HttpRequestMessage(HttpMethod.Post, "https://internal.enterprise.network/api/v1/data");
            outboundRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenResult.Token);
            
            // Add payload transformation logic here...
            // 4. Execute with retry logic (e.g., using Polly)
            var response = await _httpClient.SendAsync(outboundRequest);
            if (response.IsSuccessStatusCode)
            {
                return new OkObjectResult("Data securely processed and delivered.");
            }
            return new StatusCodeResult((int)response.StatusCode);
        }
    }
    

    This implementation effectively decoupled the data orchestration (Fabric) from the complex security and integration logic (Azure Functions). For organizations looking to hire dotnet developers for enterprise modernization, applying this separation of concerns is a foundational best practice.

    What Are the Key Engineering Lessons for API Patterns in Fabric?

    Deploying this pattern in a production enterprise environment yielded several critical lessons:

    • Embrace the Adapter Pattern: Do not force complex integration logic into data pipeline orchestration tools. Using Azure Functions as a proxy keeps your Fabric pipelines clean, declarative and focused on data movement.
    • Leverage Easy Auth: Relying on Azure App Service Authentication for the Function app completely removes the need to write custom token validation code in your Azure Function. It natively validates the token passed by Fabric.
    • Avoid Function Key Authentication: When integrating enterprise systems, avoid using standard Azure Function access keys in the URL query string. Always enforce Entra ID-based authentication to maintain auditability and compliance.
    • Implement Robust Retry Logic: Downstream APIs fail. We implemented the Polly library within our C# Azure Function to handle HTTP 429 rate limits and transient faults gracefully, shielding the Fabric pipeline from unnecessary failures.
    • Watch Your Timeouts: Standard Azure Functions have maximum timeout limits (typically 230 seconds for HTTP triggers). If your API interaction is long-running, consider transitioning to Durable Functions to return an immediate 202 Accepted status while processing in the background.
    • Mind the Compute Costs: By using serverless consumption plans for the Azure Function, we saved significantly compared to running API ingestion via PySpark. If you hire azure developers for scalable data systems, ensure they understand the cost implications of compute architectures.

    How Can Teams Accelerate Their Enterprise Azure Integrations?

    Integrating Microsoft Fabric pipelines with disparate REST APIs using Azure Functions is absolutely a viable, enterprise-grade pattern. It bridges the gap between data orchestration and complex security compliance requirements. By relying entirely on Managed Identities and Entra ID tokens, we successfully delivered a highly secure, scalable data architecture without compromising on CISO mandates.

    Designing and deploying these hybrid data architectures requires deep expertise in both data engineering and cloud-native application development. If your engineering teams are facing similar complex integration challenges and you are looking to scale your technical capabilities, contact us to explore how our pre-vetted remote development teams can accelerate your enterprise modernization.

    Social Hashtags

    #MicrosoftFabric #AzureFunctions #ManagedIdentity #MicrosoftEntraID #RESTAPI #APIIntegration #DataEngineering #AzureCloud #MicrosoftAzure #DataPipelines #CloudArchitecture #EnterpriseArchitecture #Serverless #CloudSecurity #DotNet #AzureDevelopers

     

    Frequently Asked Questions

    Success Stories That Inspire

    See how our team takes complex business challenges and turns them into powerful, scalable digital solutions. From custom software and web applications to automation, integrations, and cloud-ready systems, each project reflects our commitment to innovation, performance, and long-term value.