2

I published an app using Azure CLI with command

func azure functionapp publish [my-app-name] --nozip

Now I want to update the configuration of the app to connect to the Azure Key Vault and get secrets from the Vault. So, I am running this command

az functionapp config appsettings set --name [my-app-name] --resource-group [my-app-res-group] --settings "PublicKey=@Microsoft.KeyVault(VaultName=[vault-name];SecretName=[secret-name])"

this returns an error like this

request failed: Error occurred in request., RetryError: HTTPSConnectionPool(host='management.azure.com', port=443): Max retries exceeded with url: /subscriptions/[my-sub-guid]/resourceGroups/[my-app-res-group]/providers/Microsoft.Web/sites/[my-app-name]/config/appsettings?api-version=2019-08-01 (Caused by ResponseError('too many 500 error responses',))

But the command work fine and publish the setting to the Azure except it publish not

PublicKey=@Microsoft.KeyVault(VaultName=[vault-name];SecretName=[secret-name])

But

PublicKey=@Microsoft.KeyVault(VaultName=[vault-name];SecretName=[secret-name]

Whats the problem with closing ) and what can I do to overcome this issue.

P.S. I know I can do this both from Azure Portal, Visual Studio and VS Code but it's critical for me to do this using commandline tool!

2 Answers2

3

You can have a look at this wiki around quoting issues with PowerShell:

To make it work you have few options:

  1. Add additional double quotes for force powershell to treat the argument as a literal:

    az functionapp config appsettings set --name [my-app-name] --resource-group [my-app-res-group] --settings `""PublicKey=@Microsoft.KeyVault(VaultName=[vault-name];SecretName=[secret-name])"`"
    
  2. Use --% to stop PowerShell from parsing the argument and escape double quotes

    az --% functionapp config appsettings set --name [my-app-name] --resource-group [my-app-res-group] --settings "PublicKey=@Microsoft.KeyVault(VaultName=[vault-name];SecretName=[secret-name])"
    
Thomas
  • 24,234
  • 6
  • 81
  • 125
0

To complement Thomas's helpful answer:

The problem comes down to two separate behaviors:

  • The az CLI is implemented as a batch file (az.cmd)

  • PowerShell - of necessity - rebuilds the command line that is passed to external programs (which includes batch files) behind the scenes.

    • In doing so, it uses "..." quoting (the only kind of quoting that external programs can be expected to understand) on demand: argument values are only enclosed in "..." if they contain spaces.

Unfortunately - and inappropriately - cmd.exe (the interpreter of batch files) evaluates the arguments passed to batch file as if they had been submitted from inside a cmd.exe session, which causes space-less arguments - which PowerShell passes unquoted - that happen to contain cmd.exe metacharacters (e.g, &) to be interpreted as such, breaking the command.


The upshot is: you need to control the quoting used on the process command line explicitly:

  • To pass verbatim arguments to az.cmd, you can use --%, the stop-parsing token - though note its fundamental limitations, summarized in the bottom section of this answer:
# Note the use of --% after --settings; only for *verbatim* arguments.
az functionapp config appsettings set --name [my-app-name] --resource-group [my-app-res-group] --settings --% "PublicKey=@Microsoft.KeyVault(VaultName=[vault-name];SecretName=[secret-name])"
  • If you need string expansion (interpolation), i.e. if the arguments need to be expressed in terms of PowerShell variables or expressions, call via cmd.exe /c:

    • On the PowerShell side, an expandable (double-quoted) string ("...") ensures that PowerShell variables (e.g., $foo) or expressions (e.g., $(1 + 2)) are interpolated; embedded " chars. must be escaped as `"
cmd /c "az functionapp config appsettings set --name [my-app-name] --resource-group [my-app-res-group] --settings `"PublicKey=@Microsoft.KeyVault(VaultName=[vault-name];SecretName=[secret-name])`""

Note:

  • Using direct invocation with `""..."`" or "`"...`"" to ensure "..." enclosure on the resulting process command line should never have worked, and only works due to a long-standing bug - see this answer.

    • While this bug was mostly fixed in PowerShell (Core) 7.3, the old, broken behavior is - unfortunately - selectively retained on Windows, notably when calling batch files.

  • The advantage of the cmd /c approach is that it predictably works, irrespective of what external program you're calling, and is therefore the preferable way to control the exact quoting if and when needed.

mklement0
  • 382,024
  • 64
  • 607
  • 775