Integrating Power BI with Databricks Model Serving in Secure Networks Using Logic Apps and Power Automate

Introduction

Watch this as a video on our you tube channel JBSWiki.

Many enterprises are rapidly adopting Azure Databricks for building machine learning models and serving real-time predictions. However, when strict network security measures are in place—like disabling public network access on Databricks workspaces—it can become incredibly challenging to integrate those models into tools like Power BI.

In this blog, we’ll explore how to securely call a Databricks Model Serving endpoint from Power BI under the scenario where:

  • The Databricks workspace has Allow Public Network Access = Disabled
  • Any direct call from Power Automate to Databricks fails with a 403 Unauthorized network access error

We’ll overcome this limitation using Logic Apps running inside a Virtual Network (VNet) and acting as a secure bridge between Power BI and Databricks.

Let’s dive in! 🔍


The Challenge: Network Restrictions and 403 Errors

By default, services like Power Automate send traffic over the public internet. If your Databricks workspace is configured with Allow Public Network Access disabled, any direct HTTP request to its REST APIs from Power Automate will fail.

The result is a 403 Unauthorized network access to workspace error.

This happens because Databricks:

  • Blocks all public network traffic
  • Only allows communication from services or VNets that are directly peered or integrated

In highly secure enterprise environments, keeping Databricks private is essential. But it poses a problem:

How can Power BI users trigger predictions from Databricks ML models if public access is disabled?


The Solution: Introducing Logic Apps as a Secure Proxy

Instead of connecting Power Automate directly to Databricks, we introduce Logic Apps running inside an Azure VNet.

Logic Apps can:

✅ Connect to Databricks Model Serving endpoints privately through peered VNets or private endpoints
✅ Expose an HTTP endpoint that Power Automate can call publicly
✅ Act as a secure proxy, handling all authentication and network routing

This architecture ensures:

  • Network security compliance
  • Seamless integration between Power BI and Databricks
  • Avoidance of 403 errors

Let’s walk through the full solution step by step. 🚀


Solution Architecture

Here’s how the integration flows:

  1. User clicks a button in Power BI ➡ triggers Power Automate.
  2. Power Automate ➡ sends an HTTP POST request to Logic Apps.
  3. Logic Apps ➡ securely calls the Databricks Model Serving endpoint within the VNet.
  4. Databricks Model Serving ➡ returns prediction results to Logic Apps.
  5. Logic Apps ➡ sends the response back to Power Automate.
  6. Power Automate ➡ updates Power BI visuals or datasets with prediction results.

This ensures Databricks never exposes its endpoints publicly, yet Power BI can still retrieve real-time predictions.


Step 1 — Create Databricks Model Serving Endpoint

First, make sure you’ve deployed your machine learning model to a Databricks Model Serving endpoint.

For this blog, let’s assume you’ve published an endpoint like:

https://adb-1311343844234579.11.azuredatabricks.net/serving-endpoints/HDFC_High_price_prediction/invocations

This endpoint:

  • Requires authentication via a Databricks PAT (Personal Access Token) or Azure AD token.
  • Accepts JSON requests.
  • Returns prediction results in JSON format.

Remember, because public network access is disabled, only resources inside your VNet—or peered VNets—can reach this endpoint.


Step 2 — Create Logic Apps in VNet

Next, deploy a Logic App Standard into a VNet.

Benefits:

  • Can communicate privately with Databricks.
  • Supports secure inbound and outbound traffic.
  • Scales to enterprise workloads.

Create an HTTP Trigger

Configure Logic Apps to start on an HTTP request.

Request Body JSON Schema for our scenario looks like this:

{
  "type": "object",
  "properties": {
    "inputs": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "Date": {
            "type": "string"
          },
          "OPEN": {
            "type": "integer"
          },
          "HIGH": {
            "type": "integer"
          },
          "LOW": {
            "type": "integer"
          },
          "CLOSE": {
            "type": "integer"
          }
        },
        "required": [
          "Date",
          "OPEN",
          "HIGH",
          "LOW",
          "CLOSE"
        ]
      }
    }
  }
}

his defines the expected JSON payload your Logic App will receive from Power Automate.


Step 3 — Logic Apps: Call Databricks Model Serving

Inside Logic Apps, add an HTTP action to call your Databricks endpoint:

Method: POST
URI:

https://adb-1311343844234579.11.azuredatabricks.net/serving-endpoints/HDFC_High_price_prediction/invocations

Headers:

Authorization: Bearer dapi****************
Content-Type: application/json

Body:

{
  "inputs": [
    {
      "Date": "2024-07-03",
      "OPEN": 2300,
      "HIGH": 2400,
      "LOW": 2298,
      "CLOSE": 2350
    }
  ]
}

Logic Apps will securely send this payload over private networking to Databricks and wait for the response.


Step 4 — Deploy Power Automate Flow

Now, let’s connect Power Automate to Logic Apps.

Your Power Automate flow will:

  • Trigger from Power BI (e.g. a button click).
  • Call the Logic Apps HTTP endpoint.
  • Receive the ML prediction results.
  • Optionally, update Power BI visuals or datasets.

Power Automate HTTP Request

Configure your HTTP action:

Method: POST
URI: The URL from your Logic App’s HTTP trigger (Step 1).
Headers:

Content-Type: application/json

Body:

{
  "inputs": [
    {
      "Date": "2024-07-03",
      "OPEN": 2300,
      "HIGH": 2400,
      "LOW": 2298,
      "CLOSE": 2350
    }
  ]
}

Why Not Call Databricks Directly From Power Automate?

A natural question is: why can’t we skip Logic Apps and call Databricks directly from Power Automate?

Here’s why:

  • Power Automate sends HTTP requests from public endpoints.
  • Databricks rejects all public traffic if public access is disabled.
  • There’s no way for Power Automate to reach Databricks privately.

Logic Apps in a VNet acts as a secure intermediary:

  • Power Automate → Logic Apps → Databricks
  • Databricks → Logic Apps → Power Automate

This architecture bridges private and public networks securely.


Benefits of This Architecture

Implementing this solution provides:

Enterprise Security

  • Complies with strict network isolation policies.
  • Prevents exposing Databricks to the internet.

Seamless User Experience

  • Power BI users get real-time predictions without knowing about the backend complexity.

Scalable Architecture

  • Logic Apps can handle thousands of requests.
  • Easy to maintain and extend for other models or services.

Governance and Monitoring

  • Centralized logging in Logic Apps.
  • Easy to integrate with Azure Monitor for alerting.

Use Case: Predicting Stock Prices

Imagine you have a machine learning model predicting HDFC high prices.

  • Power BI user clicks a “Predict” button.
  • Power Automate triggers a flow.
  • Flow sends stock price inputs to Logic Apps.
  • Logic Apps calls Databricks Model Serving.
  • Databricks returns the predicted high price.
  • Power BI visual updates dynamically with the prediction!

All of this happens securely, without exposing Databricks to the public internet. 🔒


Conclusion

Integrating Power BI with Databricks Model Serving under strict network security constraints can seem daunting.

But with the help of Logic Apps deployed inside a VNet, you can:

  • Securely bridge public and private networks
  • Enable real-time ML predictions in Power BI
  • Maintain enterprise-level security and compliance

Thank You,
Vivek Janakiraman

Disclaimer:
The views expressed on this blog are mine alone and do not reflect the views of my company or anyone else. All postings on this blog are provided “AS IS” with no warranties, and confers no rights.


Azure Databricks Series: Hands-On Machine Learning for Stock Prediction

Introduction

In today’s data-driven world, machine learning (ML) plays a crucial role in predictive analytics. One of the most popular use cases is stock price prediction, where ML algorithms analyze historical data to forecast future trends. In this blog, we will explore how to leverage Azure Databricks for stock price prediction using machine learning.

📺 Watch the full tutorial video here

📂 Download the code file from here


Why Use Azure Databricks for Machine Learning?

Azure Databricks provides a powerful environment for big data processing, machine learning, and real-time analytics. Here are some key reasons why it is ideal for ML-based stock prediction:

  • Scalability – Handles large volumes of historical stock data efficiently.
  • Integration – Seamlessly connects with Azure Storage, Delta Lake, and MLflow.
  • Collaborative Environment – Supports teamwork with shared notebooks and version control.
  • High Performance – Optimized for distributed computing and deep learning workloads.

Workflow for Stock Price Prediction

The machine learning workflow in Azure Databricks for stock prediction involves multiple steps:

Step 1: Data Collection

Stock market data is gathered from a financial data provider. Typically, historical stock prices include:

  • Date
  • Open price
  • High price
  • Low price
  • Close price
  • Volume traded

Step 2: Data Preprocessing

To ensure accurate predictions, the raw data undergoes preprocessing:

  • Handling missing values
  • Normalizing stock prices
  • Converting date-time format
  • Feature engineering to extract trends and patterns

Step 3: Storing Data in a Delta Table

Azure Databricks supports Delta Lake, an optimized storage layer for big data analytics. The cleaned dataset is stored in a Delta Table, which ensures:

  • ACID transactions for data integrity
  • Scalability to handle large datasets
  • Versioning for better data management

Step 4: Model Selection & Training

For stock prediction, various machine learning models can be used, such as:

  • Linear Regression – Suitable for trend analysis.
  • Random Forest – Effective for capturing non-linear relationships.
  • LSTM (Long Short-Term Memory) – A deep learning model ideal for time-series forecasting.

The model is trained using historical data, and performance is evaluated using metrics like Mean Squared Error (MSE) and R-Squared.

Step 5: Predicting Future Stock Prices

Once the model is trained, it is used to predict next-day stock prices based on recent trends.

Step 6: Visualization & Insights

The predicted prices are visualized using interactive charts and graphs to compare with actual values. This helps in understanding the performance of the model and refining future predictions.


Challenges in Stock Price Prediction

While ML provides valuable insights, predicting stock prices has inherent challenges:

  • Market Volatility – Prices can fluctuate due to unforeseen events.
  • External Factors – News, political events, and investor sentiment impact prices.
  • Overfitting – Models may perform well on historical data but struggle with real-world scenarios.

Despite these challenges, machine learning helps traders and investors make informed decisions based on data-driven insights.


Conclusion

Azure Databricks provides a robust, scalable, and efficient platform for stock price prediction using machine learning. By leveraging its powerful data processing capabilities and ML frameworks, we can build accurate and insightful models to analyze stock trends.

📺 Watch the complete tutorial here

📂 Download the code file from here

Stay tuned for more Azure Databricks tutorials in this series! 🚀

Azure Data Factory Series: Invoke ADF Pipeline from App Service with User-Assigned Managed Identity

Watch the step by step implementation as a You tube Video.

Step 1: Create an Azure App Service (Web App)

  1. Go to Azure Portal → Search for “App Services” → Click “Create”.
  2. Choose Subscription and Resource Group (or create a new one).
  3. Set the following values:
    • Name: my-adf-web-app
    • Publish: Code
    • Runtime Stack: .NET 8 (or any preferred language)
    • Operating System: Windows or Linux
    • Region: Choose a region close to your resources.
    • Plan: Choose a basic plan (B1) for testing.
  4. Click Review + Create → Click Create.

Step 2: Enable Managed Identity for Web App

  1. In Azure Portal, go to App Services → Select my-adf-web-app.
  2. Click on Identity under Settings.
  3. Under User Assigned, toggle the switch to On.
  4. Click Save, and copy the Client ID (you’ll need it later).

Step 3: Grant Permissions to Managed Identity on ADF

  1. Go to Azure Data Factory in the Azure Portal.
  2. Click on Access Control (IAM) → Click Add Role Assignment.
  3. Select:
    • Role: Data Factory Contributor (or Data Factory Operator for limited access).
    • Assign Access To: Managed Identity.
    • Select Members: Choose your Web App (my-adf-web-app).
  4. Click Save.

Step 4: Write Code in Azure App Service to Call ADF Pipeline

Use the following C# code inside your Web App to invoke the ADF pipeline using Managed Identity.

C# Code (ASP.NET Core)

using Microsoft.AspNetCore.Mvc;
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.DataFactory;
using System.Threading.Tasks;
using System.Collections.Generic;
using System;

[Route("JB/[controller]")]
[ApiController]
public class ADFController : ControllerBase
{
    private readonly ArmClient _armClient;
    private readonly string _subscriptionId = "xxxx-xxxxx-xxxxx-xxxxx";
    private readonly string _resourceGroupName = "jbadf";
    private readonly string _dataFactoryName = "jbadfapp";
    private readonly string _pipelineName = "jb_Copydata";

    public ADFController()
    {
        // Set the Client ID of the User-Assigned Managed Identity (UMI)
        var userAssignedClientId = "xxxx-xxxxx-xxxxx-xxxxx"; // Replace this with actual Client ID

        var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
        {
            ManagedIdentityClientId = userAssignedClientId
        });

        _armClient = new ArmClient(credential);
    }

    [HttpGet("CuriousBoy")]
    public async Task<IActionResult> TriggerPipeline()
    {
        try
        {
            // Construct the pipeline resource ID
            var pipelineResourceId = DataFactoryPipelineResource.CreateResourceIdentifier(
                _subscriptionId, _resourceGroupName, _dataFactoryName, _pipelineName);

            // Get the pipeline resource
            var pipelineResource = _armClient.GetDataFactoryPipelineResource(pipelineResourceId);

            // Define pipeline parameters (if required)
            var parameters = new Dictionary<string, BinaryData>
            {
                // Example: If your pipeline requires parameters, add them here.
                // { "param1", BinaryData.FromString("value1") },
                // { "param2", BinaryData.FromString("value2") }
            };

            // Trigger the pipeline run
            var runResponse = await pipelineResource.CreateRunAsync(parameters);

            return Ok($"ADF Pipeline triggered successfully on {DateTime.UtcNow}");
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Error triggering ADF pipeline: {ex.Message}");
        }
    }
}

Step 5: Deploy the Code to Azure App Service

  1. In Visual Studio, create an ASP.NET Core Web API project.
  2. Copy the above C# code into your Controller or Service.
  3. Deploy your code to Azure App Service using:
    • Right-click on the projectPublishAzure App Service.

Step 6: Test the Web App

  1. Navigate to https://my-adf-web-app.azurewebsites.net.
  2. Trigger the endpoint that executes the above code.
  3. Your ADF pipeline should now run successfully!

This is the simplest way to invoke an ADF pipeline from Azure App Services using Managed Identity.

Possible Errors Expected,

Error triggering ADF pipeline: DefaultAzureCredential failed to retrieve a token from the included credentials. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/defaultazurecredential/troubleshoot

  • EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshoot
  • WorkloadIdentityCredential authentication unavailable. The workload options are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/workloadidentitycredential/troubleshoot
  • ManagedIdentityCredential authentication unavailable. No response received from the managed identity endpoint.
  • VisualStudioCredential authentication failed: Visual Studio Token provider can’t be accessed at D:DWASFilesSitesJBAPPLocalAppData.IdentityServiceAzureServiceAuthtokenprovider.json
  • AzureCliCredential authentication failed: Azure CLI not installed
  • AzurePowerShellCredential authentication failed: Az.Accounts module >= 2.2.0 is not installed.
  • AzureDeveloperCliCredential authentication failed: Azure Developer CLI could not be found.

Error triggering ADF pipeline: The client ’66a2225c-f1b5-439b-b375-78ae2b744f2f’ with object id ’66a2225c-f1b5-439b-b375-78ae2b744f2f’ does not have authorization to perform action ‘Microsoft.DataFactory/factories/pipelines/createRun/action’ over scope ‘/subscriptions/xxxx-xxxx-xxxx/resourceGroups/jbadf/providers/Microsoft.DataFactory/factories/jbadfapp/pipelines/jb_Copydata’ or the scope is invalid. If access was recently granted, please refresh your credentials.
Status: 403 (Forbidden)
ErrorCode: AuthorizationFailed

Content:
{“error”:{“code”:”AuthorizationFailed”,”message”:”The client ’66a2225c-f1b5-439b-b375-78ae2b744f2f’ with object id ’66a2225c-f1b5-439b-b375-78ae2b744f2f’ does not have authorization to perform action ‘Microsoft.DataFactory/factories/pipelines/createRun/action’ over scope ‘/subscriptions/xxxx-xxxx-xxxx/resourceGroups/jbadf/providers/Microsoft.DataFactory/factories/jbadfapp/pipelines/jb_Copydata’ or the scope is invalid. If access was recently granted, please refresh your credentials.”}}

Headers:
Cache-Control: no-cache
Pragma: no-cache
x-ms-failure-cause: REDACTED
x-ms-request-id: 896c9766-5ee3-4dbb-b3b6-71800e2ee564
x-ms-correlation-request-id: REDACTED
x-ms-routing-request-id: REDACTED
Strict-Transport-Security: REDACTED
X-Content-Type-Options: REDACTED
X-Cache: REDACTED
X-MSEdge-Ref: REDACTED
Date: Tue, 18 Feb 2025 08:23:20 GMT
Content-Length: 512
Content-Type: application/json; charset=utf-8
Expires: -1

Thank You,
Vivek Janakiraman

Disclaimer:
The views expressed on this blog are mine alone and do not reflect the views of my company or anyone else. All postings on this blog are provided “AS IS” with no warranties, and confers no rights.