List Azure VM custom extensions with Terraform

84 Views Asked by At

I need to install a custom execution script to Azure VM through terraform. The challenge though is we can only have one (custom)extension. So I need to delete any existing extensions before I add a new one. To delete an extension, I should know the name of the extension. Below is the code to delete it (if I know the name) and this works fine. But this approach fails, if the custom extension does not exist. Question is, how do I query and find if the extension exists? One approach is to use “null_resource”. I’d like to keep that as my last choice. Wondering if there are any other ways to list them, especially the custom one's?

resource "azapi_resource_action" "delete_vm_custom_extension" {
  provider             = azapi
  for_each = local.vm_extensions
  type        = Microsoft.Compute/virtualMachines/extensions@2023-03-01
  resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}/resourceGroups/${var.data_factory.resource_group_name}/providers/Microsoft.Compute/virtualMachines/${each.value.vm}/extensions/${each.value.custom_extension}"
  method      = "DELETE"
  response_export_values = ["*"]
}

It'd be nice if I can achieve the same with azapi methods

1

There are 1 best solutions below

0
On

I need to install a custom execution script to Azure VM through terraform,The challenge though is we can only have one (custom)extension. So I need to delete any existing extensions before I add a new one. To delete an extension.

As there is no direct way to check the existing extensions before creating the new one on Azure VM with conditions such as wanting to delete any extensions found and install a new one if not found, all these conditions are not possible via Terraform without using a null resource.

PowerShell script:

The PowerShell script will first list all extensions. If extensions are found, it will iterate through them, delete each extension one by one using Remove-AzVMExtension, and install a new extension on the Azure VM.

script.ps1

    # Specify VM details
    $resourceGroupName = "testvk-rg"
    $vmName = "testvmvkserver"
    $extenname = "IaaSAntimalware"
    
    # Get the VM
    $vm = Get-AzVM -ResourceGroupName $resourceGroupName -Name $vmName
    
    # Delete all extensions
    if ($vm.Extensions.Count -gt 0) {
        Write-Output "Deleting extensions on VM '$vmName':"
        $vm.Extensions | ForEach-Object {
            $extensionName = $_.Name
            Write-Output "Deleting extension: $extensionName"
            Remove-AzVMExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $extensionName -Force
        }
    } else {
        Write-Output "No extensions found on VM '$vmName'."
    }
    Write-Output "Installing a new extension on VM '$vmName':"
    
    $SettingsString = "{ ""AntimalwareEnabled"": true }"
    Set-AzVMExtension -ResourceGroupName $resourceGroupName -Location "East US" -VMName $vmName -Name $extenname  -Publisher "Microsoft.Azure.Security" -Type "IaaSAntimalware" -TypeHandlerVersion "1.3" -SettingString $SettingsString
    Write-Output "Installed extension named: '$extenname' on VM '$vmName'"

Terraform code:

Note: Make sure to place both the script.ps1 and the Terraform file in the same directory.

    provider "azurerm" {
          features {}
        }
        resource "null_resource" "execute_powershell" {
          provisioner "local-exec" {
            command = <<-EOT
              powershell -ExecutionPolicy Bypass -File ${path.module}/script.ps1
            EOT
          }
        }

terraform apply

enter image description here

Portal result

enter image description here