Google Cloudintermediate

GCP Cloud Armor Setup Guide: WAF, Rate Limiting, and DDoS Protection

Complete guide to setting up Google Cloud Armor for web application security. Covers WAF policies, OWASP Top 10 protection, rate limiting, adaptive protection, and DDoS mitigation for applications behind load balancers.

12 min readUpdated 2026-01-13

Cloud Armor provides web application firewall (WAF) and DDoS protection for applications running behind Google Cloud load balancers. It protects against common web attacks like SQL injection and cross-site scripting, and provides adaptive protection against application-layer DDoS attacks.

This guide covers creating security policies, implementing WAF rules, configuring rate limiting, and enabling advanced protection features. This expands on Tip 13 from our 30 Cloud Security Tips for 2026 guide on implementing web application firewalls.

Prerequisites

Before configuring Cloud Armor, ensure you have:

  • An external HTTP(S) Load Balancer (global or regional)
  • Backend services configured behind the load balancer
  • Security Admin or Compute Security Admin IAM role

Step 1: Create a Cloud Armor Security Policy

Security policies contain rules that evaluate incoming requests:

Via Google Cloud Console

    - Navigate to [Network Security > Cloud Armor](https://console.cloud.google.com/net-security/securitypolicies) - Click **Create Policy** - Configure:
    • Name: web-app-policy

    • Type: Backend security policy

    • Default rule action: Allow (or Deny for allowlist approach)

    • Click Create Policy

Via gcloud CLI

# Create a security policy
gcloud compute security-policies create web-app-policy \
  --description="Security policy for web application" \
  --project=PROJECT_ID

# Verify creation
gcloud compute security-policies describe web-app-policy --project=PROJECT_ID

Via Terraform

resource "google_compute_security_policy" "web_app_policy" {
  name        = "web-app-policy"
  description = "Security policy for web application"
  project     = var.project_id

  # Default rule - allow all traffic
  rule {
    action   = "allow"
    priority = 2147483647
    match {
      versioned_expr = "SRC_IPS_V1"
      config {
        src_ip_ranges = ["*"]
      }
    }
    description = "Default rule - allow all"
  }
}

Step 2: Add OWASP Top 10 Protection Rules

Enable preconfigured WAF rules for common attack patterns:

Via gcloud CLI

# Block SQL injection attacks
gcloud compute security-policies rules create 1000 \
  --security-policy=web-app-policy \
  --expression="evaluatePreconfiguredExpr('sqli-v33-stable')" \
  --action=deny-403 \
  --description="Block SQL injection" \
  --project=PROJECT_ID

# Block cross-site scripting (XSS) attacks
gcloud compute security-policies rules create 1100 \
  --security-policy=web-app-policy \
  --expression="evaluatePreconfiguredExpr('xss-v33-stable')" \
  --action=deny-403 \
  --description="Block XSS attacks" \
  --project=PROJECT_ID

# Block local file inclusion (LFI) attacks
gcloud compute security-policies rules create 1200 \
  --security-policy=web-app-policy \
  --expression="evaluatePreconfiguredExpr('lfi-v33-stable')" \
  --action=deny-403 \
  --description="Block LFI attacks" \
  --project=PROJECT_ID

# Block remote file inclusion (RFI) attacks
gcloud compute security-policies rules create 1300 \
  --security-policy=web-app-policy \
  --expression="evaluatePreconfiguredExpr('rfi-v33-stable')" \
  --action=deny-403 \
  --description="Block RFI attacks" \
  --project=PROJECT_ID

# Block remote code execution (RCE) attacks
gcloud compute security-policies rules create 1400 \
  --security-policy=web-app-policy \
  --expression="evaluatePreconfiguredExpr('rce-v33-stable')" \
  --action=deny-403 \
  --description="Block RCE attacks" \
  --project=PROJECT_ID

# Block protocol attacks
gcloud compute security-policies rules create 1500 \
  --security-policy=web-app-policy \
  --expression="evaluatePreconfiguredExpr('protocolattack-v33-stable')" \
  --action=deny-403 \
  --description="Block protocol attacks" \
  --project=PROJECT_ID

# Block session fixation attacks
gcloud compute security-policies rules create 1600 \
  --security-policy=web-app-policy \
  --expression="evaluatePreconfiguredExpr('sessionfixation-v33-stable')" \
  --action=deny-403 \
  --description="Block session fixation" \
  --project=PROJECT_ID

# Block scanners and probes
gcloud compute security-policies rules create 1700 \
  --security-policy=web-app-policy \
  --expression="evaluatePreconfiguredExpr('scannerdetection-v33-stable')" \
  --action=deny-403 \
  --description="Block scanners and probes" \
  --project=PROJECT_ID

Via Terraform

resource "google_compute_security_policy" "web_app_policy" {
  name        = "web-app-policy"
  description = "WAF policy with OWASP protections"
  project     = var.project_id

  # SQL injection protection
  rule {
    action   = "deny(403)"
    priority = 1000
    match {
      expr {
        expression = "evaluatePreconfiguredExpr('sqli-v33-stable')"
      }
    }
    description = "Block SQL injection"
  }

  # XSS protection
  rule {
    action   = "deny(403)"
    priority = 1100
    match {
      expr {
        expression = "evaluatePreconfiguredExpr('xss-v33-stable')"
      }
    }
    description = "Block XSS attacks"
  }

  # LFI protection
  rule {
    action   = "deny(403)"
    priority = 1200
    match {
      expr {
        expression = "evaluatePreconfiguredExpr('lfi-v33-stable')"
      }
    }
    description = "Block LFI attacks"
  }

  # RFI protection
  rule {
    action   = "deny(403)"
    priority = 1300
    match {
      expr {
        expression = "evaluatePreconfiguredExpr('rfi-v33-stable')"
      }
    }
    description = "Block RFI attacks"
  }

  # RCE protection
  rule {
    action   = "deny(403)"
    priority = 1400
    match {
      expr {
        expression = "evaluatePreconfiguredExpr('rce-v33-stable')"
      }
    }
    description = "Block RCE attacks"
  }

  # Default allow
  rule {
    action   = "allow"
    priority = 2147483647
    match {
      versioned_expr = "SRC_IPS_V1"
      config {
        src_ip_ranges = ["*"]
      }
    }
    description = "Default rule"
  }
}

Step 3: Configure Rate Limiting

Protect against DDoS and brute force attacks with rate limiting:

Via gcloud CLI

# Rate limit by IP address (100 requests per minute)
gcloud compute security-policies rules create 900 \
  --security-policy=web-app-policy \
  --expression="true" \
  --action=rate-based-ban \
  --rate-limit-threshold-count=100 \
  --rate-limit-threshold-interval-sec=60 \
  --ban-duration-sec=600 \
  --conform-action=allow \
  --exceed-action=deny-429 \
  --enforce-on-key=IP \
  --description="Rate limit by IP" \
  --project=PROJECT_ID

# Rate limit login endpoint more strictly
gcloud compute security-policies rules create 800 \
  --security-policy=web-app-policy \
  --expression="request.path.matches('/login') || request.path.matches('/api/auth')" \
  --action=rate-based-ban \
  --rate-limit-threshold-count=10 \
  --rate-limit-threshold-interval-sec=60 \
  --ban-duration-sec=3600 \
  --conform-action=allow \
  --exceed-action=deny-429 \
  --enforce-on-key=IP \
  --description="Strict rate limit on login endpoints" \
  --project=PROJECT_ID

Via Terraform

resource "google_compute_security_policy" "web_app_policy" {
  name = "web-app-policy"

  # Global rate limiting
  rule {
    action   = "rate_based_ban"
    priority = 900
    match {
      versioned_expr = "SRC_IPS_V1"
      config {
        src_ip_ranges = ["*"]
      }
    }
    rate_limit_options {
      conform_action = "allow"
      exceed_action  = "deny(429)"
      enforce_on_key = "IP"

      rate_limit_threshold {
        count        = 100
        interval_sec = 60
      }

      ban_duration_sec = 600
    }
    description = "Rate limit by IP"
  }

  # Stricter rate limiting on auth endpoints
  rule {
    action   = "rate_based_ban"
    priority = 800
    match {
      expr {
        expression = "request.path.matches('/login') || request.path.matches('/api/auth')"
      }
    }
    rate_limit_options {
      conform_action = "allow"
      exceed_action  = "deny(429)"
      enforce_on_key = "IP"

      rate_limit_threshold {
        count        = 10
        interval_sec = 60
      }

      ban_duration_sec = 3600
    }
    description = "Strict rate limit on auth endpoints"
  }
}

Step 4: Enable Adaptive Protection

Adaptive Protection uses machine learning to detect and mitigate L7 DDoS attacks:

Via gcloud CLI

# Enable adaptive protection
gcloud compute security-policies update web-app-policy \
  --enable-layer7-ddos-defense \
  --layer7-ddos-defense-rule-visibility=STANDARD \
  --project=PROJECT_ID

Via Console

    - Navigate to your security policy - Click **Edit** - Under **Adaptive Protection**, toggle **Enable** - Set rule visibility to **Standard** or **Premium** - Click **Update**

Via Terraform

resource "google_compute_security_policy" "web_app_policy" {
  name = "web-app-policy"

  adaptive_protection_config {
    layer_7_ddos_defense_config {
      enable          = true
      rule_visibility = "STANDARD"
    }
  }
}

Step 5: Add Geographic Restrictions

Block or allow traffic based on geographic location:

Via gcloud CLI

# Block traffic from specific countries
gcloud compute security-policies rules create 500 \
  --security-policy=web-app-policy \
  --expression="origin.region_code == 'CN' || origin.region_code == 'RU' || origin.region_code == 'KP'" \
  --action=deny-403 \
  --description="Block traffic from high-risk countries" \
  --project=PROJECT_ID

# Allow only specific countries (allowlist approach)
gcloud compute security-policies rules create 600 \
  --security-policy=web-app-policy \
  --expression="!(origin.region_code == 'US' || origin.region_code == 'CA' || origin.region_code == 'GB')" \
  --action=deny-403 \
  --description="Allow only US, Canada, UK" \
  --project=PROJECT_ID

Step 6: Configure Bot Management (reCAPTCHA Enterprise)

Integrate reCAPTCHA Enterprise for bot detection:

Via gcloud CLI

# Add reCAPTCHA action token rule
gcloud compute security-policies rules create 700 \
  --security-policy=web-app-policy \
  --expression="request.path.matches('/api/submit') && token.recaptcha_action.score < 0.5" \
  --action=deny-403 \
  --description="Block low-score reCAPTCHA requests" \
  --project=PROJECT_ID

Step 7: Attach Policy to Backend Service

Apply the security policy to your load balancer backend:

Via gcloud CLI

# Attach to backend service
gcloud compute backend-services update my-backend-service \
  --security-policy=web-app-policy \
  --global \
  --project=PROJECT_ID

Via Console

    - Navigate to [Load Balancing](https://console.cloud.google.com/net-services/loadbalancing) - Click on your load balancer - Click **Edit** - Select the backend service - Under **Security**, select your Cloud Armor policy - Click **Update**

Via Terraform

resource "google_compute_backend_service" "web_backend" {
  name                  = "web-backend-service"
  protocol              = "HTTP"
  timeout_sec           = 30
  load_balancing_scheme = "EXTERNAL"
  security_policy       = google_compute_security_policy.web_app_policy.self_link

  backend {
    group = google_compute_instance_group_manager.web_group.instance_group
  }

  health_checks = [google_compute_health_check.web_health.id]
}

Step 8: Monitor and Review Logs

Set up logging and monitoring for Cloud Armor events:

View Logs in Cloud Logging

# View Cloud Armor logs
gcloud logging read "resource.type=http_load_balancer AND jsonPayload.enforcedSecurityPolicy.name=web-app-policy" \
  --limit=50 \
  --project=PROJECT_ID

Create Log-Based Metrics

    - Navigate to [Logging > Log-based metrics](https://console.cloud.google.com/logs/metrics) - Click **Create Metric** - Configure:
    • Metric type: Counter

    • Name: cloud_armor_blocked_requests

    • Filter: jsonPayload.enforcedSecurityPolicy.outcome="DENY"

    • Click Create Metric

Create Alerting Policy

    - Navigate to [Monitoring > Alerting](https://console.cloud.google.com/monitoring/alerting) - Click **Create Policy** - Use the log-based metric as condition - Set threshold (e.g., >1000 blocked requests in 5 minutes) - Configure notification channels

Best Practices Summary

  • Enable OWASP rules first - Start with preconfigured rules for baseline protection
  • Use preview mode for testing - Test rules before enforcing to avoid blocking legitimate traffic
  • Implement layered rate limiting - Global limits plus stricter limits on sensitive endpoints
  • Enable Adaptive Protection - ML-based detection for L7 DDoS attacks
  • Monitor blocked requests - Regular review of what's being blocked
  • Tune rules over time - Adjust thresholds based on traffic patterns
  • Combine with VPC firewalls - Defense in depth at multiple layers

Need help implementing Cloud Armor policies for your applications? Contact InventiveHQ for expert guidance on web application security and DDoS protection.

Frequently Asked Questions

Find answers to common questions

Cloud Armor is a web application firewall (WAF) and DDoS protection service that operates at Layer 7 (application layer), inspecting HTTP/HTTPS traffic for malicious patterns like SQL injection and XSS. VPC firewall rules operate at Layer 3/4 (network layer), controlling traffic based on IP addresses, ports, and protocols. Cloud Armor is applied to HTTP(S) Load Balancers while firewall rules apply to VMs and other compute resources. Use both for defense in depth.

Expert GCP Management

From architecture design to managed operations, we handle your Google Cloud infrastructure.