Azure Bicep: Private Communication Between Azure Resources

Ajinkya Bhabal
6 min readMar 22, 2021
Use Private Endpoint for Azure Storage

Introduction

Nowadays most companies want their cloud resources to privately communicate with each other without going over the internet. Today we will focus on Microsoft Azure solutions.

The two of the services provided by azure to achieve this goal are,

  1. Private Endpoints
  2. Service Endpoints

In the above services, data will travel through the Microsoft Backbone Network.

So this article will cover making private the internet-facing public services like e.g. SQL Database, Storage Account, Web apps in Azure. The great thing is it can be access across different Virtual networks and from a Hybrid connected data center also.

The solution which I have given is based on an Azure storage account. There are different ways to deploy resources in Azure, here we have chosen the new approach Azure Bicep.

Part 1 — Private Endpoints

The private endpoint helps us to establish secure communication between resources running on a virtual network and storage account. All traffic will traverses over the VNET and Microsoft backbone network only. The private endpoint uses an IP address from the VNET address space for our storage account service. Besides resources from the on-premises network which are connected through VPN or ExpressRoute also get access to the storage service.

Now let’s begin with the actual implementation of the private endpoint with Azure bicep.

First Start Configuring the Virtual network for the private endpoint.

// All Parameters required for Network Deployment is given here.
param location string = resourceGroup().location
// All Variables required for Network Deployment is given here.
var virtualNetworkName = 'VNET01'
var addressPrefix = '10.50.0.0/16'
var subnetName = 'Subnet01'
var subnetPrefix = '10.50.1.0/24'
resource vn 'Microsoft.Network/virtualNetworks@2020-06-01' = {
name: virtualNetworkName
location: location
properties: {
addressSpace: {
addressPrefixes: [
addressPrefix
]
}
subnets: [
{
name: subnetName
properties: {
addressPrefix: subnetPrefix
privateEndpointNetworkPolicies: 'Disabled'
privateLinkServiceNetworkPolicies: 'Enabled'
}
}
]
}
}

The thing to notice here is Private Endpoint Network Policies are disabled because Network Security Group are not supported for private endpoint resource. Next Source IP address for private link service is automatically selected.

Note: This setting only applies to the Private endpoint resource.

In the second step Storage Account resource is configured.

// All Parameters required for Network Deployment is given here.
param location string = resourceGroup().location
param storageAccountName string = 'store38291'
param sku_name string = 'Standard_LRS'
resource stg 'Microsoft.Storage/storageAccounts@2019-06-01' = {
name: storageAccountName
location: location
sku: {
name: sku_name
tier: 'Standard'
}
kind: 'StorageV2'
properties: {
accessTier: 'Hot'
networkAcls: {
bypass: 'None'
defaultAction: 'Deny'
}
}
}

The point to note here is in Network ACL’s we have disabled everything, so only private endpoint resource will be attached to it.

In the third step, we will create a Private Endpoint resource along with its configuration.

// All Parameters required for Network Deployment is given here.
param location string = resourceGroup().location
// All Variables required for Network Deployment is given here.
var subnetName = 'Subnet01'
var subnetRef = '${vn.id}/subnets/${subnetName}'
resource privateEndpoint 'Microsoft.Network/privateEndpoints@2020-06-01' = {
name: 'PrivateEndpoint1'
location: location
properties: {
subnet: {
id: subnetRef
}
privateLinkServiceConnections: [
{
properties: {
privateLinkServiceId: stg.id
groupIds: [
'blob'
]
}
name: 'PrivateEndpoint1'
}
]
}
}

Following three things on which we need to be focused on for the configuration,

i. Subnet ID

ii. Storage Account ID

iii. Type of Service or Sub Resource — Blob

resource privateDnsZones 'Microsoft.Network/privateDnsZones@2018-09-01' = {
name: 'privatelink.blob.core.windows.net'
location: 'global'
properties: {}
}
resource privateDnsZoneLink 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2018-09-01' = {
name: '${privateDnsZones.name}/${privateDnsZones.name}-link'
location: 'global'
properties: {
registrationEnabled: false
virtualNetwork: {
id: vn.id
}
}
}
resource privateDnsZoneGroup 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2020-06-01' = {
name: '${privateEndpoint.name}/dnsgroupname'
properties: {
privateDnsZoneConfigs: [
{
name: 'config1'
properties: {
privateDnsZoneId: privateDnsZones.id
}
}
]
}
}

After setting up the private endpoint, Next will be Private DNS Zones using which DNS resolution will be performed to reach to the storage account service.

There’s a strict requirement from Microsoft azure to use “privatelink.blob.core.windows.net” DNS zone name for blob services.

In the DNS Zones Linking Virtual Network is Key element because after linking only connected resource can reach the storage service.

Now let’s deploy these resources in our environment. The Bicep file has been compiled here.

After Generating ARM Template resources are deployed through it.

Take a look at all deployed resources in the portal.

Check for Network Interface Card deployment in the VNET.

The most important thing to check now here is configured private endpoint in the storage account.

After checking connection, let’s see the configuration of the Private endpoint.

Next is DNS Configuration where we will see the important configuration.

In the DNS Zone we can see A Record is automatically added for Storage URL.

Last, But very important Linking of an Virtual Network to the Private DNS Zone.

Part 2 — Service Endpoints

The Virtual Network’s Service endpoint communication also done securely over Azure Backbone Network to Internet facing public services. The big difference here is critical Azure Resources can only accessed through connected virtual network subnets.

Lets begin with Azure bicep based configuration, first resource will be Azure Virtual Network.

// All Variables required for Network Deployment is given here.
var subnetName = 'SP_Subnet01'
var subnetRef = '${vn.id}/subnets/${subnetName}'
resource vn 'Microsoft.Network/virtualNetworks@2020-06-01' = {
name: 'SP_VNET01'
location: resourceGroup().location
properties: {
addressSpace: {
addressPrefixes: [
'10.60.0.0/16'
]
}
subnets: [
{
name: subnetName
properties: {
addressPrefix: '10.60.1.0/24'
serviceEndpoints: [
{
service: 'Microsoft.Storage'
}
]
}
}
]
}
}

The Key thing to notice here is, “Microsoft.Storage” service is enabled in the Service endpoint section so Storages can configured for Service Endpoints.

The Second resource storage account will be configured,

// All Variables required for Network Deployment is given here.
var subnetName = 'SP_Subnet01'
var subnetRef = '${vn.id}/subnets/${subnetName}'
resource stg 'Microsoft.Storage/storageAccounts@2019-06-01' = {
name: 'store38291'
location: resourceGroup().location
sku: {
name: 'Standard_LRS'
tier: 'Standard'
}
kind: 'StorageV2'
properties: {
accessTier: 'Hot'
networkAcls: {
bypass: 'None'
virtualNetworkRules: [
{
id: subnetRef
action: 'Allow'
}
]
defaultAction: 'Deny'
}
}
}

Here in the Storage Network Access control policy, Subnet ID is provided. So that only resources in that subnet can access storage accounts.

It’s time to run this bicep code now, First we create resource group and then build the bicep file for deployment.

Bicep build .\main.bicep

After build ARM Template has been generated from which we will start the deployment.

New-AzResourceGroupDeployment -TemplateFile "./main.json" -ResourceGroupName "SE-RG01" -Confirm -Mode "Complete"

After deployment let’s take a look at the Networking of Storage account.

Conclusion

As Cloud is becoming popular day by day, Security is the most important aspect that people often do not care mostly. The thing which we need to remember is its shared responsibility. Hope you like this session on secure communication between azure resources. Don’t wait, just get start along with me. If you have any feedback or suggestions you can ask in the comments.

--

--