diff --git a/content/nginxaas-azure/quickstart/hosting-static-content-blob-storage.md b/content/nginxaas-azure/quickstart/hosting-static-content-blob-storage.md new file mode 100644 index 000000000..1174d57e2 --- /dev/null +++ b/content/nginxaas-azure/quickstart/hosting-static-content-blob-storage.md @@ -0,0 +1,171 @@ +--- +title: Hosting static content in Azure Blob Storage +weight: 210 +toc: true +url: /nginxaas/azure/quickstart/hosting-static-content-blob-storage/ +type: +- how-to +--- + +F5 NGINXaaS for Azure (NGINXaaS) can serve static content stored in Azure Blob Storage using private endpoints, ensuring maximum security by keeping your storage account completely inaccessible from the public Internet. This approach also eliminates the configuration payload size limitations of local hosting. + +## Before you begin + +- [An Azure Storage Account](https://learn.microsoft.com/en-us/azure/storage/common/storage-account-create) +- [An NGINXaaS for Azure deployment]({{< ref "/nginxaas-azure/getting-started/create-deployment" >}}) +- [A virtual network with available subnet space for private endpoints](https://learn.microsoft.com/en-us/azure/virtual-network/quick-create-portal) +- Static content files to serve + +## Configure Azure Blob Storage + +### Upload static files to a container + +Upload your static files to a container in your storage account. In this example, we'll use a container named `content`. + +### Disable public network access + +1. In your storage account, navigate to **Networking** under **Security + networking**. +1. Under **Public network access**, select **Disable**. +1. Click **Save**. + +### Disable anonymous blob access + +1. In your storage account, navigate to **Configuration** under **Settings**. +1. Find the **Allow Blob anonymous access** setting and set it to **Disabled**. +1. Click **Save**. + +### Set container access level to private + +1. Navigate to **Containers** under **Data management**. +1. Select your container (for example, `content`). +1. Click **Change access level**. +1. Set **Anonymous access level** to **Private (no anonymous access)**. +1. Click **OK**. + +### Create a new subnet for private endpoint NICs + +1. Navigate to your virtual network where NGINXaaS is deployed. +1. Go to **Subnets** under **Settings**. +1. Click **+ Subnet**. +1. Create a new subnet which will be used to assign IP address to your Private Endpoint NIC. +1. Make a note of the subnet name for the next step. + +### Create a private endpoint + +1. In your storage account, navigate to **Networking** under **Security + networking**. +1. Go to the **Private endpoint connections** tab. +1. Click **+ Private endpoint**. +1. Configure the private endpoint: + - **Name**: Provide a descriptive name for the private endpoint + - **Network Interface Name**: Provide a name for the network interface + - **Target sub-resource**: Select **blob** + - **Virtual network**: Select the same virtual network as your NGINXaaS deployment + - **Subnet**: Select the subnet created in the previous step + - **Private DNS integration**: Enable this option to automatically create DNS records + +### Generate a Shared Access Signature (SAS) token + +1. In your storage account, navigate to **Shared access signature** under **Security + networking**. +1. Configure the SAS token with minimal required permissions: + - **Allowed services**: Check **Blob** + - **Allowed resource types**: Check **Object** + - **Allowed permissions**: Check **Read** only + - **Start and expiry date/time**: Set appropriate validity period + - **Allowed protocols**: Select **HTTPS only** +1. Click **Generate SAS and connection string**. +1. Copy the **SAS token** (the part starting with `?sv=`). + +{{< call-out "important" >}}Store the SAS token securely and regenerate it regularly according to your security policies. Grant only the minimum permissions required for your use case.{{< /call-out >}} + +## Configure NGINXaaS + +Create an NGINX configuration that uses the private endpoint and SAS token to access your Azure Blob Storage. The following NGINX config points to the `content` directory with `/static/` location and uses the SAS token from the previous step to authorize requests to blob storage. The resolver is set to 168.63.129.16 which is the Azure internal DNS IP. It doesn't change. It resolves the storage account endpoint to the private endpoint IP configured earlier. + +```nginx +user nginx; +worker_processes auto; +worker_rlimit_nofile 8192; +pid /run/nginx/nginx.pid; + +error_log /var/log/nginx/error.log error; + +http { + upstream storage_origin { + server your-storage-account.blob.core.windows.net:443; + keepalive 32; + } + resolver 168.63.129.16 valid=10s; + server { + listen 443 ssl; + set $sas_token '?sv=YYYY-MM-DD&ss=b&srt=o&sp=r&se=YYYY-MM-DDTHH:MM:SSZ&st=YYYY-MM-DDTHH:MM:SSZ&spr=https&sig=YOUR_SAS_SIGNATURE_HERE'; + ssl_certificate /etc/nginx/example.cert; + ssl_certificate_key /etc/nginx/example.key; + location /static/ { + rewrite ^/static/(.*)$ /content/$1 break; + proxy_pass https://storage_origin$uri$sas_token; + proxy_set_header Host your-storage-account.blob.core.windows.net; + proxy_http_version 1.1; + proxy_set_header Connection ""; + } + } +} +``` + +{{< call-out "important" >}}Replace the following placeholders: +- `your-storage-account` with your actual storage account name +- `YOUR_SAS_SIGNATURE_HERE` with your actual SAS token signature +- Update the SAS token parameters according to your generated token{{< /call-out >}} + +### Configuration breakdown + +{{