Skip to content

Commit e50db78

Browse files
authored
angular on azure blog post initial commit (#43)
1 parent 5050ac0 commit e50db78

File tree

5 files changed

+254
-2
lines changed

5 files changed

+254
-2
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ The blog is served at http://localhost:4000
2525

2626
## Content
2727

28-
Welcome to our official technology blog. The idea is to share with the Community about our technology challenges. A blog post in an engineering blog should show readers what in-house engineering teams are actually working on. Engineering posts help peers understand what a particular individual or team within a much larger organization actually works on, keeping sales and marketing to an absolute minimum. These posts tell us about an engineering team’s philosophy as well as their stack.
29-
But they're be educational. Well-written blog posts offer unique perspectives and different solutions to old problems. They help the reader learn about a specific topic and technology, and walk readers through how that topic/technology is applied to help the team work through a challenge. Readers should learn something new.
28+
Welcome to our official technology blog. The idea is to share with the Community about our technology challenges. A blog post in an engineering blog should show readers what in-house engineering teams are actually working on. Engineering posts help peers understand what a particular individual or team within a much larger organization actually works on, keeping sales and marketing to an absolute minimum. These posts tell us about an engineering team’s philosophy as well as their stack.
29+
30+
They should be educational. Well-written blog posts offer unique perspectives and different solutions to old problems. They help the reader learn about a specific topic and technology, and walk readers through how that topic/technology is applied to help the team work through a challenge. Readers should learn something new.
3031

3132
Regardless of the topic, the first question to ask yourself is, "Why should a reader care?" Readers don't just want to look at a blog post and say, "Cool, Company X did this thing...." and that's it. At the very least, they want to understand:
3233

_data/authors.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,8 @@ Raman Koushyk:
5454
name : "Raman Koushyk"
5555
avatar : "assets/images/avatars/raman_koushyk.png"
5656
bio : "Senior QA Engineer - Customer Success"
57+
58+
Yash Kapila:
59+
name : "Yash Kapila"
60+
avatar : "assets/images/avatars/yash.jpeg"
61+
bio : "Principal Frontend Engineer - Customer Success"
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
---
2+
title: "Angular: Deploy an Angular app on Azure"
3+
excerpt: "Deploy a multi-locale Angular app using Azure Blob Storage and CDN Classic"
4+
tags: Frontend Angular Azure i18n
5+
authors:
6+
- Yash Kapila
7+
- Marco Santarelli
8+
header:
9+
teaser: /assets/images/post/web-azure-angular-logo.jpeg
10+
teaser_alt: Azure and Angular
11+
category: Frontend
12+
---
13+
14+
![](/assets/images/post/web-azure-angular-logo.jpeg)
15+
16+
## Introduction
17+
18+
Backbase has been working towards a web architecture that follows [Jamstack](https://jamstack.org) principles and aligns with Angular best practices. Our goal is to ensure our web app's rendering strategy is decoupled from the backend and hosted on the best infrastructure possible.
19+
20+
As a first step in that direction, we replaced our Backbase proprietary app server (Portal) and moved to a lightweight **Nginx** web server. This brought several benefits:
21+
22+
1. Better performance: removing the server-side rendering ensured a low TTFB (Time To First Byte)
23+
2. Improved Security
24+
3. Cheaper infrastructure: we reduced our backend footprint and removed Portal and its dependent services
25+
4. Quick and easy deployments
26+
5. Scalability
27+
6. Greater consistency with Angular's [deployment suggestions](https://angular.io/guide/i18n-common-deploy)
28+
29+
Using Nginx allowed our customers to take this strategy regardless of whether they were on-premise or using a cloud vendor. However, we also want to enable our customers to deploy their apps to cloud components, so they can leverage the extra benefit of using the provider's native components and save costs on CPU, memory, bandwidth, and computation time.
30+
31+
To explore how we could achieve this in our Angular applications, we created a demonstration application using Microsoft Azure's web app services.
32+
33+
## Leveraging Azure
34+
35+
Several Azure services can be used to serve and deploy static web applications:
36+
37+
- Azure Blob Storage
38+
- Azure CDN (Classic, Verizon, and Akamai)
39+
- Azure Front Door
40+
- Azure Web App
41+
- Azure Static Web App
42+
43+
Each service has its features and capabilities, so it's essential to choose one that best fits an application's needs and use case. For this demonstration, we decided to go with Azure Storage and CDN(classic).
44+
45+
Let's take a quick look into these services.
46+
47+
### Azure Blob Storage
48+
49+
Azure Blob Storage is a fully managed object storage service provided by Microsoft as part of the Azure Cloud platform. It allows developers to store and retrieve large amounts of unstructured data, such as images, videos, and documents, in a highly scalable and cost-effective manner.
50+
51+
One of the main benefits of using Azure Blob Storage is its ability to scale to handle large amounts of data. The service automatically scales up and down based on usage and can store billions of objects in a single account. Additionally, Azure Blob Storage is also cost-effective, and you only pay for the storage and data transfer you use.
52+
53+
Some of the use cases this service is designed for are:
54+
55+
- Delivering images or documents directly to a browser.
56+
- Streaming video and audio.
57+
- Storing files for distributed access.
58+
59+
For more information on Azure Blob Storage, read [Microsoft’s introduction](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction) to the service.
60+
61+
### Azure CDN
62+
63+
A content delivery network (CDN) is a vast network of servers responsible for delivering content from an "origin" server to end users from a location closest to them, ensuring minimum latency. It achieves this by storing cached content on edge servers in point-of-presence (POP) locations that are geographically closest to the end users.
64+
65+
Azure CDN (Classic) is a CDN service provided by Microsoft as part of the Azure Cloud platform. It supports multiple protocols, including HTTP and HTTPS, and is integrated with Azure storage, allowing to serve content from the Azure storage account using CDN efficiently. Some benefits of using Azure Classic CDN to deliver web applications include the following:
66+
67+
1. Better performance and improved user experience due to the speed of delivery of content.
68+
2. Scaling to handle high instantaneous loads.
69+
3. Taking pressure off the origin by distributing cached content from the Edge servers.
70+
71+
For more information on Azure CDN, read [Microsoft’s introduction](https://learn.microsoft.com/en-za/azure/cdn/cdn-overview) to the service.
72+
73+
#### Front Door (alternative)
74+
75+
While we use Azure CDN for this demo application, Azure Front Door provides similar functionality. Front Door is Microsoft's modern cloud Content Delivery Network (CDN) that provides a global, multi-cloud entry point for web apps. It offers features such as load balancing, built-in layer 3-4 DDoS protection, and the ability to define custom routing rules.
76+
77+
For more information on Front Door, read [Microsoft’s introduction](https://learn.microsoft.com/en-us/azure/frontdoor/front-door-overview) to the service.
78+
79+
#### Azure CDN from Verizon & Akamai (alternative)
80+
81+
Azure CDN from Verizon & Akamai is Microsoft's latest Azure Content Delivery Network (CDN) service version. It’s a global service that allows the distribution of content to users worldwide by caching and delivering the content from a network of edge servers located in strategic locations.
82+
83+
Azure CDN from Verizon is based on the Verizon Media Platform, a CDN service provided by Verizon Communications. Azure CDN from Akamai is based on the Akamai Edge Platform, which Akamai Technologies provide.
84+
85+
It allows us to choose the provider that best fits our needs and use case and also allows us to use different providers for different endpoints, giving more flexibility and control over the CDN service.
86+
87+
## Challenges
88+
89+
We identified a few challenges which needed to be resolved before our banking applications could be served and deployed using Storage and CDN:
90+
91+
1. Multi-locale support
92+
2. CSP
93+
3. Authentication (cookie vs header based)
94+
4. Security
95+
96+
As part of this post, we will focus on addressing multi-locale support and CSP.
97+
98+
## Angular & Internationalization
99+
100+
**Internationalization**, sometimes referred to as i18n, is the process of designing and preparing an application for use in different locales worldwide, and **localization** is the process of building versions of the project for different locales. The method of determining the appropriate language and cultural settings for a user based on their device or browser settings, geographic location, or user preferences is termed **locale negotiation**.
101+
102+
At Backbase, our customers have users across multiple regions, requiring their banking apps to be localised. Leveraging in-built Angular capabilities, we can achieve this quickly by building different versions of an app for each locale.
103+
104+
For example, an app having two languages Dutch(`nl`) and English(`en`) will have a final distribution like the following:
105+
106+
```
107+
- dist
108+
- azure-angular-i18n
109+
- nl
110+
- index.html
111+
- favicon.ico
112+
- main.5f84b2e1a0ac5bcdcd0e.js
113+
- ....
114+
- en
115+
- index.html
116+
- favicon.ico
117+
- main.5f84b2e1a0ac5bcdcd0e.js
118+
- ....
119+
```
120+
121+
While building and managing i18n tasks is covered well by Angular documentation, there is limited information regarding deploying a multi-locale app and locale negotiation. The [Angular docs](https://angular.io/guide/i18n-common-deploy) only explain it for when using a web server like Nginx and Apache.
122+
123+
Web servers can perform a computation to determine the correct locale based on configured requirements. However, this implementation isn't as straightforward with a storage service and CDN, as neither provides any built-in computation capability.
124+
125+
To overcome this challenge, we used a feature in Azure CDN known as **Rule Engine**. Rule Engine allows defining of custom rules and actions that can be applied to requests and responses as the CDN processes them.
126+
127+
The rules can be applied based on various conditions, such as URLs, headers, query parameters, and cookies. They are associated with an action that can be taken on the request or response, such as caching, redirecting, rewriting, or adding headers. Find more information about it in [the Microsoft Azure docs](https://learn.microsoft.com/en-us/azure/frontdoor/front-door-rules-engine?pivots=front-door-standard-premium).
128+
129+
Some examples of things we can do with Rule Engine in Azure CDN are as follows:
130+
131+
- Serve a specific version of a file depending on the Accept-Language header.
132+
- Add security headers to improve the security of content.
133+
- Redirect users to a different URL based on the user's country or device type.
134+
- Cache different versions of an asset based on the user's device or browser.
135+
- Set custom headers or override existing headers.
136+
137+
### Demo Application
138+
139+
The source code for our demonstration application is available [here](https://github.com/Backbase/azure-angular-i18n), and the live application is available [here](https://angular-i18n-demo.azureedge.net).
140+
141+
**Disclaimer: This post is only for demonstration purposes and shouldn't be treated as production ready as it deals with basic locale negotiation requirements and lacks mandatory security aspects**
142+
143+
#### Prerequisites
144+
145+
1. [Microsoft Azure account, free tier](https://azure.microsoft.com/en-us/free/)
146+
2. [Azure CLI]((https://docs.microsoft.com/en-us/cli/azure/install-azure-cli))
147+
3. [Angular app](https://angular.io/guide/setup-local)
148+
149+
#### Project Setup
150+
151+
Following Angular [documentation](https://angular.io/guide/i18n-common-overview), the application is prepared for two languages, `en` and `nl`.
152+
153+
```json
154+
{
155+
"projects": {
156+
"azure-angular-project": {
157+
"prefix": "app",
158+
"i18n": {
159+
"sourceLocale": "en",
160+
"locales": {
161+
"nl": "src/locale/messages.nl.json"
162+
}
163+
},
164+
"architect": {
165+
"build": {
166+
"options": {
167+
"localize": true
168+
}
169+
}
170+
}
171+
}
172+
}
173+
}
174+
```
175+
176+
The app retrieves dummy information from an API made available through an [Azure function](https://swapi-function-app.azurewebsites.net). The function serves two APIs: `/planets`, which gives a dummy list of Star Wars planets and `/planets/{planetId}`, which returns dummy information about the selected planet.
177+
178+
#### Prepare Angular distribution package
179+
180+
Angular generates a separate distribution package for each locale.
181+
182+
```bash
183+
npm run build
184+
```
185+
186+
#### Create Azure Resources
187+
188+
We provision the required resources using Azure's ARM templates (infrastructure-as-code) and AZ CLI. AZ CLI must have a default subscription set to provision resources.
189+
190+
**Resource Group**
191+
192+
A resource group is a container that holds all related resources for an Azure solution. All services provisioned for this demonstration application will be held inside the same resource group. We provision a resource group named `azure-angular-i18n` in the `West Europe` region.
193+
194+
```bash
195+
az group create --location westeurope --name azure-angular-i18n
196+
```
197+
198+
**Storage Account**
199+
200+
Using the [ARM template](https://github.com/Backbase/azure-angular-i18n/tree/master/azure_arm_templates/storage-account), we provision a storage account that will store the Angular builds named `angulardemoapps` and create two containers `en-locale` and `nl-locale` within it.
201+
202+
```bash
203+
az deployment group create --resource-group azure-angular-i18n --template-file azure_arm_templates/storage-account/template.json
204+
```
205+
206+
Next, we upload the `en` and `nl` Angular distribution builds to their respective containers.
207+
208+
```bash
209+
# --account-name is the name of the storage account, and -d is the container name
210+
211+
az storage blob upload-batch --account-name angulardemoapps -d nl-locale -s dist/azure-angular-i18n/nl/ --overwrite
212+
213+
az storage blob upload-batch --account-name angulardemoapps -d en-locale -s dist/azure-angular-i18n/en/ --overwrite
214+
```
215+
216+
**Important:** We set the `cache-control` property for both locale's `index.html` to `no-store` as we don't want the CDN to cache it once it is provisioned. Caching the file causes issues with locale negotiation, especially when determining the right locale based on an empty context root `/`.
217+
218+
```bash
219+
az storage blob update --account-name angulardemoapps --container-name nl-locale --name index.html --content-cache "no-store"
220+
221+
az storage blob update --account-name angulardemoapps --container-name en-locale --name index.html --content-cache "no-store"
222+
```
223+
224+
**CDN**
225+
226+
Once the storage account is setup, we provision a CDN using its [ARM template](https://github.com/Backbase/azure-angular-i18n/tree/master/azure_arm_templates/cdn).
227+
228+
```bash
229+
az deployment group create --resource-group azure-angular-i18n --template-file azure_arm_templates/cdn/template.json
230+
```
231+
232+
The ARM template contains the following configurations:
233+
234+
1. Specifies the **origin** where the original resources reside and are fetched by the CDN when a cache doesn't exist
235+
2. Specifies the rules for the Rule Engine for locale negotiation. These rules are as follows:
236+
- If the context root of the application is empty (`/`), check for a cookie named `locale`. If the value is `en`, return `en/index.html`. If the value is `nl`, return `nl/index.html`.
237+
- For deep linking, if the URL path begins with `/en`, return `/en/index.html`. Otherwise, return `nl/index.html`.
238+
- For all assets like CSS, JS & SVGs, return them from their respective `en` or `nl` containers.
239+
- As a fallback, if locale negotiation using cookies or URL path isn't successful, return `en/index.html`.
240+
3. Modifies the response header for `index.html` and adds a dummy Content-Security-Policy-Report-Only header.
241+
242+
## Final Thoughts
243+
244+
The post gives an idea of how Azure native components are used to deploy an Angular application. We can further optimise Azure CDN (Classic) and Blob Storage implementation for a real application.
245+
246+
Additionally, an exciting new feature is coming up on Azure known as [Edge Compute](https://azure.microsoft.com/en-us/resources/cloud-computing-dictionary/what-is-edge-computing/). Edge Compute will make it possible to provide computation capabilities on Edge Locations and so achieve a lot more than the Rule Engine. Since the feature is still new, it isn't available across all regions, but it is only a matter of time before it’s natively integrated with Azure's CDN solutions.

assets/images/avatars/yash.jpeg

45.2 KB
Loading
Loading

0 commit comments

Comments
 (0)