3

There has been some confusion internally around how to automate appsettings for Function Apps and Web Apps recently with some of our deployments, and checking around there appears to be a bewildering amount of options that look like they are doing roughly the same thing, but in different steps.

Our developers usually have an appsettings.json file they commit to the repo that might look something like this for their testing...

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
    }
  },
  "Values": {
    "ThingToPointTo": "http://localhost",
  }
}

When we take that to other environment e.g. PROD, we change the ThingToPointTo to something like "https://productionservice"

We have been using the Azure DevOps YAML pipelines to deploy and change the AppSettings in this way...

- task: AzureFunctionApp@1
  inputs:
    azureSubscription: 'OurAzureSubServiceConnection'
    appType: functionApp
    appName: $(azfuncappname)
    package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
    AppSettings: '-Values:ThingToPointTo "https://productionservice"'

My question is 2-fold

  1. Is the Values:ThingToPointTo correct for enumerating to the correct setting, or should it just be ThingToPointTo (omitting the Values:) ?

  2. Is this the way to do it? I notice there are JSON transform steps you can use to change the actual file before deploying it, and also a task called "Azure App Service Settings" available to use that will do it after deployment?

There are so many articles on the subject of this, but none seem to fit.

Thanks in advance!

nmca70
  • 183
  • 3
  • 16

2 Answers2

5

Is the Values:ThingToPointTo correct for enumerating to the correct setting, or should it just be ThingToPointTo (omitting the Values:) ?

The ThingToPointTo :https://productionservice could be the correct format. You don't need to add values.

For example:

- task: AzureFunctionApp@1
  displayName: 'Azure Function App Deploy: kevin0806'
  inputs:
    azureSubscription: '7.28-8.28'
    appType: functionApp
    appName: kevin
    appSettings: '-ThingToPointTo http://localhost'

Result:

enter image description here

Is this the way to do it? I notice there are JSON transform steps you can use to change the actual file before deploying it, and also a task called "Azure App Service Settings" available to use that will do it after deployment?

The Azure App Service Settings is used to change the setting after deployment.

Here is the template, you could refer to it:

steps:
- task: AzureRmWebAppDeployment@4
....

- task: AzureAppServiceSettings@1
  displayName: 'Azure App Service Settings: kevin0608'
  inputs:
    azureSubscription: '7.28-8.28'
    appName: kevin0608
    resourceGroupName: Kevintest
    appSettings: |
     [
        {
         "name": "ThingToPointTo",
         "value": "valueabcd",
         "slotSetting": false
        }
     
     ]

Here is a doc about Json Transform, you could also refer to it.

In addition, you could check this ticket:

Settings from appsettings.json are not displayed in Azure App Service Configuration, but >settings defined there override values in appsettings.json

The appsettings configuration in the task could show in the azure app service configuration, and it could override the value in appsettings.json.

Update:

The above is the case without nested variables.

If the variable is nested values, you can follow the following structure:

"first" : {
  "second": {
    "third" : "value"
  }
}



-first.second.third value1

If your app service is linux, you could use __ to replace .

e.g. - first__second__third value1

Note: Variable name matching is case-sensitive

Kevin Lu-MSFT
  • 20,786
  • 3
  • 19
  • 28
  • 1
    Thanks Kevin - Is "Values" a known hierarchy where you can bypass enumerating though it? What if there was also a section called "Settings" or "ServiceBusSettings" etc. ? – nmca70 Aug 06 '20 at 15:43
  • Hi @nmca70. Sorry. What I shared before is the case without nested variables.Please check the update. If there are nested variables, you can follow this structure. After the release is deployed. The appsettings in app service should be overrode. – Kevin Lu-MSFT Aug 07 '20 at 01:00
  • 2
    Hi, we had no joy with these. We did end up finding out that for nested vars using a colon : separator for Web Apps worked successfully. – nmca70 Aug 18 '20 at 09:14
  • Glad to know that you have found the method to solve this issue. You may add **your answer** and accept it. so it could help other community members who get the same issues , thanks. – Kevin Lu-MSFT Aug 18 '20 at 09:23
3

Thanks to @Kevin Lu-MSFT for talking through those options with me

We found that for webapps that have nested values...e.g.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
    }
  },
  "MySettings": {
    "ThingToPointTo": "http://localhost",
  }
}

...that the AppSettings in the AZDO YAML pipeline would indeed be...

- task: AzureFunctionApp@1
  inputs:
    azureSubscription: 'OurAzureSubServiceConnection'
    appType: functionApp
    appName: $(azfuncappname)
    package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
    AppSettings: '-MySettings:ThingToPointTo "https://productionservice"'

THIS IS DIFFERENT IT SEEMS FOR FUNCTION APPS!

If you have "Values" in the JSON you DON'T use Values: to enumerate !!!!...

For example...

{
  "Values": {
    "ThingToPointTo": "http://localhost",
  }
}

...ends up being...

AppSettings: '-ThingToPointTo "https://productionservice"'

There seems to be a double-standard with Function Apps! So beware (Most of this was completed using a .Net Core and Windows setup where applicable in Azure)

nmca70
  • 183
  • 3
  • 16