Search code examples
terraform-provider-azurekqlazure-monitoringazure-alerts

How to create Azure Monitor - Log alerts (with custom KQL query) using Terrafrom


I have 2 Linux VM in my RG connected to Log-Analytics workspace (Refer below Hierarchy)

Scope-Dev

->Resource-Group-Dev

--->VM-Dev-1

--->VM-Dev-2

I want to create Alert Rule with below options using Terraform ;

  • Scope : All virtual machines under Resource-Group-Dev

  • Condition : Log query written in KQL (Pasted below)

  • dimensions : Computer(Result from KQL query) which i will be using it from action group.

        Pref | where TimeGenerated > ago(60m) | where (ObjectName == "Processor") | summarize AggregatedValue = avg(CounterValue) by Computer , _ResourceId | where AggregatedValue < 100 | project Computer, AggregatedValue , _ResourceId
    

Solution

  • Here i have used azurerm_monitor_scheduled_query_rules_alert_v2 and selected scope as log-analytics-workspace where my VM got connected.As a result it worked.

      provider "azurerm" {
      features {}
    }
    
    resource "azurerm_resource_group" "example" {
      name     = "Resource-Group-Dev"
      location = "West Europe"
    }
    
    resource "azurerm_log_analytics_workspace" "log_analytics_workspace" {
      name                = "log-analytics-workspace-custom"
      location            = "West Europe"
      resource_group_name = azurerm_resource_group.example.name
      sku                 = "PerGB2018"
      retention_in_days   = 30
    }
    
    resource "azurerm_monitor_scheduled_query_rules_alert_v2" "alert_v2" {
      name                = "cpu-alertv2"
      resource_group_name = azurerm_resource_group.example.name
      location            = "West Europe"
    
      evaluation_frequency = "PT5M"
      window_duration      = "PT5M"
      scopes               = [azurerm_log_analytics_workspace.log_analytics_workspace.id]
      severity             = 4
      criteria {
        query                   = <<-QUERY
            Perf
            | where TimeGenerated > ago(1h)
            | where CounterName == "% Processor Time" and InstanceName == "_Total" 
            | project TimeGenerated, Computer, CounterValue, _ResourceId
            | summarize AggregatedValue = avg(CounterValue)  by bin(TimeGenerated, 1h), Computer, _ResourceId   
          QUERY
        time_aggregation_method = "Maximum"
        threshold               = 99.0
        operator                = "LessThan"
    
        resource_id_column    = "_ResourceId"
        metric_measure_column = "AggregatedValue"
        dimension {
          name     = "Computer"
          operator = "Include"
          values   = ["*"]
        }
        failing_periods {
          minimum_failing_periods_to_trigger_alert = 1
          number_of_evaluation_periods             = 1
        }
      }
    
      auto_mitigation_enabled          = false
      workspace_alerts_storage_enabled = false
      description                      = "This is V2 custom log alert"
      display_name                     = "cpu-alertv2"
      enabled                          = true
      query_time_range_override        = "P2D" 
      skip_query_validation            = false
      action {
        action_groups =  [azurerm_monitor_action_group.delete_dsvm_action.id]
      }
      # custom_properties = {}
      tags = {
      }
    }
    
    resource "azurerm_monitor_action_group" "delete_dsvm_action" {
      name                = "delete-vm-action"
      resource_group_name = azurerm_resource_group.example.name
      short_name          = "destoy-vm"
    
      logic_app_receiver {
        name                    = "auto-deletion-logicapp"
        resource_id             = azurerm_logic_app_workflow.auto_deletion_logicapp.id
        callback_url            = azurerm_logic_app_workflow.auto_deletion_logicapp.access_endpoint
        use_common_alert_schema = true
      }
    
      email_receiver {
        name                    = "sendtoPraveen"
        email_address           = "[email protected]"
        use_common_alert_schema = true
      }
    
    }
    
    resource "azurerm_logic_app_workflow" "auto_deletion_logicapp" {
      name                = "auto-deletion-logicapp"
      location            = "East US 2"
      resource_group_name = azurerm_resource_group.example.name
    }
    
    
    variable "prefix" {
      default = "tfvmex"
    }
    resource "azurerm_virtual_network" "main" {
      name                = "${var.prefix}-network"
      address_space       = ["10.2.0.0/16"]
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
    }
    
    resource "azurerm_subnet" "internal" {
      name                 = "internal"
      resource_group_name  = azurerm_resource_group.example.name
      virtual_network_name = azurerm_virtual_network.main.name
      address_prefixes     = ["10.2.2.0/24"]
    }
    
    resource "azurerm_network_interface" "main" {
      name                = "${var.prefix}-nic"
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
    
      ip_configuration {
        name                          = "testconfiguration1"
        subnet_id                     = azurerm_subnet.internal.id
        private_ip_address_allocation = "Dynamic"
      }
    }
    
    resource "azurerm_virtual_machine" "main" {
      name                  = "VM-Dev-1"
      location              = azurerm_resource_group.example.location
      resource_group_name   = azurerm_resource_group.example.name
      network_interface_ids = [azurerm_network_interface.main.id]
      vm_size               = "Standard_DS1_v2"
    
      storage_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "16.04-LTS"
        version   = "latest"
      }
      storage_os_disk {
        name              = "myosdisk1"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Standard_LRS"
      }
      os_profile {
        computer_name  = "hostname"
        admin_username = "testadmin"
        admin_password = "Password1234!"
      }
      os_profile_linux_config {
        disable_password_authentication = false
      }
      tags = {
        environment = "dev1"
      }
    }
    
    //VM2
    
    resource "azurerm_virtual_network" "main2" {
      name                = "${var.prefix}-network2"
      address_space       = ["10.1.0.0/16"]
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
    }
    
    resource "azurerm_subnet" "internal2" {
      name                 = "internal"
      resource_group_name  = azurerm_resource_group.example.name
      virtual_network_name = azurerm_virtual_network.main2.name
      address_prefixes     = ["10.1.2.0/24"]
    }
    
    resource "azurerm_network_interface" "main2" {
      name                = "${var.prefix}-nic2"
      location            = azurerm_resource_group.example.location
      resource_group_name = azurerm_resource_group.example.name
    
      ip_configuration {
        name                          = "testconfiguration2"
        subnet_id                     = azurerm_subnet.internal2.id
        private_ip_address_allocation = "Dynamic"
      }
    }
    
    resource "azurerm_virtual_machine" "main2" {
      name                  = "VM-Dev-2"
      location              = azurerm_resource_group.example.location
      resource_group_name   = azurerm_resource_group.example.name
      network_interface_ids = [azurerm_network_interface.main2.id]
      vm_size               = "Standard_DS1_v2"
    
      storage_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "16.04-LTS"
        version   = "latest"
      }
      storage_os_disk {
        name              = "myosdisk2"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Standard_LRS"
      }
      os_profile {
        computer_name  = "hostname1"
        admin_username = "testadmin2"
        admin_password = "Password123!"
      }
      os_profile_linux_config {
        disable_password_authentication = false
      }
      tags = {
        environment = "dev2"
      }
    

    For setting : For setting complex Logic App using Terraform