azureterraformterraform-provider-azure

How to correctly write the settings-block azurerm_virtual_machine_extension?


Background: The Virtual Machine Extension "AzureMonitorLinuxAgent" shall be used by a VM hosted in Azure. To set up the infrastructure (and the VM), a terraform-template is used. The fundamental parameters are set (like name, virtual_machine_id and so on) for that VM-resource and also the settings-block is defined. Also the extension is added to the VM.

Expected results: We expected that the extension is set to "Plugin enabled" compared to an extension which was installed via the portal.

Current results: The state of the extension remains in state "Enable succeeded" (under Settings->Extensions+Applications inside of the Virtual machine in Azure Portal), but should be "Plugin enabled", and also no connection to the LogAnalyticsWorkspace is made. Further no data is received there from the machine. Now the question is, wether the settings-block of the extension needs further or less informations? How to correctly formulate the settings-block, which is later passed to the extension (see example code below)?

Template-code of the resource:

resource "azurerm_virtual_machine_extension" "monitor_agent" {
  name                       = "AzureMonitorLinuxAgent"
  virtual_machine_id         = azurerm_linux_virtual_machine.monitorsimple.id
  publisher                  = "Microsoft.Azure.Monitor"
  type                       = "AzureMonitorLinuxAgent"
  type_handler_version       = "1.33"
  auto_upgrade_minor_version = false
  settings = jsonencode({
    azureMonitorConfiguration = {
      workspaceId               = azurerm_log_analytics_workspace.monitorsimple.id
      azureResourceId           = azurerm_linux_virtual_machine.monitorsimple.id
      stopOnMultipleConnections = false
      authentication = {
        managedIdentity = {
          identifier-name  = "mi_res_id"
          identifier-value = azurerm_user_assigned_identity.monitorsimple.id
        }
      }
    }
  })
  
  protected_settings = jsonencode({
    "workspaceKey" = azurerm_log_analytics_workspace.monitorsimple.primary_shared_key
  })
}

What we further tried:


Solution

  • We now find a solution, so to say, we found a structure of template which works for us and connects the VM to the LogAnalyticsWorkspace. One keypoint was to completely remove the settings- and protected_settings-block within the resource "azurerm_virtual_machine_extension" and further use a "azurerm_user_assigned_identity" for all related resources in the whole template.

    Here is a complete working example (tested some minutes ago) which collects syslog data of a vm, stores it to LogAnalyticsWorkspace and exports it to an EventHub for further usage:

    terraform {
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~> 4.26.0"
        }
      }
    }
    
    provider "azurerm" {
      features {}
      subscription_id = ""
    }
    
    #Remote-State configuration
    terraform {
      backend "azurerm" {
        resource_group_name  = "MonitoringTest2StateStore"
        storage_account_name = "montststatestore2"
        container_name       = "opentofustate"
        key                  = "tofu.tfstate"
      }
    }
    
    resource "azurerm_resource_group" "monitorsimple" {
      name     = "monitorsimple"
      location = "Germany West Central"
    }
    
    resource "azurerm_virtual_network" "monitorsimple" {
      name                = "monitorsimple-vnet"
      address_space       = ["10.0.0.0/16"]
      location            = azurerm_resource_group.monitorsimple.location
      resource_group_name = azurerm_resource_group.monitorsimple.name
    }
    
    resource "azurerm_subnet" "monitorsimple" {
      name                 = "monitorsimple-subnet"
      resource_group_name  = azurerm_resource_group.monitorsimple.name
      virtual_network_name = azurerm_virtual_network.monitorsimple.name
      address_prefixes     = ["10.0.1.0/24"]
    }
    
    resource "azurerm_network_interface" "monitorsimple" {
      name                = "monitorsimple-nic"
      location            = azurerm_resource_group.monitorsimple.location
      resource_group_name = azurerm_resource_group.monitorsimple.name
    
      ip_configuration {
        name                          = "monitorsimple-ip-config"
        subnet_id                     = azurerm_subnet.monitorsimple.id
        private_ip_address_allocation = "Dynamic"
      }
    }
    
    resource "azurerm_linux_virtual_machine" "monitorsimple" {
      name                            = "monitorsimple-vm"
      resource_group_name             = azurerm_resource_group.monitorsimple.name
      location                        = azurerm_resource_group.monitorsimple.location
      size                            = "Standard_DS1_v2"
      disable_password_authentication = false
      admin_username                  = "adminuser"
      admin_password                  = " :) "
      network_interface_ids           = [azurerm_network_interface.monitorsimple.id]
      allow_extension_operations      = true
      provision_vm_agent              = true
    
      boot_diagnostics {}
    
      os_disk {
        caching              = "ReadWrite"
        storage_account_type = "Standard_LRS"
      }
    
      source_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "18.04-LTS"
        version   = "latest"
      }
    
      identity {
        type         = "UserAssigned"
        identity_ids = [azurerm_user_assigned_identity.monitorsimple.id]
      }
    }
    
    resource "azurerm_log_analytics_workspace" "monitorsimple" {
      name                = "monitorsimple-law"
      location            = azurerm_resource_group.monitorsimple.location
      resource_group_name = azurerm_resource_group.monitorsimple.name
      sku                 = "PerGB2018"
      retention_in_days   = 30
      identity {
        type         = "UserAssigned"
        identity_ids = [azurerm_user_assigned_identity.monitorsimple.id]
      }
    }
    
    resource "azurerm_log_analytics_solution" "monitorsimple" {
      solution_name         = "VMInsights"
      resource_group_name   = azurerm_resource_group.monitorsimple.name
      location              = azurerm_resource_group.monitorsimple.location
      workspace_resource_id = azurerm_log_analytics_workspace.monitorsimple.id
      workspace_name        = azurerm_log_analytics_workspace.monitorsimple.name
      plan {
        publisher = "Microsoft"
        product   = "OMSGallery/VMInsights"
      }
    }
    
    resource "azurerm_eventhub_namespace" "monitorsimple" {
      name                = "monitorsimpleehns"
      location            = azurerm_resource_group.monitorsimple.location
      resource_group_name = azurerm_resource_group.monitorsimple.name
      sku                 = "Standard"
      capacity            = 1
    }
    
    resource "azurerm_eventhub" "monitorsimple" {
      name              = "monitorsimpleeh"
      namespace_id      = azurerm_eventhub_namespace.monitorsimple.id
      partition_count   = 2
      message_retention = 1
    }
    
    resource "azurerm_monitor_data_collection_rule" "monitorsimple" {
      name                = "monitorsimpledcr"
      location            = azurerm_resource_group.monitorsimple.location
      resource_group_name = azurerm_resource_group.monitorsimple.name
      kind                = "Linux"
      description         = "DCR for processing Linux VM syslog"
      tags = {
        creator = "juri"
      }
      depends_on = [
        azurerm_log_analytics_solution.monitorsimple
      ]
    
      identity {
        type         = "UserAssigned"
        identity_ids = [azurerm_user_assigned_identity.monitorsimple.id]
      }
    
      destinations {
        log_analytics {
          workspace_resource_id = azurerm_log_analytics_workspace.monitorsimple.id
          name                  = "destination-laws"
        }
      }
    
      data_flow {
        streams       = ["Microsoft-Syslog"]
        destinations  = ["destination-laws"]
        transform_kql = "source"
        output_stream = "Microsoft-Syslog"
      }
    
      data_sources {
        syslog {
          facility_names = ["alert", "audit", "auth", "authpriv", "clock", "cron", "daemon", "ftp", "kern", "local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7", "lpr", "mail", "news", "nopri", "ntp", "syslog", "user", "uucp"]
          log_levels     = ["Debug", "Info", "Notice", "Warning", "Error", "Critical", "Alert", "Emergency"]
          name           = "sysLogsDataSource-1744703423"
          streams        = ["Microsoft-Syslog"]
        }
      }
    }
    
    resource "azurerm_monitor_data_collection_rule_association" "monitorsimple" {
      name                    = "monitorsimpledcra"
      target_resource_id      = azurerm_linux_virtual_machine.monitorsimple.id
      data_collection_rule_id = azurerm_monitor_data_collection_rule.monitorsimple.id
      description             = "assoc between vm and dcr"
    }
    
    resource "azurerm_user_assigned_identity" "monitorsimple" {
      location            = azurerm_resource_group.monitorsimple.location
      name                = "monitorsimpleusid"
      resource_group_name = azurerm_resource_group.monitorsimple.name
    }
    
    resource "azurerm_log_analytics_data_export_rule" "monitorsimple" {
      name                    = "monitorsimplelaexportrule"
      resource_group_name     = azurerm_resource_group.monitorsimple.name
      workspace_resource_id   = azurerm_log_analytics_workspace.monitorsimple.id
      destination_resource_id = azurerm_eventhub.monitorsimple.id
      table_names             = ["HealthStateChangeEvent", "Heartbeat", "Alert", "Syslog"]
      enabled                 = true
    }
    
    resource "azurerm_virtual_machine_extension" "monitor_agent" {
      name                       = "AzureMonitorLinuxAgent"
      virtual_machine_id         = azurerm_linux_virtual_machine.monitorsimple.id
      publisher                  = "Microsoft.Azure.Monitor"
      type                       = "AzureMonitorLinuxAgent"
      type_handler_version       = "1.33"
      auto_upgrade_minor_version = false
    }
    

    Source which may be of interest regarding the original question:

    https://github.com/Azure/azure-linux-extensions/tree/master/AzureMonitorAgent

    Question can be closed, but feel free to post improvments for the template by using comment function here.