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
- 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
-
Protection Strategy
- Enable on all public IPs
- Configure alerts
- Monitor traffic
- Review policies
-
Security
- Use Standard SKU
- Enable logging
- Monitor attacks
- Configure NSGs
-
High Availability
- Use zones
- Configure failover
- Monitor health
- Implement backup
-
Cost Optimization
- Monitor usage
- Review policies
- Optimize alerts
- Track metrics
Advanced Features
- 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