Managing Azure DDoS Protection with Terraform

Learn how to set up and manage Azure DDoS Protection using Terraform, including protection plans and monitoring

Managing Azure DDoS Protection with Terraform

Azure DDoS Protection provides enhanced DDoS mitigation capabilities to protect your applications from DDoS attacks. This guide demonstrates how to set up and manage DDoS Protection using Terraform.

Video Tutorial

Learn more about managing Azure DDoS Protection 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 DDoS and security concepts

Project Structure

terraform-azure-ddos/
├── main.tf
├── variables.tf
├── outputs.tf
├── modules/
│   └── ddos/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
└── policies/
    └── protection.json

DDoS Protection Configuration

Create modules/ddos/main.tf:

# DDoS Protection Plan
resource "azurerm_network_ddos_protection_plan" "main" {
  name                = "${var.project_name}-ddos"
  location            = var.location
  resource_group_name = var.resource_group_name

  tags = var.tags
}

# Virtual Network with DDoS Protection
resource "azurerm_virtual_network" "main" {
  name                = "${var.project_name}-vnet"
  location            = var.location
  resource_group_name = var.resource_group_name
  address_space       = ["10.0.0.0/16"]

  ddos_protection_plan {
    id     = azurerm_network_ddos_protection_plan.main.id
    enable = true
  }

  tags = var.tags
}

# Public IP with DDoS Protection
resource "azurerm_public_ip" "main" {
  name                = "${var.project_name}-pip"
  location            = var.location
  resource_group_name = var.resource_group_name
  allocation_method   = "Static"
  sku                 = "Standard"
  zones               = ["1", "2", "3"]

  ddos_protection_mode = "VirtualNetworkInherited"
  
  tags = var.tags
}

# Application Gateway with DDoS Protection
resource "azurerm_application_gateway" "main" {
  name                = "${var.project_name}-appgw"
  location            = var.location
  resource_group_name = var.resource_group_name
  enable_http2        = true

  sku {
    name     = "WAF_v2"
    tier     = "WAF_v2"
    capacity = 2
  }

  gateway_ip_configuration {
    name      = "gateway-ip-configuration"
    subnet_id = azurerm_subnet.frontend.id
  }

  frontend_port {
    name = "http"
    port = 80
  }

  frontend_port {
    name = "https"
    port = 443
  }

  frontend_ip_configuration {
    name                 = "frontend"
    public_ip_address_id = azurerm_public_ip.main.id
  }

  backend_address_pool {
    name = "backend"
  }

  backend_http_settings {
    name                  = "http"
    cookie_based_affinity = "Disabled"
    port                  = 80
    protocol             = "Http"
    request_timeout      = 60
  }

  http_listener {
    name                           = "http"
    frontend_ip_configuration_name = "frontend"
    frontend_port_name             = "http"
    protocol                       = "Http"
  }

  request_routing_rule {
    name                       = "rule1"
    rule_type                  = "Basic"
    http_listener_name         = "http"
    backend_address_pool_name  = "backend"
    backend_http_settings_name = "http"
    priority                   = 1
  }

  waf_configuration {
    enabled                  = true
    firewall_mode           = "Prevention"
    rule_set_type           = "OWASP"
    rule_set_version        = "3.2"
    file_upload_limit_mb    = 100
    max_request_body_size_kb = 128
  }

  tags = var.tags
}

# Load Balancer with DDoS Protection
resource "azurerm_lb" "main" {
  name                = "${var.project_name}-lb"
  location            = var.location
  resource_group_name = var.resource_group_name
  sku                 = "Standard"

  frontend_ip_configuration {
    name                 = "frontend"
    public_ip_address_id = azurerm_public_ip.main.id
  }

  tags = var.tags
}

# Network Security Group
resource "azurerm_network_security_group" "main" {
  name                = "${var.project_name}-nsg"
  location            = var.location
  resource_group_name = var.resource_group_name

  security_rule {
    name                       = "AllowHTTPS"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "443"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }

  security_rule {
    name                       = "DenyAll"
    priority                   = 4096
    direction                  = "Inbound"
    access                     = "Deny"
    protocol                   = "*"
    source_port_range          = "*"
    destination_port_range     = "*"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }

  tags = var.tags
}

## Monitoring Configuration

1. **Diagnostic Settings**
```hcl
resource "azurerm_monitor_diagnostic_setting" "ddos" {
  name                       = "${var.project_name}-diag"
  target_resource_id        = azurerm_network_ddos_protection_plan.main.id
  log_analytics_workspace_id = var.log_analytics_workspace_id

  metric {
    category = "AllMetrics"
    enabled  = true

    retention_policy {
      enabled = true
      days    = 30
    }
  }
}

# DDoS Attack Alerts
resource "azurerm_monitor_metric_alert" "ddos_inbound" {
  name                = "${var.project_name}-ddos-inbound-alert"
  resource_group_name = var.resource_group_name
  scopes              = [azurerm_public_ip.main.id]
  description         = "Alert when inbound traffic exceeds threshold"

  criteria {
    metric_namespace = "Microsoft.Network/publicIPAddresses"
    metric_name      = "IfUnderDDoSAttack"
    aggregation      = "Maximum"
    operator         = "GreaterThan"
    threshold        = 0
  }

  action {
    action_group_id = var.action_group_id
  }
}

resource "azurerm_monitor_metric_alert" "ddos_dropped" {
  name                = "${var.project_name}-ddos-dropped-alert"
  resource_group_name = var.resource_group_name
  scopes              = [azurerm_public_ip.main.id]
  description         = "Alert when packets are dropped due to DDoS"

  criteria {
    metric_namespace = "Microsoft.Network/publicIPAddresses"
    metric_name      = "DDoSMitigationPacketsDropped"
    aggregation      = "Total"
    operator         = "GreaterThan"
    threshold        = 1000
  }

  action {
    action_group_id = var.action_group_id
  }
}

Flow Logs Configuration

  1. Network Watcher and Flow Logs
resource "azurerm_network_watcher" "main" {
  name                = "${var.project_name}-nw"
  location            = var.location
  resource_group_name = var.resource_group_name

  tags = var.tags
}

resource "azurerm_storage_account" "flowlogs" {
  name                     = "${var.project_name}flowlogs"
  resource_group_name      = var.resource_group_name
  location                 = var.location
  account_tier             = "Standard"
  account_replication_type = "LRS"

  tags = var.tags
}

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 = azurerm_network_security_group.main.id
  storage_account_id        = azurerm_storage_account.flowlogs.id
  enabled                   = true

  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
  }
}

Best Practices

  1. Protection Strategy

    • Enable on all public IPs
    • Configure alerts
    • Monitor traffic
    • Review policies
  2. Security

    • Use Standard SKU
    • Enable logging
    • Monitor attacks
    • Configure NSGs
  3. High Availability

    • Use zones
    • Configure failover
    • Monitor health
    • Implement backup
  4. Cost Optimization

    • Monitor usage
    • Review policies
    • Optimize alerts
    • Track metrics

Advanced Features

  1. Custom Policies
resource "azurerm_policy_definition" "ddos" {
  name                = "${var.project_name}-ddos-policy"
  policy_type         = "Custom"
  mode                = "All"
  display_name        = "Require DDoS Protection"

  metadata = jsonencode({
    version  = "1.0.0"
    category = "Network"
  })

  policy_rule = jsonencode({
    if = {
      allOf = [
        {
          field  = "type"
          equals = "Microsoft.Network/virtualNetworks"
        }
      ]
    }
    then = {
      effect = "deny"
      details = {
        type = "Microsoft.Network/virtualNetworks"
        existenceCondition = {
          allOf = [
            {
              field  = "Microsoft.Network/virtualNetworks/enableDdosProtection"
              equals = true
            }
          ]
        }
      }
    }
  })
}

Conclusion

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

  • DDoS mitigation
  • Traffic monitoring
  • Attack prevention
  • Security policies

Remember to:

  • Monitor attacks
  • Review policies
  • Update configurations
  • Maintain protection