azure-cli: -j/--handle-extended-json-format does not work as expected for mutil-line string containing double quotes
Hi experts, I found if an ARM template contains multi-line string containing double quotes, the template deployment will fail, please help to check, thank you. I would like to pass parameters that contains double quotes to shell script within virtual machine extension, please see variables executeCustomScriptArguments1. The template deployment failed. I deploy the template with az cli flag --handle-extended-json-format, az version is 2.2.0. My template works if I change the mutil-line string to single line string. Error:
cli.azure.cli.core.util : Invalid control character at: line 1 column 5789 (char 5788)
The flag also works for cases listed in document, I can make sure my Az CLI supports --handle-extended-json-format.
Attach my template:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"_artifactsLocation": {
"type": "string",
"metadata": {
"description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated."
},
"defaultValue": "[deployment().properties.templateLink.uri]"
},
"_artifactsLocationSasToken": {
"type": "securestring",
"metadata": {
"description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured."
},
"defaultValue": ""
},
"guidValue": {
"type": "string",
"defaultValue": "[newGuid()]"
},
"adminUsername": {
"type": "string",
"metadata": {
"description": "User name for the Virtual Machine."
}
},
"authenticationType": {
"type": "string",
"defaultValue": "password",
"allowedValues": [
"sshPublicKey",
"password"
],
"metadata": {
"description": "Type of authentication to use on the Virtual Machine. SSH key is recommended."
}
},
"adminPasswordOrKey": {
"type": "securestring",
"metadata": {
"description": "SSH Key or password for the Virtual Machine. SSH key is recommended."
}
},
"acceptOTNLicenseAgreement": {
"type": "string",
"metadata": {
"description": "Do you agree to provide OTN credentials to accept OTN License Agreement? Enter Y or y to agree, else N or n"
}
},
"otnAccountUsername": {
"type": "string",
"metadata": {
"description": "Username for your Oracle Technology Network account"
}
},
"otnAccountPassword": {
"type": "securestring",
"metadata": {
"description": "Password for your Oracle Technology Network account"
}
},
"portsToExpose": {
"type": "string",
"defaultValue": "80,443,7001-9000",
"metadata": {
"description": "Ports and port ranges to expose"
}
},
"wlsDomainName": {
"type": "string",
"metadata": {
"description": "Provide Weblogic domain name"
}
},
"wlsUserName": {
"type": "string",
"metadata": {
"description": "Username for your Weblogic domain name"
}
},
"wlsPassword": {
"type": "securestring",
"metadata": {
"description": "Password for your Weblogic domain name"
}
},
"dnsLabelPrefix": {
"type": "string",
"metadata": {
"description": "Unique DNS Name for the Public IP used to access the Virtual Machine."
}
},
"linuxOSVersion": {
"type": "string",
"defaultValue": "7.4",
"allowedValues": [
"7.4",
"7.3"
],
"metadata": {
"description": "The Oracle Linux version for the VM. This will pick a fully patched image of this given Oracle Linux version."
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"vmSizeSelect": {
"type": "string",
"defaultValue": "Standard_A3",
"allowedValues": [
"Standard_A1",
"Standard_A2",
"Standard_A3",
"Standard_A4"
],
"metadata": {
"description": "Select appropriate VM Size as per requirement (Standard_A1, Standard_A2, Standard_A3, Standard_A4)"
}
},
"configureAAD": {
"type": "bool",
"defaultValue": false,
"metadata": {
"description": "Bool value, if it's set to true, will enable Azure Active Directory after WebLogic Server starts."
}
},
"wlsLDAPProviderName": {
"type": "string",
"defaultValue": "AzureActiveDirectoryProvider",
"metadata": {
"description": "The value used for creating authentication provider name of WebLogic Server."
}
},
"addsServerHost": {
"type": "string",
"defaultValue": "ldaps.example.com",
"metadata": {
"description": "The LDAP server host."
}
},
"addsPublicIP": {
"type": "string",
"defaultValue": "The LDAP server public IP address"
},
"aadsPortNumber": {
"type": "string",
"defaultValue": "636",
"metadata": {
"description": "Accessible port of the LDAP server."
}
},
"wlsLDAPPrincipal": {
"type": "string",
"defaultValue": "null",
"metadata": {
"description": "The Distinguished Name (DN) of the LDAP user that WebLogic Server should use to connect to the LDAP server."
}
},
"wlsLDAPPrincipalPassword": {
"type": "securestring",
"defaultValue":"[newGuid()]",
"metadata": {
"description": "The credential (usually a password) used to connect to the LDAP server."
}
},
"wlsLDAPUserBaseDN": {
"type": "string",
"defaultValue": "null",
"metadata": {
"description": "The base distinguished name (DN) of the tree in the LDAP directory that contains users."
}
},
"wlsLDAPGroupBaseDN": {
"type": "string",
"defaultValue": "null",
"metadata": {
"description": "The base distinguished name (DN) of the tree in the LDAP directory that contains groups."
}
},
"wlsLDAPSSLCertificate": {
"type": "string",
"defaultValue": "null",
"metadata": {
"description": "Client certificate that will be imported to trust store of SSL."
}
}
},
"variables": {
"storageAccountName": "[concat(take(replace(parameters('guidValue'),'-',''),6),'olvm')]",
"imagePublisher": "Oracle",
"imageOffer": "Oracle-Linux",
"nicName": "adminServerVM_NIC",
"addressPrefix": "10.0.0.0/16",
"subnetName": "Subnet",
"subnetPrefix": "10.0.0.0/24",
"storageAccountType": "Standard_LRS",
"publicIPAddressName": "adminServerVM_PublicIP",
"publicIPAddressType": "Dynamic",
"vmName": "adminServerVM",
"vmSize": "[parameters('vmSizeSelect')]",
"virtualNetworkName": "[concat(parameters('wlsDomainName'),'_VNET')]",
"oradownScript": "oradown.sh",
"ScriptFileName": "setupAdminDomain.sh",
"pyConfigureSSL": "configure-ssl.py",
"pyConfigureLDAP": "configure-active-directory.py",
"linuxConfiguration": {
"disablePasswordAuthentication": true,
"ssh": {
"publicKeys": [
{
"path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]",
"keyData": "[parameters('adminPasswordOrKey')]"
}
]
}
},
"subnetRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]",
"networkSecurityGroupName": "[concat(parameters('dnsLabelPrefix'), '-nsg')]",
"networkSecurityGroupRef": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]",
"requiredPortrange": ",65200-65535,5556",
"executeCustomScriptArguments1": "[
if(parameters('configureAAD'),
concat(parameters('wlsLDAPProviderName'), ' ',
parameters('addsServerHost'), ' ',
parameters('aadsPortNumber'), ' ',
concat('\"',parameters('wlsLDAPPrincipal'),'\"'), ' ',
parameters('wlsLDAPPrincipalPassword'), ' ',
concat('\"',parameters('wlsLDAPUserBaseDN'),'\"'), ' ',
concat('\"',parameters('wlsLDAPGroupBaseDN'),'\"'), ' ',
parameters('wlsLDAPSSLCertificate'), ' ',
parameters('addsPublicIP'), ' ',
parameters('adminPasswordOrKey')),'')
]"
},
"resources": [
{
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2019-06-01",
"name": "[variables('networkSecurityGroupName')]",
"location": "[parameters('location')]",
"properties": {
"securityRules": [
{
"name": "WebLogicPorts",
"properties": {
"protocol": "TCP",
"sourcePortRange": "*",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 320,
"direction": "Inbound",
"destinationPortRanges": "[split(concat(parameters('portsToExpose'),variables('requiredPortrange')), ',')]"
}
}
]
}
},
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-06-01",
"name": "[variables('storageAccountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[variables('storageAccountType')]"
},
"kind": "Storage",
"properties": {}
},
{
"type": "Microsoft.Network/publicIPAddresses",
"apiVersion": "2018-11-01",
"name": "[variables('publicIPAddressName')]",
"location": "[parameters('location')]",
"properties": {
"publicIPAllocationMethod": "[variables('publicIPAddressType')]",
"dnsSettings": {
"domainNameLabel": "[concat(toLower(parameters('dnsLabelPrefix')),'-',take(replace(parameters('guidValue'), '-', ''), 10),'-',toLower(parameters('wlsDomainName')))]"
}
}
},
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2018-11-01",
"name": "[variables('virtualNetworkName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[variables('networkSecurityGroupRef')]"
],
"properties": {
"addressSpace": {
"addressPrefixes": [
"[variables('addressPrefix')]"
]
},
"subnets": [
{
"name": "[variables('subnetName')]",
"properties": {
"addressPrefix": "[variables('subnetPrefix')]",
"networkSecurityGroup": {
"id": "[variables('networkSecurityGroupRef')]"
}
}
}
]
}
},
{
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2018-11-01",
"name": "[variables('nicName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]",
"[resourceId('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]"
},
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
]
}
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2018-10-01",
"name": "[variables('vmName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
"[resourceId('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
],
"properties": {
"hardwareProfile": {
"vmSize": "[variables('vmSize')]"
},
"osProfile": {
"computerName": "[variables('vmName')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPasswordOrKey')]",
"linuxConfiguration": "[if(equals(parameters('authenticationType'), 'password'), json('null'), variables('linuxConfiguration'))]"
},
"storageProfile": {
"imageReference": {
"publisher": "[variables('imagePublisher')]",
"offer": "[variables('imageOffer')]",
"sku": "[parameters('linuxOSVersion')]",
"version": "latest"
},
"osDisk": {
"createOption": "FromImage"
},
"dataDisks": [
{
"diskSizeGB": 900,
"lun": 0,
"createOption": "Empty"
}
]
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
}
]
},
"diagnosticsProfile": {
"bootDiagnostics": {
"enabled": true,
"storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), '2019-06-01').primaryEndpoints.blob]"
}
}
}
},
{
"type": "Microsoft.Compute/virtualMachines/extensions",
"name": "[concat(variables('vmName'),'/newuserscript')]",
"apiVersion": "2019-07-01",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
],
"properties": {
"publisher": "Microsoft.Azure.Extensions",
"type": "CustomScript",
"typeHandlerVersion": "2.0",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": [
"[uri(parameters('_artifactsLocation'), concat('scripts/', variables('ScriptFileName'), parameters('_artifactsLocationSasToken')))]",
"[uri(parameters('_artifactsLocation'), concat('scripts/', variables('oradownScript'), parameters('_artifactsLocationSasToken')))]",
"[uri(parameters('_artifactsLocation'), concat('scripts/', variables('pyConfigureSSL'), parameters('_artifactsLocationSasToken')))]",
"[uri(parameters('_artifactsLocation'), concat('scripts/', variables('pyConfigureLDAP'), parameters('_artifactsLocationSasToken')))]"
],
"commandToExecute": "[concat('sh',' ',variables('ScriptFileName'),' ',parameters('acceptOTNLicenseAgreement'),' ',parameters('otnAccountUsername'),' ',parameters('otnAccountPassword'),' ',parameters('wlsDomainName'),' ',parameters('wlsUserName'),' ',parameters('wlsPassword'),' ',variables('vmName'),' ',parameters('configureAAD'),' ',variables('executeCustomScriptArguments1'),' ')]"
}
}
}
]
}
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 16 (10 by maintainers)
I’d also make the argument that the value after the service processing is precisely what is expected. The fact that it won’t work is specific to the field. It should be perfectly valid to have a variable whose value includes newlines. You just can’t use that variable in a context where the new line wouldn’t be allowed.
For example, both of these values should be equivalent, and neither of them should work in a situation like this.
@galiacheng Hi, mutil-line is not supported in the semantics of JSON, so I understand that this issue is a feature request.
This error was obtained from the validationin of CLI. I tried to make CLI ignore the line feed in a string when validating JSON, but I still found some problems: the ARM template in CLI is designed to send to Service must be unmodified, and Service will add the line break as text to the multi-line string, such as:
The string
"executeCustomScriptArguments1"you pass in is actually a string of arguments that need to be parsed, and the extra line breaks in the middle will obviously destroy the parsing logic of these arguments.