When building cloud-native applications, there are situations where an Azure Function still needs access to resources hosted on a local network or private server.

In my case, I had an Azure Function acting as a subscriber in a messaging system and calling an API hosted on an Ubuntu VPS. To make things work quickly during development, the API was temporarily exposed publicly through a reverse proxy.

Although functional, this approach was not ideal for production. The API was publicly reachable, even if protected, and the overall architecture felt more like a workaround than a proper solution.

The goal was simple: keep the API private while allowing an Azure Function to securely access it.

This is where Azure Hybrid Connections comes in.

The architecture

The flow looked like this:

Publisher Function
        ↓
Azure Service Bus Topic
        ↓
Subscriber Function (Premium)
        ↓
Azure Hybrid Connection
        ↓
Ubuntu VPS
        ↓
Local API

The subscriber receives a Service Bus message and then calls an API hosted on a private server.

Instead of exposing the API publicly through a reverse proxy, the communication happens through an outbound-only secure tunnel initiated by the server itself.

The first problem: Flex Consumption

My subscriber Function App was initially deployed using the Flex Consumption plan.

Unfortunately, Hybrid Connections are not supported for this scenario.

The solution was to create a new Function App using the Premium plan.

One important detail: you cannot directly convert a Flex Consumption Function App to Premium. A new Function App must be created and the code redeployed.

For testing purposes, I used:

Linux
Premium Plan
EP1

After deployment, I copied all existing environment variables from the original Function App.

Example:

TargetApiBaseUrl
TargetApiEquipmentPath
TargetApiLoginPath
TargetApiUsername
TargetApiPassword
ServiceBusConnection

Most values remained unchanged except for the API base URL, which would later point to the Hybrid Connection endpoint.

Creating the Azure Relay namespace

Hybrid Connections require an Azure Relay namespace.

In Azure Portal:

Create Resource
→ Relay

Configuration:

Pricing Tier: Standard
Region: Same as Function App

The namespace acts as the communication bridge between Azure and the server hosting the local API.

At first, the portal terminology was confusing because it asks for a Service Bus Namespace, but this is actually the Azure Relay namespace used internally by Hybrid Connections.

Creating the Hybrid Connection

Inside the Function App:

Networking
→ Hybrid Connections
→ Add Hybrid Connection
→ Create New Hybrid Connection

Initially, I tried using:

localhost
127.0.0.1

for the endpoint host.

Azure immediately rejects those values because reserved loopback addresses are not allowed.

Instead, a hostname must be used.

My final configuration looked like this:

Hybrid Connection Name:
mylocal-api

Endpoint Host:
mylocal-api.local

Endpoint Port:
8080

Service Bus Namespace:
relay-msg-dev

The hostname itself does not need to exist publicly, but it must resolve on the Linux server hosting the API.

Configuring Linux hostname resolution

On the Ubuntu VPS, I added a local hostname mapping.

Edit:

sudo nano /etc/hosts

Add:

127.0.0.1 mylocal-api.local

This makes the hostname resolve locally to the API running on the server.

Before moving further, I verified connectivity:

curl http://mylocal-api.local:8080/api/health

If this request fails locally, Hybrid Connections will also fail.

Installing Hybrid Connection Manager on Linux

The next step is installing the Hybrid Connection Manager (HCM).

First, install Azure CLI:

curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

Login:

az login

Then install HCM:

sudo apt update
sudo apt install tar gzip wget -y

wget https://download.microsoft.com/download/HybridConnectionManager-Linux.tar.gz
tar -xf HybridConnectionManager-Linux.tar.gz

cd HybridConnectionManager
chmod +x setup.sh

sudo ./setup.sh

Verify installation:

hcm --help

Adding the Hybrid Connection

Once installed:

hcm add

The command launches an interactive configuration.

Select:

  • Azure subscription
  • Relay namespace
  • Hybrid connection

Once completed:

hcm list

Expected result:

Status: Connected

This means Azure can now securely reach the local server.

Updating the Function App configuration

Finally, I updated the subscriber Function App environment variable:

Before:

https://public-api-url.com

After:

http://mylocal-api.local:8080

The rest of the settings remained unchanged.

Example:

TargetApiEquipmentPath=/api/equipment
TargetApiLoginPath=/api/login
TargetApiUsername=my-user
TargetApiPassword=my-password

One thing I noticed during testing: Azure Function environment variables can take a few minutes to refresh after changes.

Restarting the Function App helped force the configuration reload.

Function App
→ Restart

Troubleshooting

Here are the main issues I encountered.

Function not consuming Service Bus messages

At one point, messages were visible in the subscription, but the subscriber was not processing them.

The issue turned out to be stale environment variables.

Restarting the Function App and waiting a few minutes resolved the problem.

Hybrid Connection not working

Verify:

hcm list

The connection should show:

Connected

Then validate hostname resolution locally:

curl http://mylocal-api.local:8080/api/health

Reserved hostname error

If Azure says:

This name is reserved

avoid:

localhost
127.0.0.1

Use a hostname instead and map it in /etc/hosts.

Final thoughts

After implementing Hybrid Connections, the API no longer needed to be exposed publicly through a reverse proxy.

The Function App could securely access the local API while keeping everything private and outbound-only from the server.

Overall, the setup ended up being surprisingly clean once all the moving pieces were understood:

  • Azure Function Premium
  • Azure Relay
  • Hybrid Connection
  • Linux HCM
  • Local hostname resolution

If you are building Azure Functions that still need to interact with on-premise or privately hosted services, Hybrid Connections is definitely worth considering.