Things you may consider when choosing a Microsoft Azure Region.

With over 50 regions worldwide, Azure has more global regions than any other cloud provider. When you have to choose a region for your Azure resources, consider these four factors:

  1. Not all services are available in all regions
    You have to ensure all resources you want to deploy are available within the desired region. Here is a nice overview of Products available by region.
  2. Prices vary by region
    Not all Azure Regions have the same pricing for the same resources. While most of the time you are looking for the closest Azure Region to your company / customers, you may consider choosing another Region due to the lower pricing model. A good resource to determine the price for a resource for a specific region is the Azure Pricing Calculator.
  3. Latency from your customer to the Azure datacenter
    For performance reason you want to choose the Azure region with the least latency to your company / customers. To measure the latency you can perform a Azure Latency Test on AzureSpeed.com
  4. Location of your customer data (data residency)
    You may have specific compliance or data-residency requirements that will force you to use a specific region. Get data residency details.

Additional information: Learn more about Azure Regions 

 

Serving a HTML Page from Azure PowerShell Function

The new PowerShell language (experimental) support in Azure Function is really handy. Especially if you want to use the Azure PowerShell cmdlets to retrieve any kind of Azure Resources and diplay them in a HTML page. Hosting the cmdlet in Azure Function eliminates the need of a local installed Azure PowerShell module.

Here is a simple PowerShell Function that returns a Hello world HTML page:

# POST method: $req
$requestBody = Get-Content $req -Raw | ConvertFrom-Json
$name = $requestBody.name

# GET method: each querystring parameter is its own variable
if ($req_query_name)
{
    $name = $req_query_name
}

$html = @'

<header>This is title</header>


Hello world


'@

Out-File -Encoding Ascii -FilePath $res -inputObject $html

Invoking the script in a browser doesn’t give us the desired result. The content gets interpreted as XML instead of HTML:

xmlresult

The reason for that is that the Content-Type is set to applicaton/xml:

xmlresponse

The output of an Azure PowerShell function is a file (called $res by default) – so how can we change the content type to text/html?

It turns out (thanks to Mikhail) that we can construct a Repsonse Object using a JSON string (here the node definition) where we can set the content and the content type:

$resp = [string]::Format('{{ "status": 200, "body": "{0}", "headers": {{
"content-type": "text/html" }} }}', $html)
Out-File -Encoding Ascii -FilePath $res -inputObject $resp

If we invoke the function in the browser again we get the desired result:
htmlresponse

And the content-type is set to text/html:
htmldebug

Note that if your HTML contains JSON characters like double quotes or backslashes you will have to escape them. Example:

$html -replace '"', '\"'

Web.config for hosting an Angular application on Azure Web App

If you host an Angular application on Microsoft Azure you probably want to define a mimemap for .json and .woff / .woff2 files to get rid of the console errors. Also in order to enable client side routing we have to add a rewrite rule.

This is how my web.config looks like:

<configuration>
    <system.webServer>
        <staticContent>
            <mimeMap fileExtension=".json" mimeType="application/json" />
            <remove fileExtension=".woff"/>
            <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
            <mimeMap fileExtension=".woff2" mimeType="font/woff2" />
     </staticContent>

      <rewrite>
        <rules>
            <rule name="Angular" stopProcessing="true">
                <match url=".*" />
                <conditions logicalGrouping="MatchAll">
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                </conditions>
                <action type="Rewrite" url="/" />
            </rule>
        </rules>
        </rewrite>
    </system.webServer>
</configuration>

To ensure the config gets deployed, put it in the src directory:

vs

And add it to list of assets within the .angular-cli.json:

cli