331 строка
17 KiB
Markdown
331 строка
17 KiB
Markdown
---
|
||
layout: post
|
||
title: "LinkDev uses App Service to help ALEXBANK implement its empowering Business Passport"
|
||
author: "Sherif El Mahdi"
|
||
author-link: "https://twitter.com/_SherifElMahdi"
|
||
#author-image: "{{ site.baseurl }}/images/authors/SherifElMahdi.jpg"
|
||
date: 2017-06-08
|
||
categories: [Azure App Service, Azure Functions]
|
||
color: "blue"
|
||
image: "images/LinkDev/VAS_thumb.png"
|
||
excerpt: Link Development and Microsoft used Azure App Service to develop and deliver ALEXBANK's digital marketplace for small and medium-sized enterprises.
|
||
language: [English]
|
||
verticals: [Banking & Capital Markets]
|
||
geolocation: [Middle East]
|
||
---
|
||
|
||
ALEXBANK, named the [Middle East’s Best Bank for SMEs](https://www.alexbank.com/En/News/NewsDetails/Euromoney2) in 2017 for the second year in a row, has ambitious plans that extend into providing non-financial value-added services (VAS) to small and medium-sized enterprises (SMEs). With this goal in mind, the bank launched a major initiative called *ALEXBANK Business Passport.*
|
||
|
||
The ALEXBANK Business Passport initiative seeks to digitally empower and modernize SMEs through tools, education, and programs specifically designed to grow their skills and capacities, and by connecting them with the right partners.
|
||
|
||
For SMEs, the ALEXBANK Business Passport is a digital marketplace that provides a whole range of value-added services and products positioned from a group of partners such as Etisalat Misr, BDO Esnad, and Egyptian Junior Business Association (EJB), including ALEXBANK.
|
||
|
||
![ValueAddedServices]({{ site.baseurl }}/images/LinkDev/VAS.png)
|
||
|
||
<br/>
|
||
|
||
>“We are extremely happy for the launch of our new ALEXBANK Business Passport, which we designed to support and empower Egyptian enterprises.”
|
||
>
|
||
>— Dante Campioni, Chief Executive Officer and Managing Director, ALEXBANK
|
||
|
||
<br/>
|
||
|
||
Global technology solutions provider **Link Development** teamed up with Microsoft to develop and deliver the bank’s digital marketplace on Azure App Service. Link Development also put a value-added service called Website Builder into the marketplace, capitalizing on their experience over the past few years with the SME ecosystem.
|
||
|
||
Missing the opportunities of an online presence is a common pitfall for SMEs; Website Builder enables SMEs to create their own company websites for free (financed through the bank) or at an extremely low cost. While creating websites, SMEs can select among multiple industry-specific templates in both Arabic and English.
|
||
|
||
<br/>
|
||
|
||
>“We want to accompany the Enterprises, especially SMEs and SBs, to accelerate their efficiency and growth by facilitating their access to technology and professional services. Our aim is to grow the level of trust of SMEs and entrepreneurs toward the banking sector, by promoting us as a true partner for their businesses, aiming to support them not only financially but also with technical advisory and access to innovative solutions enabled by the new technologies we can access through Link Development.”
|
||
>
|
||
>— Dante Campioni, ALEXBANK
|
||
|
||
<br/>
|
||
|
||
**Key technologies used:**
|
||
|
||
- [Azure App Service](https://docs.microsoft.com/en-us/azure/app-service/)
|
||
- [Azure SQL Database](https://docs.microsoft.com/en-us/azure/sql-database/)
|
||
- [Azure Blob storage](https://docs.microsoft.com/en-us/azure/storage/storage-xamarin-blob-storage)
|
||
- [ASP.NET](https://www.asp.net/)
|
||
|
||
**Core team:**
|
||
|
||
- Bishoy Labib – Technology Manager, Link Development
|
||
- Rana Rabee – Senior Solution Developer, Link Development
|
||
- Mahmoud Ibrahim – Technology Manager, Link Development
|
||
- [Sherif El Mahdi](https://twitter.com/_SherifElMahdi) – Technical Evangelist, Microsoft
|
||
- Sara Ahmed – Technical Evangelist, Microsoft
|
||
- Nour Ramadan – Technical Evangelist, Microsoft
|
||
|
||
## Customer profile ##
|
||
|
||
[Link Development](http://www.linkdev.com/en-us/), headquartered in Egypt, is a global technology solutions provider leading the digitization of the private and public sectors with a focus on the Middle East and Africa. Founded in 1996, it operates in 24 or more countries in Egypt, United Arab Emirates, Saudi Arabia (KSA), and Qatar.
|
||
|
||
- [LinkDev Customers](http://www.linkdev.com/en-us/about-us/customers)
|
||
- [LinkDev Awards](http://www.linkdev.com/en-us/about-us/awards)
|
||
- [Contact LinkDev](http://www.linkdevelopment.com/en-us/contact-us)
|
||
|
||
## Problem statement ##
|
||
|
||
To manage ALEXBANK’s ambitious go-to-market plan, the Link Development (LinkDev) team was challenged to develop and deliver the ALEXBANK Business Passport (the main digital marketplace) in addition to the Website Builder with the following constraints:
|
||
|
||
- Fast service deployment time to market.
|
||
- Reduced operations cost.
|
||
- Least management overhead where most of IT time is saved.
|
||
- Built-in autoscale and load balancing.
|
||
- Easy continuous integration and continuous deployment setup.
|
||
|
||
In order to comply with these constraints, the Link Development team decided to use the Web Apps feature of Azure App Service for building and hosting the main digital marketplace in addition to their value-added service Website Builder.
|
||
|
||
>“Azure App Service is more developer-friendly in terms of publishing and continuous deployment. Also, the ability to automatically provision, configure, and autoscale new websites is much simpler than doing this under the IaaS model.”
|
||
>
|
||
>— Bishoy Labib, Technology Manager, Link Development
|
||
|
||
<br/>
|
||
|
||
## Solution, steps, and delivery ##
|
||
|
||
The ALEXBANK Business Passport marketplace is built on Link Development's in-house developed products: SMEGO (Digital Marketplace Platform) and Website Builder (Webccano). It is complemented with an open source WordPress portal for an SME Toolkit where all the products are run on Azure.
|
||
|
||
The focus of this article is mainly on the Website Builder, so let’s walk through the journey of building and hosting Website Builder using Azure App Service.
|
||
|
||
Website Builder is a web app that enables users to create and deploy their websites with no coding by choosing from various ready-made multilingual templates that are customizable through easy drag and drop. From a technical perspective, it’s an ASP.NET web app that deploys new web apps at run time by restoring an existing backup from a blob based on the selected template. Here’s the architecture:
|
||
|
||
![Architecture]({{ site.baseurl }}/images/LinkDev/architecture.png)
|
||
|
||
<br/>
|
||
|
||
**Authoring the Resource Manager template**
|
||
|
||
The LinkDev team started by authoring an Azure Resource Manager template that defines what resources to create on Azure. The resources represent the infrastructure required to deploy a new website when the user-customized website template is selected.
|
||
|
||
The Resource Manager template has been authored using Visual Studio Tools for Azure (File -> New Project -> Cloud -> Azure Resource Group Project) and it defines the following resources: App Service Plan, Azure web app, Azure SQL Database, and Azure Blob.
|
||
|
||
![ARM]({{ site.baseurl }}/images/LinkDev/ARM.png)
|
||
|
||
<br/>
|
||
|
||
The following snippets show the defined resources alongside their configurations:
|
||
|
||
**Creating Azure SQL Database**
|
||
|
||
```json
|
||
{
|
||
"apiVersion": "2014-04-01-preview",
|
||
"name": "[parameters('dbName')]",
|
||
"type": "databases",
|
||
"location": "[resourceGroup().location]",
|
||
"dependsOn": [
|
||
"[parameters('dbServerName')]"
|
||
],
|
||
"properties": {
|
||
"edition": "[parameters('dbEdition')]",
|
||
"collation": "SQL_Latin1_General_CP1_CI_AS",
|
||
"requestedServiceObjectiveId": "F1173C43-91BD-4AAA-973C-54E79E15235B"
|
||
}
|
||
|
||
```
|
||
|
||
<br/>
|
||
|
||
**Creating Azure storage account**
|
||
|
||
```json
|
||
{
|
||
"type": "Microsoft.Storage/storageAccounts",
|
||
"name": "[variables('storageAccountName')]",
|
||
"apiVersion": "2016-01-01",
|
||
"location": "[resourceGroup().location]",
|
||
"sku": {
|
||
"name": "[parameters('storageAccountType')]"
|
||
},
|
||
"kind": "Storage",
|
||
"properties": {
|
||
}
|
||
}
|
||
|
||
```
|
||
<br/>
|
||
|
||
**Creating Azure web app**
|
||
|
||
```json
|
||
{
|
||
"apiVersion": "2015-02-01",
|
||
"name": "[parameters('appName')]",
|
||
"type": "Microsoft.Web/Sites",
|
||
"location": "[resourceGroup().location]",
|
||
"tags": {
|
||
"[concat('hidden-related:', '/subscriptions/', subscription().subscriptionId,'/resourcegroups/', resourceGroup().name, '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]": "empty"
|
||
},
|
||
"dependsOn": [
|
||
"[concat('Microsoft.Web/serverFarms/', variables('appServicePlanName'))]"
|
||
],
|
||
"properties": {
|
||
"name": "[parameters('appName')]",
|
||
"serverFarmId": "[concat('/subscriptions/', subscription().subscriptionId,'/resourcegroups/',resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]",
|
||
"hostingEnvironment": "",
|
||
"siteconfig": {
|
||
"connectionstrings": [
|
||
{
|
||
"name": "CMS",
|
||
"ConnectionString": "[concat('Data Source=tcp:', reference(concat('Microsoft.Sql/servers/', parameters('dbServerName'))).fullyQualifiedDomainName, ',1433;Initial Catalog=', parameters('dbName'), ';User Id=', parameters('dbAdministratorLogin'), '@', parameters('dbServerName'), ';Password=', parameters('dbAdministratorLoginPassword'), ';')]"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
]
|
||
}
|
||
|
||
```
|
||
|
||
<br/>
|
||
|
||
**Closer look at the Resource Manager template — Restoring the web app from an existing backup stored in a blob using MSDeploy and Import DB:**
|
||
|
||
The website files to be deployed alongside the database are stored in a blob so the following JSON is added to the Resource Manager template to be able to restore the web app with its linked database from existing backups using MSDeploy and Import DB.
|
||
|
||
**Import .bacpac file into the newly created SQL database**
|
||
|
||
```json
|
||
{
|
||
"apiVersion": "2014-04-01-preview",
|
||
"name": "Import",
|
||
"type": "extensions",
|
||
"properties": {
|
||
"operationMode": "Import",
|
||
"storageKey": "[parameters('bacpacStorageKey')]",
|
||
"storageKeyType": "Primary",
|
||
"administratorLogin": "[parameters('dbAdministratorLogin')]",
|
||
"administratorLoginPassword": "[parameters('dbAdministratorLoginPassword')]",
|
||
"storageUri": "[parameters('masterBacpacUrl')]"
|
||
},
|
||
|
||
"dependsOn": [
|
||
"[resourceId('Microsoft.Sql/servers/databases', parameters('dbServerName'), parameters('dbName'))]"
|
||
]
|
||
}
|
||
|
||
```
|
||
|
||
<br/>
|
||
|
||
**Creating MSDeploy resource to reference the backup package that will be deployed**
|
||
|
||
```json
|
||
{
|
||
"apiVersion": "2014-06-01",
|
||
"name": "MSDeploy",
|
||
"type": "extensions",
|
||
"dependsOn": [
|
||
"[concat('Microsoft.Web/Sites/', parameters('appName'))]",
|
||
"[concat('Microsoft.Web/Sites/', parameters('appName'), '/config/web')]",
|
||
"[concat('Microsoft.Sql/servers/', parameters('dbServerName'), '/databases/', parameters('dbName'))]",
|
||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]"
|
||
],
|
||
"properties": {
|
||
"packageUri": "https://alexbankmarketplace.blob.core.windows.net/backups/packages.zip",
|
||
"dbType": "SQL",
|
||
"connectionString": "[concat('Data Source=tcp:', reference(concat('Microsoft.Sql/servers/', parameters('dbServerName'))).fullyQualifiedDomainName, ',1433;Initial Catalog=', parameters('dbName'), ';User Id=', parameters('dbAdministratorLogin'), '@', parameters('dbServerName'), ';Password=', parameters('dbAdministratorLoginPassword'), ';')]"
|
||
}
|
||
}
|
||
|
||
```
|
||
|
||
<br/>
|
||
|
||
**Deploying Resource Manager template with the REST API:**
|
||
|
||
When the user selects a customized website template to create a new website, the previous Resource Manager template is deployed at the run time.
|
||
|
||
```csharp
|
||
//Authenticate
|
||
string token = await AuthenticationHelpers.AcquireTokenBySPN(tenantId, clientId, clientSecret);
|
||
|
||
using (var client = new HttpClient(new LoggingHandler(new HttpClientHandler())))
|
||
{
|
||
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
|
||
client.BaseAddress = new Uri("https://management.azure.com/");
|
||
|
||
// Create the resource group
|
||
using (var response = await client.PutAsJsonAsync(
|
||
$"/subscriptions/{Subscription}/resourceGroups/{resourceGroup}?api-version=2015-11-01",
|
||
new
|
||
{
|
||
location = location
|
||
}))
|
||
{
|
||
response.EnsureSuccessStatusCode();
|
||
}
|
||
|
||
// Deploy ARM Template
|
||
using (var response = await client.PostAsJsonAsync(
|
||
$"/subscriptions/{Subscription}/resourceGroups/{resourceGroup}/providers/microsoft.resources/deployments/{deploymentName}?api-version=2015-08-01",
|
||
new
|
||
{
|
||
properties = new
|
||
{
|
||
templatelink = new
|
||
{
|
||
uri = "https://alexbank.blob.core.windows.net/armtemplate/WebSiteSQLDatabase.json",
|
||
contentVersion = "1.0.0.0",
|
||
},
|
||
mode = "Incremental",
|
||
parametersLink = new
|
||
{
|
||
uri = "https://alexbank.blob.core.windows.net/armtemplate/WebSiteSQLDatabase.parameters.json",
|
||
contentVersion = "1.0.0.0",
|
||
}
|
||
}
|
||
}))
|
||
{
|
||
var responseMessage = response.EnsureSuccessStatusCode();
|
||
}
|
||
}
|
||
|
||
```
|
||
<br/>
|
||
|
||
**Applying autoscaling:**
|
||
|
||
Autoscaling is one of the features that comes out of the box with Azure App Service (platform as a service). We configured the App Service plan to automatically scale based on CPU percentage (target range: 0%-85%) using a range of 1 to 3 instances.
|
||
|
||
![Scaling]({{ site.baseurl }}/images/LinkDev/autoscaling.png)
|
||
|
||
<br/>
|
||
|
||
**Monitoring from the inside out**
|
||
|
||
The LinkDev team used Azure Application Insights to detect, triage, and diagnose performance issues in the production environment. In addition, Application Insights provides consolidated analytics across server and client. Here are some insights from the live web app:
|
||
|
||
![Monitoring Insights]({{ site.baseurl }}/images/LinkDev/monitor.png)
|
||
|
||
![More Insights]({{ site.baseurl }}/images/LinkDev/montior2.png)
|
||
|
||
## Conclusion ##
|
||
|
||
Azure App Service enabled the Link Development team to manage ALEXBANK’s ambitious go-to-market plan, taking into consideration time, cost, and performance constraints.
|
||
|
||
**General lessons:**
|
||
|
||
- Using the Web Apps feature of Azure App Service (PaaS model) reduced service deployment time to market by 50 percent. In addition, about 70 percent of the IT time was saved.
|
||
- Applying autoscaling achieved the optimal balance between performance and cost. The LinkDev team configured scaling horizontally (scale in and out) based on the CPU utilization per instance.
|
||
- Using Azure Resource Manager templates for deployment allowed the LinkDev team to create a new web app alongside multiple resources via a single REST call at run time, taking into consideration dependencies between resources. The team used to rely on Azure Classic APIs and it took them eight sequential REST calls to accomplish the same task.
|
||
- Classic APIs were more time-consuming and error-prone because each resource was handled individually and it required manual intervention to complete the deployment if any exception occurred during the deployment of any resource.
|
||
- Implementing DevOps practices using Visual Studio Team Services with Web Apps led to automating the whole development lifecycle (source code management, build automation, test automation, and code analysis).
|
||
- Application Insights Smart Alerts enabled the LinkDev team to achieve faster error detection in a production environment.
|
||
|
||
## Additional resources ##
|
||
|
||
- [ALEXBANK Business Passport Website](http://www.alexbankpassport.com/en-us/)
|
||
- [ALEXBANK Website Builder](http://www.alexbankpassport.com/en-us/services/website)
|
||
- [Azure Web Apps](https://docs.microsoft.com/en-us/azure/app-service-web/app-service-web-overview)
|
||
- [Azure Blob storage](https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-how-to-use-blobs)
|
||
- [Authoring Azure Resource Manager templates](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authoring-templates)
|
||
- [Azure SQL Database](https://docs.microsoft.com/en-us/azure/sql-database/)
|
||
- [Deploying Web Apps with MSDeploy](https://docs.microsoft.com/en-us/azure/app-service-web/app-service-web-arm-with-msdeploy-provision)
|
||
- [Deploying Resource Manager templates using REST API](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-deploy-rest)
|
||
- [Validating the syntax of Resource Manager templates using REST API](https://docs.microsoft.com/en-us/rest/api/resources/deployments#Deployments_Validate)
|
||
|