Managing Azure Network Watcher with Terraform

Learn how to set up and manage Azure Network Watcher using Terraform, including flow logs, connection monitoring, and packet capture

Managing Azure Network Watcher with Terraform

Azure Network Watcher provides tools to monitor, diagnose, view metrics, and enable or disable logs for resources in an Azure virtual network. This guide demonstrates how to set up and manage Network Watcher using Terraform.

Video Tutorial

Learn more about managing Azure Network Watcher with Terraform in this comprehensive video tutorial:

Prerequisites

  • Azure CLI configured with appropriate permissions
  • Terraform installed (version 1.0.0 or later)
  • Resource group created
  • Understanding of networking concepts

Project Structure

terraform-azure-networkwatcher/
├── main.tf
├── variables.tf
├── outputs.tf
├── modules/
│   └── networkwatcher/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
└── configs/
    └── monitoring.json

Network Watcher Configuration

Create modules/networkwatcher/main.tf:

# Network Watcher
resource "azurerm_network_watcher" "main" {
  name                = "${var.project_name}-nw"
  location            = var.location
  resource_group_name = var.resource_group_name

  tags = var.tags
}

# Storage Account for Logs
resource "azurerm_storage_account" "logs" {
  name                     = "${var.project_name}logs"
  resource_group_name      = var.resource_group_name
  location                 = var.location
  account_tier             = "Standard"
  account_replication_type = "LRS"

  tags = var.tags
}

# Flow Logs
resource "azurerm_network_watcher_flow_log" "main" {
  network_watcher_name = azurerm_network_watcher.main.name
  resource_group_name  = var.resource_group_name

  network_security_group_id = var.network_security_group_id
  storage_account_id        = azurerm_storage_account.logs.id
  enabled                   = true
  version                   = 2

  retention_policy {
    enabled = true
    days    = 30
  }

  traffic_analytics {
    enabled               = true
    workspace_id          = var.log_analytics_workspace_id
    workspace_region      = var.location
    workspace_resource_id = var.log_analytics_workspace_resource_id
    interval_in_minutes   = 10
  }
}

# Connection Monitor
resource "azurerm_network_connection_monitor" "main" {
  name                = "${var.project_name}-monitor"
  network_watcher_id  = azurerm_network_watcher.main.id
  location            = var.location

  endpoint {
    name               = "source"
    target_resource_id = var.source_vm_id
  }

  endpoint {
    name               = "destination"
    target_resource_id = var.destination_vm_id
  }

  test_configuration {
    name                      = "http"
    protocol                  = "Http"
    test_frequency_in_seconds = 30

    http_configuration {
      port = 80
      method = "Get"
      path = "/"
      valid_status_code_ranges = ["200-299"]
    }

    success_threshold {
      checks_failed_percent = 50
      round_trip_time_ms   = 100
    }
  }

  test_group {
    name                     = "example"
    destination_endpoints    = ["destination"]
    source_endpoints        = ["source"]
    test_configuration_names = ["http"]
    enabled                 = true
  }

  output_workspace_resource_ids = [var.log_analytics_workspace_resource_id]

  tags = var.tags
}

# Packet Capture
resource "azurerm_network_packet_capture" "main" {
  name                 = "${var.project_name}-capture"
  network_watcher_name = azurerm_network_watcher.main.name
  resource_group_name  = var.resource_group_name
  target_resource_id   = var.target_vm_id

  storage_location {
    storage_account_id = azurerm_storage_account.logs.id
    file_path         = "/captures/example.cap"
  }

  filter {
    local_ip_address = "10.0.0.4"
    local_port       = "443"
    protocol         = "TCP"
  }
}

# Network Security Group Flow Logs
resource "azurerm_network_watcher_flow_log_definition" "example" {
  network_watcher_name = azurerm_network_watcher.main.name
  resource_group_name  = var.resource_group_name
  name                = "${var.project_name}-flow-log"
  enabled             = true
  retention_policy {
    enabled = true
    days    = 7
  }
  storage_id                   = azurerm_storage_account.logs.id
  network_security_group_id    = var.network_security_group_id
  version                      = 2
  traffic_analytics_interval   = 10

  traffic_analytics {
    enabled               = true
    workspace_id          = var.log_analytics_workspace_id
    workspace_region      = var.location
    workspace_resource_id = var.log_analytics_workspace_resource_id
  }
}

# Network Test Configuration
resource "azurerm_network_watcher_connection_monitor_test_configuration" "tcp" {
  name                      = "${var.project_name}-tcp-test"
  connection_monitor_id     = azurerm_network_connection_monitor.main.id
  protocol                  = "Tcp"
  test_frequency_in_seconds = 30

  tcp_configuration {
    port = 443
  }

  success_threshold {
    checks_failed_percent = 50
    round_trip_time_ms   = 100
  }
}

# Network Test Group
resource "azurerm_network_watcher_connection_monitor_test_group" "tcp" {
  name                     = "${var.project_name}-tcp-group"
  connection_monitor_id     = azurerm_network_connection_monitor.main.id
  destination_endpoints    = ["destination"]
  source_endpoints        = ["source"]
  test_configuration_names = [azurerm_network_watcher_connection_monitor_test_configuration.tcp.name]
  enabled                 = true
}

Monitoring Configuration

  1. Diagnostic Settings
resource "azurerm_monitor_diagnostic_setting" "networkwatcher" {
  name                       = "${var.project_name}-diag"
  target_resource_id        = azurerm_network_watcher.main.id
  log_analytics_workspace_id = var.log_analytics_workspace_id

  metric {
    category = "AllMetrics"
    enabled  = true

    retention_policy {
      enabled = true
      days    = 30
    }
  }
}

# Network Watcher Alerts
resource "azurerm_monitor_metric_alert" "connection" {
  name                = "${var.project_name}-connection-alert"
  resource_group_name = var.resource_group_name
  scopes              = [azurerm_network_connection_monitor.main.id]
  description         = "Alert when connection monitor detects issues"

  criteria {
    metric_namespace = "Microsoft.Network/networkWatchers/connectionMonitors"
    metric_name      = "ProbesFailedPercent"
    aggregation      = "Average"
    operator         = "GreaterThan"
    threshold        = 10
  }

  action {
    action_group_id = var.action_group_id
  }
}

Advanced Features

  1. Network Performance Monitor
resource "azurerm_network_watcher_connection_monitor_endpoint" "performance" {
  name                  = "${var.project_name}-performance"
  connection_monitor_id = azurerm_network_connection_monitor.main.id

  target_resource_id = var.target_vm_id
  target_type       = "AzureVM"

  coverage_level = "Default"
}

resource "azurerm_network_watcher_connection_monitor_test_configuration" "performance" {
  name                      = "${var.project_name}-performance-test"
  connection_monitor_id     = azurerm_network_connection_monitor.main.id
  protocol                  = "Http"
  test_frequency_in_seconds = 30

  http_configuration {
    port = 80
    method = "Get"
    path = "/"
    valid_status_code_ranges = ["200-299"]
  }

  success_threshold {
    checks_failed_percent = 50
    round_trip_time_ms   = 100
  }
}

Best Practices

  1. Monitoring

    • Enable flow logs
    • Configure alerts
    • Monitor connections
    • Track metrics
  2. Performance

    • Set appropriate intervals
    • Configure thresholds
    • Monitor latency
    • Track bandwidth
  3. Security

    • Enable NSG flow logs
    • Monitor traffic
    • Track connections
    • Review logs
  4. Cost Optimization

    • Optimize logging
    • Review usage

Conclusion

You’ve learned how to set up and manage Azure Network Watcher using Terraform. This setup provides:

  • Network monitoring
  • Traffic analysis
  • Connection tracking
  • Performance metrics

Remember to:

  • Monitor connections
  • Review logs
  • Update configurations
  • Maintain monitoring