Introduction
This article is the second post of a series that show a use case of using ASP.NET razor pages, blob storage and Azure CDN.
In the previous article : (https://lemtirisalah.com/using-azure-blob-storage-and-azure-cdn-in-asp-net-5-razor-pages-part-i/) we saw the creation of the ASP.NET razor page and the usage of the Azure storage emulator locally for development purposes.
Today’s topic will focus on deploying the web application to Azure app service and create the storage account that will contain our blob container.
If you didn’t have a chance to check my previous post, I highly recommend to go back and check the article as we will be deploying the web application we create earlier.
As a reminder, below is the target architecture:
For scripting, I am using Azure CLI and PowerShell. You can feel free to change to another scripting tool depending on your choice and operating system.
Create the Azure infrastructure components
We will be using Azure CLI to create the following components for our deployment infrastructure :
- A resource group located in West US
- An Azure plan app service
- A web App
- A storage account
- A blob container
First we will start by setting some global variables :
$location = "westus2"
$rg = "test-cdn-app-service-rg"
$plan_service_name = "test-cdn-app-service-ps"
$webapp_name = "test-cdn-app-service-wa"
$st = "testcdnappservicest"
$ct = "testcdnappservicestcontainer"
Note : I am using the location westus2 to host my resources on purpose. As I am based in Europe, I want the connection from my machine to the servers take as much time as possible, so I can show in my next article the advantage of using CDN to optimize content delivery.
Create the resource group :
az group create --location $location --name $rg
Create the service plan that will host our web application. you can check the differents SKU of the plan service in this link : https://azure.microsoft.com/fr-fr/pricing/details/app-service/linux/
az appservice plan create --name $plan_service_name --resource-group $rg --is-linux --sku B1
After that, create the app service that will host our web application. The app service should execute the run time .NET 5.0 and have a system identity assigned to it. This system identity will be granted a RBAC to access the storage account later for read and write operations.
az webapp create --name $webapp_name `
--plan $plan_service_name `
--resource-group $rg `
--assign-identity '[system]' `
--runtime 'DOTNET:5.0'
TIP : To get the runtime avalible for app service, execute the following command : az webapp list-runtimes –linux
We move next to create the storage account. For demonstration purpose, we will be using the LRS sku.
az storage account create --name $st `
--resource-group $rg `
--location $location `
--sku Standard_LRS `
--kind StorageV2
TIP : To check if the name of the storage account is avalible, execute the following command :az storage account check-name –name $st
After the storage account is created, create the blob container with the access level “blob read only”.
az storage container create `
--account-name $st `
--name $ct `
--public-access blob
Finally, go the Azure portal and make sure you have created all the required components :
Assign the role Storage Blob Data Contributor for the web app managed identity
In order to avoid using the connection string of the storage account directly in the web application, which may cause some security breaches. A good approach is to assign a managed identity automatically to the web application.(The managed identity is handled by Azure, and we won’t need to store any credentials) and assign it a RBAC that can read and write from the container storage.
First, we will get the principal ID of the assigned identity :
$principal_id = (az resource list -n $webapp_name --query [0].identity.principalId --out tsv)
Get the complete storage account id :
$storage_id=$(az storage account show -n $st -g $rg --query id --out tsv)
Assign the role “Storage Blob Data Contributor” to the identity
az role assignment create --assignee $principal_id --role 'Storage Blob Data Contributor' --scope $storage_id
Update the web application source code.
Go to appsettings.json, and add the following section that contains information about our Azure storage configuration :
"AzureStorageConfig": {
"AccountName": "testcdnappservicest",
"ContainerName": "testcdnappservicestcontainer"
}
Update the constructor UploadModel() in the class Upload.cshtml.cs with the following content :
public UploadModel(IOptions config, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
_containerClient = new BlobContainerClient(config.Value.AccountName, config.Value.ContainerName);
}
else
{
string containerEndpoint = string.Format("https://{0}.blob.core.windows.net/{1}",
config.Value.AccountName,
config.Value.ContainerName);
_containerClient = new BlobContainerClient(new Uri(containerEndpoint), new DefaultAzureCredential()); } }
The initialization of the class BlobContainerClient depends on the environment. In development, we use the local Azure storage emulator, and for production we will be using the Azure storage account.
In the page Images.cshtml, add the following image. The file “img1.jpg” is the file we will be uploading once we will deploy our application to Azure.
@page
@model Web.Pages.ImagesModel
@{
}
<img src="https://testcdnappservicest.blob.core.windows.net/testcdnappservicestcontainer/img1.jpg" alt="Sample Photo" />
Deploy the web application
For simplicity, we will deploy our application directly from Visual Studio.
Right click in your project and choose publish.
Choose Azure as your target deployment.
And choose Azure app service Linux
If you are not connected to your Azure account, you will be prompted to enter your credentials. After selecting your account, select the app service we create earlier :
Check if your application was published by accessing the link https://test-cdn-app-service-wa.azurewebsites.net/
Test uploading a file from your deployed application
Chose whatever image file from your local machine and name it “img1.jpg”, and then access your web application and upload it.
To check that the file was uploaded correctly, access the Azure portal or Azure file storage explorer and make sure img1.jpg is present in your container.
And finally, to check that your web application has anonymous access to your blob container, open the page “Images”, and you will be able to view your uploaded picture 😊
Conclusion
In this second article, we went through the steps of deploying a Razor web application that use Azure storage account to host our media files. This media can be images, videos, scripts or any other content.
However, Azure Storage account can have some limits dealing with requests from different regions, especially if you have worldwide users.
If you want to have a look at the code source of the web application, you can clone the repository from this link: https://github.com/salahlemtiri/aspnetrazor-azure-blob.git
In the third article, we are going to see, how we can implement Azure CDN to optimize our content delivery and improve our application performance.
Leave a comment if you find this article useful, and I will be pleased to answer your questions if you have any problem.
Salah.
well done Salah