Configurar una Azure Storage Account con un private endpoint y reglas de firewall con Azure CLI

Revisando la documentación de Azure Storage me he dado cuenta de que no existe una guía de cómo configurar una cuenta de almacenamiento con un private endpoint y reglas de firewall, que te permitan acceder a la misma desde tu ubicación, con Azure CLI. En este artículo te comparto cómo lo he hecho.

Nota: En este ejemplo estoy usando como base el artículo donde configuro un App Service con private endpoint y tengo una máquina de salto en la misma red.

Crear la cuenta de almacenamiento

Para este escenario, lo único que hago diferente cuando creo la cuenta es añadir el parámetro –default-action a Deny:

STORAGE_ACCOUNT_NAME="internalstore"
# Create the storage account
az storage account create \
--name $STORAGE_ACCOUNT_NAME \
--resource-group $RESOURCE_GROUP \
--location $LOCATION \
--sku Standard_LRS \
--default-action Deny 

De esta manera me aseguro de que no haya acceso desde el exterior nada más crearla. Para comprobarlo puedes usar la herramienta Azure Storage Explorer desde tu máquina y al intentar acceder al contenido de la misma recibirás un error:

Error de Azure Storage Explorer al intentar acceder a una cuenta de almacenamiento con el acceso restringido

Crear una subnet dentro de la red desde la que se va a consumir

Lo siguiente que debes hacer es crear una subnet en la red desde la que quieres utilizar el recurso:

STORAGE_SUBNET_NAME="storage-subnet"
STORAGE_SUBNET_CIDR=10.10.5.0/24
# Create a subnet for the storage account
az network vnet subnet create \
--name $STORAGE_SUBNET_NAME \
--resource-group $RESOURCE_GROUP \
--vnet-name $WEB_APP_VNET_NAME \
--address-prefixes $STORAGE_SUBNET_CIDR
# Disable private endpoint network policies
az network vnet subnet update \
--name $STORAGE_SUBNET_NAME \
--resource-group $RESOURCE_GROUP \
--vnet-name $WEB_APP_VNET_NAME \
--disable-private-endpoint-network-policies true

En este punto, es importante el parámetro –disable-private-endpoint-network-policies a true ya que de lo contrario lo siguiente te dará error al intentar crear el private endpoint.

Crear el private endpoint asociado a la cuenta de almacenamiento y a la subnet

Ahora que ya tienes la cuenta con el acceso exterior deshabilitado, crea el private endpoint que permitirá conectividad con la misma a través de la red elegida:

STORAGE_ACCOUNT_ID=$(az storage account show --name $STORAGE_ACCOUNT_NAME --resource-group $RESOURCE_GROUP --query id --output tsv)
# Create a private endpoint for the storage account
az network private-endpoint create \
--name $STORAGE_ACCOUNT_NAME-private-endpoint \
--resource-group $RESOURCE_GROUP \
--vnet-name $WEB_APP_VNET_NAME \
--subnet $STORAGE_SUBNET_NAME \
--connection-name "storage-connection" \
--private-connection-resource-id $STORAGE_ACCOUNT_ID \
--group-id blob

Crear un private DNS zone y asociarlo a la red

Por último, para que otros servicios puedan resolver correctamente la IP interna de la cuenta de almacenamiento falta por crear y configurar el Private DNS:

BLOB_PRIVATE_DNS_ZONE="privatelink.blob.core.windows.net"
# Create a DNS private zone
az network private-dns zone create \
--resource-group $RESOURCE_GROUP \
--name $BLOB_PRIVATE_DNS_ZONE
#link the private zone to the vnet
az network private-dns link vnet create \
--name "blob_private_dns" \
--resource-group $RESOURCE_GROUP \
--zone-name $BLOB_PRIVATE_DNS_ZONE \
--virtual-network $WEB_APP_VNET_NAME \
--registration-enabled false

Una vez creado, registra la IP privada de la cuenta de almacenamiento en el DNS:

# Register the storage account in the private DNS zone
# Get the ID of the azure storage NIC
STORAGE_NIC_ID=$(az network private-endpoint show --name $STORAGE_ACCOUNT_NAME-private-endpoint -g $RESOURCE_GROUP --query 'networkInterfaces[0].id' -o tsv)
# Get the IP of the azure storage NIC
STORAGE_ACCOUNT_PRIVATE_IP=$(az resource show --ids $STORAGE_NIC_ID --query 'properties.ipConfigurations[0].properties.privateIPAddress' --output tsv)
# create a record set for the storage account
az network private-dns record-set a add-record \
--record-set-name $STORAGE_ACCOUNT_NAME \
--resource-group $RESOURCE_GROUP \
--zone-name $BLOB_PRIVATE_DNS_ZONE \
--ipv4-address $STORAGE_ACCOUNT_PRIVATE_IP

A partir de este momento, si desde la máquina de salto ubicada en la misma red, intentas acceder a tu cuenta de almacenamiento con Azure Storage Explorer comprobarás que puedes hacerlo sin problemas. Por el contrario, todo acceso desde el exterior queda prohibido.

Permitir el acceso desde tu máquina local

Sin embargo, puede que tengas la necesidad de querer interactuar con la cuenta desde tu local o la IP de tu empresa. Para ello puedes añadir reglas al firewall incluyendo una o un rango de IPs:

# Get my public IP
HOME_IP=$(curl -s ipinfo.io/ip)
# Create a rule to access the storage account from a specific IP
az storage account network-rule add --resource-group $RESOURCE_GROUP --account-name $STORAGE_ACCOUNT_NAME --ip-address $HOME_IP
# List IP rules
az storage account network-rule list --resource-group $RESOURCE_GROUP --account-name $STORAGE_ACCOUNT_NAME --query ipRules

Si ahora vuelves a probar desde tu Azure Storage Explorer local verás que puedes acceder sin problemas.

¡Saludos!