question

nrc avatar image
2 Votes"
nrc asked durayakar answered

App Service (Web App): How to manage Slots App Settings using ARM templates and Azure Pipelines?

Dear all,

We are currently working on automating deployment of an App Service (Web App) in Azure.

Our goals are:

  • To use slots to do hot deployment

  • To use an Azure DevOps Release pipeline and ARM templates for deploying the App Service resource, including the Staging slot

  • To have another Azure Release pipeline to deploy the binaries of the application to the Staging slot, including App Settings values


Some settings are "deployment slot settings" and some aren't - see https://docs.microsoft.com/en-us/azure/app-service/deploy-staging-slots for explanations.

The problem is, we can't find a way to differentiate the deployment slot settings from those who swap with the slot in ARM template. In ARM template, an App Setting is just a name - value pair, and all App Settings belong to the same App Settings resource type (see https://docs.microsoft.com/en-us/azuretemplates/microsoft.web/2018-02-01/sites).

To the best of my understanding this doesn't allow us to specify slot settings - so what is the solution to do that?

Thanks in advance for your answer.


azure-webapps
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

DabhanMSFT-1185 avatar image
0 Votes"
DabhanMSFT-1185 answered

Hi

Deploying your application to a non-production slot has the following benefits:


You can validate app changes in a staging deployment slot before swapping it with the production slot.
Deploying an app to a slot first and swapping it into production makes sure that all instances of the slot are warmed up before being swapped into production. This eliminates downtime when you deploy your app. The traffic redirection is seamless, and no requests are dropped because of swap operations. You can automate this entire workflow by configuring auto swap when pre-swap validation isn't needed.
After a swap, the slot with previously staged app now has the previous production app. If the changes swapped into the production slot aren't as you expect, you can perform the same swap immediately to get your "last known good site" back.

Which settings are swapped?
When you clone configuration from another deployment slot, the cloned configuration is editable. Some configuration elements follow the content across a swap (not slot specific), whereas other configuration elements stay in the same slot after a swap (slot specific). The following lists show the settings that change when you swap slots.

Settings that are swapped:

General settings, such as framework version, 32/64-bit, web sockets
App settings (can be configured to stick to a slot)
Connection strings (can be configured to stick to a slot)
Handler mappings
Public certificates
WebJobs content
Hybrid connections
Virtual network integration

Service endpoints
Azure Content Delivery Network

Features marked with an asterisk (*) are planned to be unswapped.

Refer - https://docs.microsoft.com/en-us/azure/app-service/deploy-staging-slots#which-settings-are-swapped

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

nrc avatar image
1 Vote"
nrc answered

Thank you @DabhanMSFT-1185 ,

So to clarify - my question is very specific to App settings and to how to manage them when creating the Web App and the Slots programatically by the mean of ARM templates.

In the link that we share, section "Which settings are swapped?", the list "Settings that are swapped:" says "App settings (can be configured to stick to a slot)". Fine. So I have the option to choose which ones are swapped and which ones aren't.

Now when I look at the description of the ARM template to create the Web app (see https://docs.microsoft.com/en-us/azure/templates/microsoft.web/2019-08-01/sites ), I can't find a way to specify which App settings I want to swap and which ones I want to stick to a Slot, because there is only one appSettings section which only contains name / value pairs of App settings. And the slots (https://docs.microsoft.com/en-us/azure/templates/microsoft.web/2019-08-01/sites/slots/config ) use the same section.

Thus the question: how can I declare programatically an App setting is swappable and another one isn't?

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

ajeetchouksey avatar image
0 Votes"
ajeetchouksey answered nrc commented

You can add the following PS task. Hope this will help.

Get Azure Functions App Settings

Write-Host "Getting Azure Web App Settings..."
$azureWebNames = Get-AzureRmResource -ResourceGroupName "ResoruceGroupName" -ResourceType "Microsoft.Web/sites"

$azureWebNames | ForEach-Object -Process{
$webAppNames = $_.Name

 $webAppSettings= Get-AzureRmWebAppslot -ResourceGroupName "ResoruceGroupName" -Name $webAppNames -slot "slotname"

 $webAppSettings|  ForEach-Object -Process{
     $currentAppSettings = $functionAppSettings.SiteConfig.AppSettings
     $newAppSettings = @{}
         ForEach ($item in $currentAppSettings){
             $newAppSettings[$item.Name] = $item.Value
             $newAppSettings["CosmosDb_ConnectionString"] = $conn
             $newAppSettings["DatabaseName"] = $databaseName         
         }
     Set-AzureRmWebAppSot -AppSettings $newAppSettings -Name $webAppNames  -ResourceGroupName "ResoruceGroupName" -slot "slotname"
  }

}

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@ajeetchouksey This PowerShell snippet adds app settings to a slot but where do you say that the app setting is sticky? Or am I missing something?

0 Votes 0 ·
DabhanMSFT-1185 avatar image
0 Votes"
DabhanMSFT-1185 answered nrc commented

An example to make slot sticky:

$connectionString = @{}
$webAppName = "Web AppName"
$resourceGroup ="Resource Group Name"
$slotName ="slot Name"
$connectionString.Add("AzureWebJobsStorage", @{ value = "The Actual connecting string here" ; Type = 3 }) #Custom
$connectionString.Add("Common", @{ value = "The Actual connecting string here" ; Type = 2 }) #Azure SQL

Login-AzureRmAccount
# creat slot connection string
New-AzureRmResource -PropertyObject $connectionString -ResourceGroupName $resourceGroup
-ResourceType "Microsoft.Web/sites/slots/config" -ResourceName "$webAppName/$slotName/connectionstrings"
-ApiVersion 2015-08-01 -Force

set connection string as sticky setting


$stickSlotConfigObject = @{"connectionStringNames" = @("AzureWebJobsStorage","Common")} #connection string Name
Set-AzureRmResource -PropertyObject $stickSlotConfigObject -ResourceGroupName $resourceGroup
-ResourceType Microsoft.Web/sites/config -ResourceName $webAppName/slotConfigNames
-ApiVersion 2015-08-01 -Force

Refer: https://blogs.msdn.microsoft.com/benjaminperkins/2017/09/04/how-to-make-an-app-setting-or-connection-string-sticky/

· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@DabhanMSFT-1185 I appreciate your answer but it doesn't work for me :(

The Set-AzureWebsite solution exposed in Benjamin Perkins' blog is based on the Azure Powershell module (now being replaced by the Az Powershell module)

When I try it, logging through Login-AzureRmAccount as he does, I get the following error message:

 Set-AzureWebsite : No default subscription has been designated. Use Select-AzureSubscription -Default
  to set the default subscription.





0 Votes 0 ·

If I use Add-AzureAccount to connect, I get the following:

 Add-AzureAccount : No subscriptions are associated with the logged in account in Azure Service Management (RDFE). This
 means that the logged in user is not an administrator or co-administrator for any account.

0 Votes 0 ·

This message is true - I am a contributor, not an administrator nor a co-admin.

However being required to be an admin or a co-admin simply to set sticky slots when I can do so much more by being a contributor (creating all kind of resources I need, deleting them...) doesn't make sense.

And the security team will not allow me to be an admin or a co-admin, neither will they agree to have a Service Principal (which will eventually execute the script through Azure Pipelines) to be an admin or a co-admin!

0 Votes 0 ·
nrc avatar image
0 Votes"
nrc answered Kittoes0124 commented

Nothing to add on this topic?

So far this is my understanding on programmatically managing sticky App Settings, and it's quite disappointing:

  1. It can't be done with ARM templates

  2. It can't be done with Az PowerShell module

  3. It can be done with Azure PowerShell module, which will be deprecated and is being replaced by Az module mentionned above. The worst part is that Azure Powershell module requires the account used to be administrator or co-administrator of the subscription when Contributor on the Web App should be enough. This poses a security question.

Microsoft, we need something like Set-AzWebApp -SlotStickyAppSettingNames, and Set-AzWebApp -SlotStickyConnectionStringNames please!

Slots enable new, safer and more agile deployments, this is great, having sticky App Settings and Connection Strings is needed, so thanks for that, but lack of ability to manage them programmatically (unless done with a solution being deprecated and requiring exagerately high privileges) is a blocker to industrial / large scale use!






· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I agree, it is totally ridiculous that such a fundamental requirement to actually use slots for their intended purpose is unavailable

0 Votes 0 ·
gregslack-7120 avatar image
0 Votes"
gregslack-7120 answered

Google "slotconfignames". You'll find plenty of info from that. Basically it's a subresource of your app or slot resource.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Kittoes0124 avatar image
0 Votes"
Kittoes0124 answered Kittoes0124 edited

@nrc, what you want can be accomplished in ARM via the following magic incantation:

 {
     "apiVersion": "2019-08-01",
     "dependsOn": [
         "[variables('siteResourceId')]"
     ],
     "name": "[format('{0}/slotConfigNames', parameters('siteName'))]",
     "properties": {
         "appSettingNames": [
             "MySettingNameA",
             "MySettingNameB",
             "MySettingNameC"
         ]
     },
     "type": "Microsoft.Web/sites/config"
 }

Naming is the most important thing here, the resource should be called {siteName}/slotConfigNames and be of the type Microsoft.Web/sites/config. Getting this to work "neatly" takes a bit more fooling around; a full example can be found within the Microsoft.Web-sites template here.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

NickPurington-2789 avatar image
0 Votes"
NickPurington-2789 answered NickPurington-2789 rolled back

Definitely late to this one, but for anyone still looking for a solution, Azure DevOps has a task that can be added to a release pipeline to do everything @nrc was looking for. I've done some testing and it works great, plus you can just pull the app settings JSON from the portal and paste in the task instead of converting the app settings to "key:value" format in an ARM template.

azure-app-service-settings


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

durayakar avatar image
0 Votes"
durayakar answered

https://docs.microsoft.com/en-us/rest/api/appservice/web-apps/list-slot-configuration-names#slotconfignamesresource

@nrc ,
Please see the link above.
<rant>It is sometimes too hard to get your question through</rant> :)

You can use this in your ARM Template or Bicep to manage Slot App Settings.
The names you specify in the corresponding string arrays becomes "Slot" settings - the little tiny mini checkbox that says "slot setting" gets checked.
IMHO, Microsoft should have made this a property of the appSetting, storageSetting and connectionStrings.
This is so error-prone. What if the name you give in this string array does not exist as a setting? LOL.

Here is a Bicep blurb - please note the name of the slotConfig_resource, it has to be "slotConfigNames".

 param appService_SlotAppSettings array = [
   'setting1'
   'setting2'
   'setting3'
   'setting4'
 ]
 resource appService_resource 'Microsoft.Web/sites@2021-01-01' = {
   name: 'yourAppServiceName'
   location: resourceGroup().location  
 }
    
 resource slotConfig_resource 'Microsoft.Web/sites/config@2021-01-01' = {
   name: 'slotConfigNames'
   parent: appService_resource
   properties:{
     'appSettingNames': appService_SlotAppSettings
   }
 }




5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.