How to install this goddamn extensions?

Hey folks, this will be a really quick post. I've struggling with deploying my ASP.NET Core app via ARM template due to some unexpected problems. Since there's no magic "Enable .NET Core" button in Azure Portal or other App Service property, there's one thing you have to do to make yourself happy. Or maybe two. None is straightforward or intuitive.

Extension

Magically the only thing you need to run ASP.NET Core app in Azure is to install an extension:

Once you have it, your application will run without hesitation. But how to enable it via ARM template?

Use internet

To be honest I got literally no idea how to install an extension with my template. After quick search using Google I found this article. It shows a nice and quick way to deploy an application:

/
{
    "type": "siteextensions",
    "name": "AspNetCoreRuntime",
    "apiVersion": "2015-04-01",
    "location": "[resourceGroup().location]",
    "properties": {
        "version": "[parameters('aspnetcoreVersion')]"
    },
    "dependsOn": [
        "[resourceId('Microsoft.Web/Sites', parameters('siteName'))]"
    ]
}

However - for some reason this advice does not work - while deploying ARM throws an error, that AspNetCoreRuntime extension could not be found. Well, it never rains but it pours.

Use your head

I decided to stop experimenting with different approaches like:

  • using different values of version property
  • using full names as the proper value of name propety
  • installing extension using Powershell where it clearly worked

And made the one, final decision - I'll get rid of version and use(hopefully) the most recent one. Using following template:

/
{
    "type": "siteextensions",
    "name": "AspNetCoreRuntime",
    "apiVersion": "2015-04-01",
    "location": "[resourceGroup().location]",
    "dependsOn": [
        "[resourceId('Microsoft.Web/Sites', parameters('siteName'))]"
    ]
}

ARM had no problems deploying my App Service. 

I'm not sure whether you have to pass a very specific version as a value or maybe this parameter is not supported currently - all in all I was a bit dissapointed, that an article 3 months old seemed to be either outdated or incomplete. This is not how you help your community.

Finding deployment credentials of your Web App in Azure

When a Web App is published to Azure for the first time, publish profile is being generated containing basic information regarding what, where and how should be deployed. After you've automated your CI/CD pipeline, those informations are somehow lost. But what if I need to incorporate them in my build or release process? Fortunately there's an easy way to download all the data and use it for our purpose.

Azure CLI for the rescue!

To be honest, there's a few Powershell commands, which could help us here at least like:

  • Get-AzureWebsite
  • Get-AzureRMWebApp
  • Get-AzureRMWebAppPublishProfile

The first one is designed for Azure Classic and won't work e.g. when a connection type in VSTS is set to Azure Resource Manager. However it allows you to get credentials really easily:

/
$website = Get-AzureWebsite -Name $functionAppName

$username = $website.PublishingUsername
$password = $website.PublishingPassword

It will work perfectly if only you're not restricted to using ARM.

Get-AzureRMWebApp is a command, which is designed for working with Resource Manager. It's very similar to Get-AzureRMWebAppPublishProfile, the difference comes from the amount of information it returns. Since in this post we're focusing on getting deployment credentials, we'll skip the former and consider the latter only. When Get-AzureRMWebAppPublishProfile is called, it returns XML content, similar to .PublishSettings file which can be downloaded from Azure Portal. To fetch both a username and a password, you can use following script:

/
$xml = [xml](Get-AzureRMWebAppPublishingProfile -ResourceGroupName $resourceGroup -Name $functionAppName -OutputFile "__deploymentProfile.xml" -Format WebDeploy) 
$publishProfile =  $xml.FirstChild.ChildNodes[1]

$username = $publishProfile.userName.split('\')
$password = $publishProfile.userPWD

With those credentials, you can automate your CI/CD pipeline even more(e.g. they are needed when accessing Kudu for a master key for Azure Function). The only thing you have to remember, is to select the right version of the command, depending on the deployment model.