Issue applying deployment, Error due to invalid character in VM Extension

Hello All,

I have a CustomScript running via a VM Extension on a windows VM. I am passing powershell commands into this extension to run at deploy time.

I started running into issues when I started to implement Windows UNC paths when I figured out that ‘\’ in terraform is equal to '' in Windows. I believe this issue is either due to not escaping from a string correctly or a bug in how backslashes are handled.

Below are snippets of code and the associated error. Would appreciate any advice or feedback, thanks!

The errors are essentially the same and I’ve correlated it to the copy_fileshare_command locals variable.

locals {
fileshare_file_name          = "\"win_fileshare_mount.ps1\""
fileshare_path               = "\\\\${local.privatelink_fqdn}\\${var.fileshare_name}"
fileshare_script_path_upload = "${local.fileshare_path}\\${local.fileshare_file_name}"
copy_source                  = "\\\\${local.privatelink_fqdn}\\${var.fileshare_name}\\${local.fileshare_file_name}"
copy_destination             = "c:\\terraform"
copy_fileshare_command       = "copy ${local.copy_source} ${local.copy_destination}"
srv_powershell_command       = "${local.firewall_command}; ${local.fileshare_mount_command}; ${local.copy_fileshare_command}; ${local.exit_code_hack};"
wks_powershell_command       = "${local.firewall_command}; ${local.fileshare_mount_command}; ${local.copy_fileshare_command}; ${local.exit_code_hack};"
}

# win10 VM Extension
resource "azurerm_virtual_machine_extension" "wks_win10_vm_extension_bootstrap" {
  count                      = var.number_of_win10_wks
  depends_on                 = [azurerm_windows_virtual_machine.wks_win10]
  name                       = "win10postdeploy${count.index}"
  virtual_machine_id         = "${element(azurerm_windows_virtual_machine.wks_win10.*.id, count.index )}"
  publisher                  = "Microsoft.Compute" # "Microsoft.Azure.Extensions"
  type                       = "CustomScriptExtension" # "CustomScript"
  type_handler_version       = "1.9"
  #  auto_upgrade_minor_version = true
  settings = <<SETTINGS
  {
    "commandToExecute": "powershell -ExecutionPolicy unrestricted -NoProfile -NonInteractive -command \"${local.wks_powershell_command}\""
  }
SETTINGS
}

# Windows Server 2016 VM Extension
resource "azurerm_virtual_machine_extension" "srv_2016_vm_extension_bootstrap" {
  count                      = var.number_of_win_srv_2016
  depends_on                 = [azurerm_windows_virtual_machine.srv_win_2016]
  name                       = "srv2016postdeploy${count.index}"
  virtual_machine_id         = "${element(azurerm_windows_virtual_machine.srv_win_2016.*.id, count.index )}"
  publisher                  = "Microsoft.Compute" # "Microsoft.Azure.Extensions"
  type                       = "CustomScriptExtension" # "CustomScript"
  type_handler_version       = "1.9"
  #  auto_upgrade_minor_version = true
  settings = <<SETTINGS
  {
    "commandToExecute": "powershell -ExecutionPolicy unrestricted -NoProfile -NonInteractive -command \"${local.srv_powershell_command}\""
  }
SETTINGS
}


Errors:
│ Error: "settings" contains an invalid JSON: invalid character 'c' after object key:value pair
│
│   with module.compute.azurerm_virtual_machine_extension.wks_win10_vm_extension_bootstrap[0],
│   on modules/compute/win_10.tf line 94, in resource "azurerm_virtual_machine_extension" "wks_win10_vm_extension_bootstrap":
│   94:   settings = <<SETTINGS
│   95:   {
│   96:     "commandToExecute": "powershell -ExecutionPolicy unrestricted -NoProfile -NonInteractive -command \"${local.wks_powershell_command}\""
│   97:   }
│   98: SETTINGS

│ Error: "settings" contains an invalid JSON: invalid character 'c' after object key:value pair
│
│   with module.compute.azurerm_virtual_machine_extension.srv_2016_vm_extension_bootstrap[0],
│   on modules/compute/win_srv_2016.tf line 92, in resource "azurerm_virtual_machine_extension" "srv_2016_vm_extension_bootstrap":
│   92:   settings = <<SETTINGS
│   93:   {
│   94:     "commandToExecute": "powershell -ExecutionPolicy unrestricted -NoProfile -NonInteractive -command \"${local.srv_powershell_command}\""
│   95:   }
│   96: SETTINGS


For anyone else having this issue, I found a fix. Make use of single quotes within the argument to separate your strings. My specific use-case was getting hung up by the multiple variables and mixing terraform with powershell.