{"id":88519,"date":"2020-09-25T17:02:09","date_gmt":"2020-09-25T17:02:09","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=88519"},"modified":"2021-03-30T14:15:40","modified_gmt":"2021-03-30T14:15:40","slug":"static-hosting-with-azure-blob-storage-and-azure-cdn","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/cloud\/azure\/static-hosting-with-azure-blob-storage-and-azure-cdn\/","title":{"rendered":"Static hosting with Azure Blob Storage and Azure CDN"},"content":{"rendered":"<p>One of the most significant advantages of developing SPAs (<em>Single-page applications<\/em>) is the simplicity of deploying them to the cloud. Whether it is Angular, Vue, or React-based, you simply need to load an initial <em>index.html<\/em> file and point your hosting solution to it. All the rest of the work is automatically performed by the SPA framework along with the power of JavaScript.<\/p>\n<p>However, for many developers out there, the chances are that once in a while they\u2019d want to host a single application that is entirely static, i.e., doesn\u2019t perform any HTTP call to a back-end API; like with a business website, or a portfolio page, for example.<\/p>\n<p>If this is your case, then Microsoft is equipped with the right solution: <a href=\"https:\/\/azure.microsoft.com\/en-us\/services\/storage\/blobs\/\">Azure Blob Storage<\/a> along with <a href=\"https:\/\/azure.microsoft.com\/en-us\/services\/cdn\/\">Azure CDN<\/a> (<em>Azure Content Delivery Network<\/em>).<\/p>\n<p>They\u2019re all about static hosting. While Azure CDN is a global CDN solution for delivering high-bandwidth content, it also uses cached static objects loaded from Azure Blob storage, which, in turn, allows users to store large amounts of data on Microsoft\u2019s storage solution.<\/p>\n<p>This tutorial explores these two great tools by creating an Angular SPA application and deploying it statically to Azure in just a few steps. Come with me!<\/p>\n<h2><a id=\"post-88519-_dka2zh95cl2k\"><\/a>Setup<\/h2>\n<p>For this piece, you\u2019ll be making use of a fully working <a href=\"https:\/\/angular.io\/tutorial\">example<\/a> provided by the official Angular docs. It is an SPA app that loads an in-memory list of heroes, allowing the users to perform CRUD operations over it as shown in Figure 1.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"800\" class=\"wp-image-88520\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-174.png\" \/><\/p>\n<p><strong>Figure 1. Official Angular example app<\/strong><\/p>\n<p>Please, feel free to use any other Angular (or another SPA framework as well) app you desire. Go to this <a href=\"https:\/\/angular.io\/tutorial\">link<\/a> and find the <em>Download example<\/em> link within it. Download the app, unzip it, and access its root folder via command line.<\/p>\n<p>You\u2019ll also need to have the latest version of <a href=\"https:\/\/nodejs.org\/en\/\">Node.js<\/a> installed on your machine. Then, open a command window and navigate to the app folder. Run the following commands:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">npm install\r\nnpm start<\/pre>\n<p>They will download the required Node dependencies and start the app right after. Feel free to play around with it. The focus, however, is with the <em>dist<\/em> folder; so, run the following command:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">npm run build<\/pre>\n<p>This command will generate a bunch of files under the <em>dist\/<\/em> folder that, together, represent the SPA as a whole. Save them for later.<\/p>\n<h2><a id=\"post-88519-_mk4n57c7u1a3\"><\/a>Azure Configs<\/h2>\n<p>Now, on to the Azure configurations. First, log in to your Azure account <a href=\"https:\/\/portal.azure.com\/\">here<\/a>. If you don\u2019t have one already, please go ahead and make sure to complete the <a href=\"https:\/\/azure.microsoft.com\/en-us\/\">checkout<\/a> until the end. For this example, you need a subscription. Azure subscriptions are paid, but you can make use of the free initial trial to test it out.<\/p>\n<p>You can access the <em>Subscriptions<\/em> option through the home page of your Azure account. Please, make sure to complete the subscription setup until the end before proceeding to the next steps. It\u2019s a straightforward process, so don\u2019t worry.<\/p>\n<p>Once you\u2019ve logged in, go to the home page and search for <em>Storage account<\/em> in the top search bar. Click it, and you\u2019ll be redirected to the listing of storage accounts.<\/p>\n<p>You may not have any yet, so click the <em>Add<\/em> button in the top bar and once redirected to the form page, fill in the fields according to the Figure 2 shown below.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"817\" height=\"929\" class=\"wp-image-88521\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-175.png\" \/><\/p>\n<p><strong>Figure 2. Filling in storage account details<\/strong><\/p>\n<p>Note that you\u2019ve got to inform a Resource group name. If you don\u2019t have any, click the <em>Create new<\/em> link and give it a name like shown in Figure 3:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"803\" height=\"798\" class=\"wp-image-88522\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-176.png\" \/><\/p>\n<p><strong>Figure 3. Creating a new resource group<\/strong><\/p>\n<p>These groups are responsible for integrating all the common resources under the same subscription, which is good for organizational means. If you dedicate a resource group for one purpose, it\u2019s easy just to delete the resource group when you are done to clean up everything.<\/p>\n<p>Your storage account name is also important. It defines how your blob account will be called through all the other Azure services and services of users across the globe. It has to be unique.<\/p>\n<p>After you finish, click the button <em>Review + create <\/em>at the bottom of the page as shown in Figure 4. Then, you\u2019ll be redirected to the review page with a summary of the configs.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"617\" height=\"85\" class=\"wp-image-88523\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-177.png\" \/><\/p>\n<p><strong>Figure 4. Click Review + create button<\/strong><\/p>\n<p>Finally, click the <em>Create<\/em> button. This is it, for now, you have your first storage account!<\/p>\n<p>Whenever you go back to the home page, your newly created Storage account will be exhibited there:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1110\" height=\"141\" class=\"wp-image-88524\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-178.png\" \/><\/p>\n<p><strong>Figure 5. Recently created resources<\/strong><\/p>\n<p>When you click it, the <em>Overview<\/em> dashboard will display summarized and important information about this resource, like its location (datacenter), the subscription details, as well as some graphs with usage data.<\/p>\n<p>Now, at the left-side panel, click the <em>Static website<\/em> menu option (under the <em>Settings<\/em> section) and enable it by clicking the <em>Enabled<\/em> toggle button. This is the option to allow the deploy of static websites to your Azure account.<\/p>\n<p>Once you enable it, you must provide two main endpoints: the index file (where the app starts) and the error path, just as shown in Figure 6.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"845\" height=\"390\" class=\"wp-image-88525\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-179.png\" \/><\/p>\n<p><strong>Figure 6. Providing document paths data<\/strong><\/p>\n<p>Once you\u2019ve filled in the values, click the <em>Save<\/em> button. Then, the same page will be automatically updated with the public endpoints you may use to access them as shown in Figure 7.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"964\" height=\"558\" class=\"wp-image-88526\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-180.png\" \/><\/p>\n<p><strong>Figure 7. Static website endpoints<\/strong><\/p>\n<p>However, this is still not enough to host the Angular files within Azure. You need a Blob container for that. Go back to the Storage account and click the <em>Containers<\/em> menu option (on the left-side panel), under the <em>Blob service<\/em> section as shown in Figure 8.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"286\" height=\"246\" class=\"wp-image-88527\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-181.png\" \/><\/p>\n<p><strong>Figure 8. Click the Containers menu option<\/strong><\/p>\n<p>There you\u2019ll get to see the list of containers among which there are two available ones: the <em>$logs<\/em> and <em>$web<\/em> containers. The second one is just what we need since it is well-suited for website content.<\/p>\n<p>You can create as many containers as you want to organize your applications.<\/p>\n<p>Click the <em>$web<\/em> container, and you\u2019ll be redirected to the <em>Overview<\/em> page in which you get to upload your app files. That\u2019s an effortless task to do. Click the <em>Upload<\/em> button at the top bar, and the right-sided panel shown in Figure 9 will appear.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"301\" height=\"292\" class=\"wp-image-88528\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-182.png\" \/><\/p>\n<p><strong>Figure 9. Uploading files to your blob <\/strong><\/p>\n<p>Click the browse button and search for the <em>dist<\/em> folder that you built before in your local Angular app. Select all the files under the folder and click <em>Ok<\/em>. Then, click the <em>Upload<\/em> button. Wait until all the files are uploaded and watch each of them appear in the same <em>Overview<\/em> page.<\/p>\n<p>That\u2019s it! How do you access the application? Remember the <em>Primary endpoint<\/em> that was autogenerated under the <em>Static website<\/em> page? This is the final endpoint you may access to see your Angular app up and running. Enter it directly to your browser and have fun!<\/p>\n<h2><a id=\"post-88519-_vuww6xdkcatv\"><\/a>Azure CDN<\/h2>\n<p>Like all other CDNs, Azure CDN offers a faster way to cache your static website contents hosted in your Azure storage to enhance the speed and provide a better experience to the users. For this, you need to access your storage account once more and click the menu option <em>Azure CDN<\/em> (under the <em>Blob service<\/em> section of the left-side panel).<\/p>\n<p>The screen shown in Figure 10 will appear. Make sure to fill in the <em>New endpoint<\/em> form fields accordingly. Note that the CDN endpoint name must be unique across Azure, so try again with a new name if there is a failure when creating the resource.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"722\" height=\"770\" class=\"wp-image-88529\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-183.png\" \/><\/p>\n<p><strong>Figure 10. Creating a new CDN endpoint<\/strong><\/p>\n<p>Notice also that it\u2019s targeting to cache the static website, not the blob, so be sure to select the proper option in the <em>Origin hostname<\/em> combo box. The CDN endpoint name is the prefix you want your hostname to have simplified at the end of the process.<\/p>\n<p>When you\u2019re done, click the <em>Create<\/em> button. This will take some time, so you\u2019ll get to see a loading section at the notifications menu (Figure 11).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"526\" height=\"315\" class=\"wp-image-88530\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-184.png\" \/><\/p>\n<p><strong>Figure 11. Processing the CDN creation<\/strong><\/p>\n<p>Once it\u2019s done, you\u2019ll remain on the same page and the <em>Endpoints<\/em> section is going to be refreshed to receive the newly created endpoint:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"913\" height=\"152\" class=\"wp-image-88531\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-185.png\" \/><\/p>\n<p><strong>Figure 12. List of created endpoints<\/strong><\/p>\n<p>When you click it, Azure will redirect you to the details page. There, you may see more information about the CDN like its location, the supported protocols, and the <em>Endpoint hostname<\/em> (the one we must use to access the referred CDN).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"916\" height=\"416\" class=\"wp-image-88532\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-186.png\" \/><\/p>\n<p><strong>Figure 13. Detailed information about the created CDN<\/strong><\/p>\n<p>If you try to access the created CDN through the provided <em>Endpoint hostname<\/em>, chances are that you may see the error screen shown in Figure 14. This happens because Azure takes some time to process the creation and propagate the new CDN through the web.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1149\" height=\"824\" class=\"wp-image-88533\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-187.png\" \/><\/p>\n<p><strong>Figure 14. Page not found<\/strong><\/p>\n<p>Once you wait a bit more, you get to see the fully working app in action shown in Figure 15.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1057\" height=\"757\" class=\"wp-image-88534\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/09\/word-image-188.png\" \/><\/p>\n<p><strong>Figure 15. Angular app running under Azure CDN hostname<\/strong><\/p>\n<h2><a id=\"post-88519-_mmt1fzwqrl60\"><\/a>Conclusion<\/h2>\n<p>The solution explored over this article is also focused on the cost-benefit. On Azure, you pay only for what you use; that means that it\u2019s a very cheap solution to host static websites that may be accessed rarely over time. Rather than paying for a fixed-priced solution, Azure CDN along with Azure Blob Containers offers a flexible and easy-to-use way to approach your needs.<\/p>\n<p>And you can go beyond that. With an Azure Storage account in hand, you can store files, queues, disks, and many types of data, in a fast and straightforward manner. Best of luck!<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>No matter what you need, Azure probably has a solution. In this article Diogo Souza demonstrates how to host a static web page in Azure in just a few steps with Azure Blob Storage and Azure CDN.&hellip;<\/p>\n","protected":false},"author":320401,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[137091],"tags":[124839,124840,5613,5134,124841],"coauthors":[60461],"class_list":["post-88519","post","type-post","status-publish","format-standard","hentry","category-azure","tag-azure-blob-storage","tag-azure-cdn","tag-cloud-computing","tag-sql-prompt","tag-web-hosting"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/88519","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/320401"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=88519"}],"version-history":[{"count":2,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/88519\/revisions"}],"predecessor-version":[{"id":88536,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/88519\/revisions\/88536"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=88519"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=88519"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=88519"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=88519"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}