0

I need to deploy azure custom script extension.My script is powershell i want to use terraform variable in powershell script. my script works perfectly when i use null resource but i can sent value in azure custom script extension.

my terraform script is below

resource "azurerm_virtual_machine_extension" "example_extension" {
  name                 = "exampleExtension"
  virtual_machine_id   = azurerm_virtual_machine.example_vm.id
  publisher            = "Microsoft.Compute"
  type                 = "CustomScriptExtension"
  type_handler_version = "1.10"

  settings = <<SETTINGS
    {
      "commandToExecute": "powershell -command \"[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${base64encode(file("testing.ps1"))}')) | Out-File -filepath testing.ps1\" && powershell -ExecutionPolicy Unrestricted -File testing.ps1 -example_variable '${var.example_variable}'"
     
    }
SETTINGS
}

Powershell script

Param(
    [Parameter(Mandatory=$true)]
    [string]$example_variable
)

Write-Host "The value of example_variable is: $example_variable"

Getting error on extension

[
    {
        "code": "ComponentStatus/StdOut/succeeded",
        "level": "Info",
        "displayStatus": "Provisioning succeeded",
        "message": "The value of example_variable is: \r\n\r\n\r\n    Directory: C:\\Packages\\Plugins\\Microsoft.Compute.CustomScriptExtension\\1.10.15\\Downloads\\0\r\n\r\n\r\nMode                LastWriteTime         Length Name                                                                  \r\n----                -------------         ------ ----                                                                  \r\n-a----         5/8/2023   1:10 AM              0 .txt                                                                  \r\n\r\n\r\n"
    },
    {
        "code": "ComponentStatus/StdErr/succeeded",
        "level": "Info",
        "displayStatus": "Provisioning succeeded",
        "message": "?Param : The term '?Param' is not recognized as the name of a cmdlet, function, script file, or operable program. \r\nCheck the spelling of the name, or if a path was included, verify that the path is correct and try again.\r\nAt C:\\Packages\\Plugins\\Microsoft.Compute.CustomScriptExtension\\1.10.15\\Downloads\\0\\testing.ps1:1 char:1\r\n+ ?Param(\r\n+ ~~~~~~\r\n    + CategoryInfo          : ObjectNotFound: (?Param:String) [], CommandNotFoundException\r\n    + FullyQualifiedErrorId : CommandNotFoundException\r\n \r\n"
    }
]

i am not using ?param as it is showing me. Is there any solution to deploy terraform variable in powershell script using microsoft extension.

2
  • Does this answer your question? Terraform on Azure: executing powershell script for Windows VM from local file with variables as arguments Commented May 9, 2023 at 23:07
  • I suspect your testing.ps1 file referenced in ${base64encode(file("testing.ps1"))} has a UTF8 BOM at the start of the file which is being converted into the ? in ?Param, creating an invalid script when it's saved by Out-File. Try re-saving the original testing.ps1file without a BOM and see if that works (or at least changes the error)... Commented May 10, 2023 at 9:35

2 Answers 2

0

Check if the file content after powershell execution is fetched properly .

Use

 data "template_file" "tf" {
    template = "${file("mypscript.ps1")}"
}

to fetch the powershell file.

Code:

resource "azurerm_virtual_machine" "example" {
  name                  = "kaaaacctvm"
  location              = data.azurerm_resource_group.example.location
  resource_group_name   = data.azurerm_resource_group.example.name
 ....

  storage_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "16.04-LTS"
    version   = "latest"
  }

  ...
  os_profile {
    computer_name  = "hostname"
    admin_username = "testadmin"
    admin_password = "Password1234!"
  }

  ...

}

resource "azurerm_virtual_machine_extension" "example" {
  name                 = "vmextnname"
  virtual_machine_id   = azurerm_virtual_machine.example.id
  publisher            = "Microsoft.Azure.Extensions"
  type                 = "CustomScript"
  type_handler_version = "2.0"
settings = <<SETTINGS
    {
      "commandToExecute": "powershell -command \"[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${base64encode(data.template_file.tf.rendered)}'))  | Out-File -filepath mypscript.ps1\" && powershell -ExecutionPolicy Unrestricted -File mypscript.ps1 -example_variable '${var.example_variable}'"
     
    }
SETTINGS

 
}

data "template_file" "tempfile" {
    template = "${file("mypscript.ps1")}"
}

enter image description here

Reference: Terraform azurerm_virtual_machine_extension, run local PowerShell Script using CustomScriptExtension - Stack Overflow

Sign up to request clarification or add additional context in comments.

1 Comment

I am deploying powershell script in windows server and you are deploying it in ubuntu how can ubuntu run powershell script? please check from the portal that extension is not unable to execute command
0

Here, I am storing the required files in storage account and getting the required secrets from keyvault(in my case).

# In my data.tf file
data "azurerm_key_vault" "commonkv" {
  name                = var.common_kv_name
  resource_group_name = var.common_rg_name
}

# Non-Domain admin user name
data "azurerm_key_vault_secret" "vmusername" {
  name         = "vm-admin-user-name"
  key_vault_id = data.azurerm_key_vault.commonkv.id
}

# Non-Domain admin user Password
data "azurerm_key_vault_secret" "vmuserpwd" {
  name         = "vm-admin-user-pwd"
  key_vault_id = data.azurerm_key_vault.commonkv.id
}

# In my main.tf file
resource "azurerm_virtual_machine_extension" "winvmcse" {
  name                       = "wincse"
  virtual_machine_id         = azurerm_windows_virtual_machine.winvm.id
  publisher                  = "Microsoft.Compute"
  type                       = "CustomScriptExtension"
  type_handler_version       = "1.9"
  auto_upgrade_minor_version = true
  automatic_upgrade_enabled  = false
  settings                   = <<SETTINGS
  {
  "fileUris": ["https://mystorageaccount.blob.core.windows.net/packages/file1.zip","https://mystorageaccount.blob.core.windows.net/packages/file2.ps1"],
  "commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File ./file2.ps1 ${data.azurerm_key_vault_secret.vmusername.value} ${data.azurerm_key_vault_secret.vmuserpwd.value}",
  "timestamp" : "2"
  }
SETTINGS
  timeouts {
    create = "1h30m"
    delete = "1h15m"
  }
  tags = var.tags
}

in my file2.ps1, I get those values by

$username = $args[0]
$password = $args[1]

This method works for both linux and windows, and the only change is you have to modify your execution script, according to the os. Hope this helps!

2 Comments

Yes but the password will be logged cleartext in C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension I would not recommend this!
@Skyborg - Thanks for highlighting this to me, I will verify this path for logs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.