nmca70
nmca70

Reputation: 313

Azure DevOps CI/CD Deploy Web or Function App changing the values in appsettings in YAML Pipelines

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!

Upvotes: 3

Views: 2775

Answers (2)

nmca70
nmca70

Reputation: 313

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)

Upvotes: 3

Kevin Lu-MSFT
Kevin Lu-MSFT

Reputation: 35184

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

Upvotes: 5

Related Questions