'pass to azurerm_virtual_machine_extension multiple files

I want to use terraform azurerm_virtual_machine_extension as module and somehow pass multiple files as settings parameter.

Here is an example:

module "ad_settings" {
  source = "./modules/cse" 
  vm_id = azurerm_virtual_machine.addc_vm.id  

  files = [
        "${azurerm_storage_container.scripts_ct.id}/1.ps1",
        "${azurerm_storage_container.scripts_ct.id}/2.ps1",
        "${azurerm_storage_container.scripts_ct.id}/22.ldif",
        "${azurerm_storage_container.scripts_ct.id}/3.zip",
        "${azurerm_storage_container.scripts_ct.id}/5.zip"]

  cse_protected_settings =  "powershell -ExecutionPolicy Unrestricted -File 1.ps1 ${var.vm_admin_name} ${var.vm_admin_pass} ${var.ad_domain_name} true"

}

cse_resources.tf

resource "azurerm_virtual_machine_extension" "template" {
  name                 = "CustomScriptExtension"
  virtual_machine_id   = var.vm_id
  publisher            = "Microsoft.Compute"
  type                 = "CustomScriptExtension"
  type_handler_version = "1.9"

  settings = <<SETTINGS
    {
      "fileUris": [
          ${var.files}
      ]
                }
SETTINGS 

  protected_settings = <<PROTECTED_SETTINGS
      {
              "commandToExecute": "${var.cse_protected_settings}"
      }
  PROTECTED_SETTINGS


  tags = {
    environment = var.farm_environment_tag_value
  }
}

Error:

Error: Invalid template interpolation value
│
│   on modules\cse\cse_resources.tf line 11, in resource "azurerm_virtual_machine_extension" "template":
│    8:   settings = <<SETTINGS
│    9:     {
│   10:       "fileUris": [
│   11:           ${var.files}
│   12:       ]
│   13:                 }
│   14: SETTINGS
│     ├────────────────
│     │ var.files is list of string with 5 elements
│
│ Cannot include the given value in a string template: string required.

Any suggestions? I also thy to generate file list inside tf with locals



Solution 1:[1]

The fileUris setting requires that the value be in string format. Terraform's string format expects everything to be on a single line. As you have multiple files you want to pull, terraform sees the comma as an argument requiring a new line. The solution to this is using terraform's heredoc style.

To do this I make a local variable which uses Heredoc, and then I later call that variable in the settings of my extension.

This can be a variable or some other placeholder

  locals {
      fileUris = <<EOT
      [
        "${azurerm_storage_container.scripts_ct.id}/1.ps1",
        "${azurerm_storage_container.scripts_ct.id}/2.ps1",
        "${azurerm_storage_container.scripts_ct.id}/22.ldif",
        "${azurerm_storage_container.scripts_ct.id}/3.zip",
        "${azurerm_storage_container.scripts_ct.id}/5.zip"
        ]
      EOT
    } 

This part goes in your extension

    settings = <<SETTINGS
      {
          "fileUris": ${local.fileUris},
          "commandToExecute": "${var.cse_protected_settings}"
      } 
  SETTINGS

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sean Connelly