Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

az functionapp config appsettings set Munges values into first setting when no spaces are used in PowerShell with multiple settings #23920

Closed
aolszowka opened this issue Sep 16, 2022 · 7 comments
Assignees
Labels
Auto-Assign Auto assign by bot bug This issue requires a change to an existing behavior in the product in order to be resolved. customer-reported Issues that are reported by GitHub users external to the Azure organization. CXP Attention This issue is handled by CXP team. Functions az functionapp Mgmt This issue points to a problem in the management-plane of the library.

Comments

@aolszowka
Copy link

Related to #23919 but different behavior.

I have been trying to troubleshoot why I am unable to use the documented --settings switch with multiple space separated Key=Value pairs Documentation in a PowerShell script I have for provisioning. In my production script I end up having all of the secrets roll into the first secret.

I am able to reproduce this behavior with this new script.

I suspect that there is an issue with the way that these values are parsed after the argument and a combination of sending this from PowerShell.

Describe the bug

Command Name
az functionapp config appsettings set

Errors:
This does not error but produces undesired behavior that is detailed below.

To Reproduce:

Steps to reproduce the behavior. Note that argument values have been redacted, as they may contain sensitive information.

  • az functionapp config appsettings set --name {} --resource-group {} --settings {}

This command is being generated from this PowerShell Script (I have redacted any private information):

$appSettingsToUpdate = [System.Collections.Generic.Dictionary[string, string]]::new()
$appSettingsToUpdate.Add("Setting1", "SetValueWithNoSpaces")
$appSettingsToUpdate.Add("Setting2", "SetValueWithNoSpaces2")

[System.Text.StringBuilder]$settingsString = [System.Text.StringBuilder]::new()
foreach ($appSettingToUpdate in $appSettingsToUpdate.GetEnumerator()) {
    $settingsString.Append("""$($appSettingToUpdate.Key)=$($appSettingToUpdate.Value)"" ") | Out-Null
}

$expandedSettingsString = $settingsString.ToString()

# Set the new settings; This will restart the function app
az functionapp config appsettings set --name {REDACTED} --resource-group {REDACTED} --settings $expandedSettingsString

This ends up generating this for a setting:

  {
    "name": "Setting1",
    "slotSetting": false,
    "value": "SetValueWithNoSpaces Setting2=SetValueWithNoSpaces2"
  }

As you can see Setting1 has been munged together with Setting2

Expected Behavior

This should have generated something equivalent to the following:

az functionapp config appsettings set --name {REDACTED} --resource-group {REDACTED} --settings "Setting1=SetValueWithNoSpaces" "Setting2=SetValueWithNoSpaces2"

Which does work when manually ran through the command line.

Workaround

Again I suspect there is probably some weird behavior with PowerShell and the way this command is passed to az combined with the way that az parses commands. From the error report you can see that az thinks it only got one setting rather than the space separated values that the script expected to send.

Again I am going to try working around this by passing a JSON file that contains the settings to avoid this, but for functionapp this is not documented behavior.

Environment Summary

Windows-10-10.0.19044-SP0
Python 3.10.5
Installer: MSI

azure-cli 2.40.0

Extensions:
azure-devops 0.25.0

Dependencies:
msal 1.18.0b1
azure-mgmt-resource 21.1.0b1

$PSVersionTable
Name                           Value
----                           -----
PSVersion                      7.2.6
PSEdition                      Core
GitCommitId                    7.2.6
OS                             Microsoft Windows 10.0.19044
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Additional Context

@ghost ghost added customer-reported Issues that are reported by GitHub users external to the Azure organization. Auto-Assign Auto assign by bot CXP Attention This issue is handled by CXP team. Functions az functionapp labels Sep 16, 2022
@yonzhan
Copy link
Collaborator

yonzhan commented Sep 16, 2022

route to CXP team

@aolszowka
Copy link
Author

I can confirm that the following workaround does indeed work:

$appSettingsToUpdate2 = [System.Collections.Generic.Dictionary[string, string]]::new()
$appSettingsToUpdate2.Add("Setting1", "SetValueWithNoSpaces")
$appSettingsToUpdate2.Add("Setting2", "SetValueWithNoSpaces2")

$appSettingsToUpdate = foreach ($appSettingToUpdate in $appSettingsToUpdate2.GetEnumerator()) {
    [PSCustomObject]@{
        name        = $appSettingToUpdate.Key
        slotSetting = $false
        value       = $appSettingToUpdate.Value
    }
}

# Due to this issue we're going to work around this by creating a
# throw-away JSON file to pass to the command:
# https://github.com/Azure/azure-cli/issues/23920
# https://docs.microsoft.com/en-us/cli/azure/functionapp/config/appsettings?view=azure-cli-latest#az-functionapp-config-appsettings-set
$appSettingsJsonFile = New-TemporaryFile
try {
    $appSettingsToUpdate | ConvertTo-Json | Out-File -FilePath $appSettingsJsonFile.FullName

    # Set the new settings; This will restart the function app
    # Note that as of 2022/09/16 taking a JSON file is undocumented but
    # does work.
    az functionapp config appsettings set --name {REDACTED} --resource-group {REDACTED} --settings "@$($appSettingsJsonFile.FullName)"
}
finally {
    # Cleanup after ourselves
    Remove-Item $appSettingsJsonFile
}

Properly updates the settings like so:

  {
    "name": "Setting1",
    "slotSetting": false,
    "value": "SetValueWithNoSpaces"
  },
  {
    "name": "Setting2",
    "slotSetting": false,
    "value": "SetValueWithNoSpaces2"
  }

@RakeshMohanMSFT RakeshMohanMSFT self-assigned this Sep 17, 2022
@RakeshMohanMSFT
Copy link
Contributor

@aolszowka Thank you for reaching out, glad to know that the work around helped. We are investigating the original issue

@jiasli
Copy link
Member

jiasli commented Sep 19, 2022

Duplicate of #23797

@jiasli jiasli marked this as a duplicate of #23797 Sep 19, 2022
@jiasli jiasli closed this as completed Sep 19, 2022
@aolszowka
Copy link
Author

@jiasli Again the linked issue looks to be an end user passing an Array, this passes a constructed space delimited string. Can you explain what I'm missing here? Is this some PowerShell Functionality that I don't quite understand?

@jiasli
Copy link
Member

jiasli commented Sep 19, 2022

This should work:

$appSettingsToUpdate = [System.Collections.Generic.Dictionary[string, string]]::new()
$appSettingsToUpdate.Add("Setting1", "SetValueWithNoSpaces")
$appSettingsToUpdate.Add("Setting2", "SetValueWithNoSpaces2")

$settings = [System.Collections.ArrayList]@()

foreach ($appSettingToUpdate in $appSettingsToUpdate.GetEnumerator()) {
    $settings.Add("$($appSettingToUpdate.Key)=$($appSettingToUpdate.Value)")
}

# Set the new settings; This will restart the function app
az functionapp config appsettings set --name REDACTED --resource-group REDACTED --settings @settings --debug

Output:

cli.knack.cli: Command arguments: ['functionapp', 'config', 'appsettings', 'set', '--name', 'REDACTED', '--resource-group', 'REDACTED', '--settings', 'Setting1=SetValueWithNoSpaces', 'Setting2=SetValueWithNoSpaces2', '--debug']

@aolszowka
Copy link
Author

Correct, because you've changed the behavior of the script to instead pass a PowerShell Array instead of using the string.

As you mentioned in the sister issue the root cause of the problem is PowerShell/PowerShell#1995 which supposedly is fixed in PowerShell 7.3.

I will use the work around of passing the JSON object as this will subvert both issues entirely.

I appreciate you digging further into this.

@RakeshMohanMSFT RakeshMohanMSFT added bug This issue requires a change to an existing behavior in the product in order to be resolved. Mgmt This issue points to a problem in the management-plane of the library. labels Oct 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Auto-Assign Auto assign by bot bug This issue requires a change to an existing behavior in the product in order to be resolved. customer-reported Issues that are reported by GitHub users external to the Azure organization. CXP Attention This issue is handled by CXP team. Functions az functionapp Mgmt This issue points to a problem in the management-plane of the library.
Projects
None yet
Development

No branches or pull requests

4 participants