Skip to content

Instantly share code, notes, and snippets.

@anuchandy
Last active October 27, 2022 01:05
Show Gist options
  • Save anuchandy/3a2c6d06e851509c31098d3f1cea30fc to your computer and use it in GitHub Desktop.
Save anuchandy/3a2c6d06e851509c31098d3f1cea30fc to your computer and use it in GitHub Desktop.

Private Endpoint enabled Event Hubs

Enabling Private Endpoint assigns a Private IP from a subnet in an Azure Virtual Network to the Event Hubs.

If we enable Private Endpoint and configure the Event Hubs to restrict all public access, then only the hosts (e.g., VM) belonging to a subnet in the same virtual network can access the Event Hubs.

It means we can run Azure Event Hubs SDK in such a VM to access the Event Hubs securely. A DNS lookup from the VM for FQDN of the Event Hubs will get resolved to the Private IP assigned to the Event Hubs.

nslookup <eventhubs-namespace>.servicebus.windows.net
Non-authoritative answer: 
Name: <eventhubs-namespace>.privatelink.servicebus.windows.net Address: 10.0.1.4
Aliases: <eventhubs-namespace>.servicebus.windows.net

where 10.0.1.4 is the private IP address associated with the private endpoint.

Application Gateway and Private Endpoint enabled Event Hubs

This section describes the setup to access Private Endpoint enabled Event Hubs through the "Public IP" of the Application Gateway.

First, ensure you meet all prerequisites. For that, follow everything documented in the Gist AzureEventHubsJavaSDKCustomEndpointWebSockets.md and confirm the environment running Azure Event Hubs SDK and Application Gateway is configured correctly.

Enabling Private IP for Event Hubs

The Application Gateway has an Azure Virtual Network associated with it. We saw in the Gist AzureEventHubsJavaSDKCustomEndpointWebSockets.md that the Application Gateway uses a subnet from this Virtual Network.

AppGatewayVNet

By design, Application Gateway requires a dedicated subnet (default in the example). We'll need a new subnet in the same Virtual Network to allocate Private IP for the Event Hubs, so create one.

In the Create-Subnet wizard, choose "Enabled" for the "Private endpoint network policy" field.

VNetForPrivateIP

We have two subnets in the VNet - the old subnet (default) associated with the App Gateway and the new one (subnet2) that we will use for Event Hub's Private IP.

VNetFinal

Follow the official document to enable Private IP for the Event Hubs (The Event Hubs we associated with the Application Gateway in the Gist AzureEventHubsJavaSDKCustomEndpointWebSockets.md).

In the "Virtual Network" Tab (of Private IP creation), choose the Azure Virtual Network and the new subnet created above (subnet2).

Follow the rest of that official document and complete Event Hubs Private IP association.

Confirm that we see the private endpoint connection created shows up in the list of endpoints.

EventHubsNW_PrivateEndpoint

Also, check the private DNS Zone resource, where we'll see the Event Hubs namespace name and Private IP allocated (e.g. 10.0.1.4).

PrivateDNSResource

Adding Private IP to AppGateway's Backend Pool

Go to the AppGateway Backend Pool and update it to use the Private IP (e.g., 10.0.1.4) [ Earlier, in AzureEventHubsJavaSDKCustomEndpointWebSockets.md, it was the FQDN of the Event Hubs <eventubs-namespace>.servicebus.windows.net]

Further testing showed that we could continue to keep the FQDN in backend pool and do not need to replace it with the Private IP. Keeping this section in strikethrough form.

AppGWBackendSettingsPrivateIP

Updating AppGateway's Backend settings

Go to AppGateway Backend settings

  1. For "Host name override" option, choose "Override with specific domain name"
  2. For "Host Name" provide FQDN (in the form <eventubs-namespace>.servicebus.windows.net) of the Event Hubs.

AppGWBackendSettings

Backend Health

The Portal gives the option to test if the backend is healthy, i.e., if the target (i.e., Private IP 10.0.1.4) can respond to HTTPS GET on port 443.

BackendHealth

Testing in browser

If all the configurations are correct, then the "Public IP" will be reachable at port 443 through the browser.

Browser

That's It

At this point, the same java code in the previous Gist AzureEventHubsJavaSDKCustomEndpointWebSockets.md can connect to Private IP enabled Event Hubs through the AppGateway "Public IP" address.

List<EventData> telemetryEvents = Arrays.asList(
        new EventData("Roast beef".getBytes(UTF_8)),
        new EventData("Cheese".getBytes(UTF_8)),
        new EventData("Tofu".getBytes(UTF_8)),
        new EventData("Turkey".getBytes(UTF_8)));


AzureNamedKeyCredential credential = new AzureNamedKeyCredential("RootManageSharedAccessKey", 
        "<Shared Access Policy Primary or Secondary Key from the Portal>");

EventHubProducerClient producer = new EventHubClientBuilder()
        .credential("<eventubs-namespace>.servicebus.windows.net", "<eventhubs-name>", credential)
        .customEndpointAddress("https://<public-ip-of-app-gateway>") // e.g. "https://20.232.196.115"
        .transportType(AmqpTransportType.AMQP_WEB_SOCKETS)
        .buildProducerClient();

EventDataBatch currentBatch = producer.createBatch();

for (EventData event : telemetryEvents) {
    if (currentBatch.tryAdd(event)) {
        continue;
    }

    producer.send(currentBatch);
    currentBatch = producer.createBatch();

    if (!currentBatch.tryAdd(event)) {
        System.err.printf("Event is too large for an empty batch. Skipping. Max size: %s. Event: %s%n",
                currentBatch.getMaxSizeInBytes(), event.getBodyAsString());
    }
}

producer.send(currentBatch);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment