30

Given the following resource in an AzureRM template, how would one encode the single quote in the commandToExecute part?

{
  "type": "Microsoft.Compute/virtualMachines/extensions",
  "name": "[concat(variables('vmNameMaster'), copyIndex(), '/sethost')]",
  "apiVersion": "2015-06-15",
  "location": "[resourceGroup().location]",
  "copy": {
      "name": "extensionLoopNode",
      "count": "[variables('masterCount')]"
  },
  "dependsOn": [
      "[concat('Microsoft.Compute/virtualMachines/', variables('vmNameMaster'), copyIndex(),'/extensions/DockerExtension')]"
  ],
  "properties": {
    "publisher": "Microsoft.OSTCExtensions",
    "type": "CustomScriptForLinux",
    "typeHandlerVersion": "1.4",
    "settings": {
      "fileUris": [ ],
      "commandToExecute": "[concat('/bin/bash -c \'echo \"export DOCKER_HOST=:2375\" >> /home/', parameters('adminUsername') ,'/.profile\'')]",
      "timestamp": 123456789
    }
  }
},
Scott Weldon
  • 9,673
  • 6
  • 48
  • 67
Poul K. Sørensen
  • 16,950
  • 21
  • 126
  • 283
  • Have you tried escaping using \. i.e. "commandToExecute": "[concat('/bin/bash -c \'echo \"export DOCKER_HOST=:2375\" >> /home/\', parameters(\'adminUsername\') ,\'/.profile\'')]" – Steve Ford Nov 30 '15 at 12:57

4 Answers4

63

You escape Azure ARM functions in the same way as with VB strings: you simply double the single quote characters.

[concat('This is a ''quoted'' word.')]

outputs

This is a 'quoted' word.

Double quotes still needs to be escaped from JSON.

 [concat('''single'' and \"double\" quotes.')]

outputs

'single' and "double" quotes.
Eric Cote
  • 851
  • 1
  • 7
  • 7
  • 11
    This should be the accepted answer as the currently accepted answer is not as elegant. – zurebe-pieter Apr 23 '18 at 16:00
  • 3
    Unfortunately, Visual Studio will view this as an error: Expected a comma. It may work, but you will have to ignore the red squiggle. A lot of people will find this unacceptable. – friggle Jan 29 '20 at 21:54
  • 2
    this didn't work for me. So I'll have to resort to the less elegant solution :) – Thiago Passos Aug 28 '20 at 14:29
  • While deploying resources in Azure Synapse using ARM templates I found that [concat('This is a ''quoted'' word.')] became "This is a ''quoted'' word" for some annoying reason. The accepted answer worked in that case. – Alexander Kvist Jul 17 '23 at 12:28
18

I've worked around this with a variable:

"variables": {
    "singleQuote": "'",
},
...
"settings": {
    "fileUris": [],
    "commandToExecute": "[concat('/bin/bash -c ', variables('singleQuote'), 'echo \"export DOCKER_HOST=:2375\" >> /home/', parameters('adminUsername') ,'/.profile', variables('singleQuote'))]",
}

It isn't elegant but it works.

Scott Weldon
  • 9,673
  • 6
  • 48
  • 67
Jason Stangroome
  • 4,459
  • 3
  • 33
  • 39
2

In DevOps release pipeline, for APIM policy, use & quote; to escape quotes within an expression,

<when condition='@(context.Variables.GetValueOrDefault&lt;bool&gt;(&quot;isAuthOk&quot;))' />
usman shaheen
  • 3,636
  • 4
  • 30
  • 36
-4

it is not necessary encode the single quote in the commandToExecute part. The json segment below has been validated as valid json in http://jsonlint.com/

{
    "type": "Microsoft.Compute / virtualMachines / extensions ",
    "name": "[concat(variables('vmNameMaster'), copyIndex(), '/sethost')]",
    "apiVersion": "2015-06-15",
    "location": "[resourceGroup().location]",
    "copy": {
        "name": "extensionLoopNode",
        "count": "[variables('masterCount')]"
    },
    "dependsOn": [
        "[concat('Microsoft.Compute/virtualMachines/', variables('vmNameMaster'), copyIndex(),'/extensions/DockerExtension')]"
    ],
    "properties": {
        "publisher": "Microsoft.OSTCExtensions",
        "type": "CustomScriptForLinux",
        "typeHandlerVersion": "1.4",
        "settings": {
            "fileUris": [],
            "commandToExecute": "[concat('/bin/bash -c 'echo \"export DOCKER_HOST=:2375\" >> /home/', parameters('adminUsername') ,'/.profile'')]",
            "timestamp": 123456789
        }
    }
}
juvchan
  • 6,113
  • 2
  • 22
  • 35