Configure GCP Region Security Policy Rules

The gcp:compute/regionSecurityPolicyRule:RegionSecurityPolicyRule resource, part of the Pulumi GCP provider, defines individual rules within a Cloud Armor regional security policy: their match conditions, actions, and priority ordering. This guide focuses on four capabilities: IP-based access control, rule priority and layering, WAF exclusions, and network-level packet matching.

Rules belong to a RegionSecurityPolicy and reference it by name. Network match rules require advanced DDoS protection and a NetworkEdgeSecurityService. The examples are intentionally small. Combine them with your own security policies and network infrastructure.

Allow traffic from specific IP ranges

Most Cloud Armor deployments start by defining rules that allow or deny traffic based on source IP addresses.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.compute.RegionSecurityPolicy("default", {
    region: "us-west2",
    name: "policyruletest",
    description: "basic region security policy",
    type: "CLOUD_ARMOR",
});
const policyRule = new gcp.compute.RegionSecurityPolicyRule("policy_rule", {
    region: "us-west2",
    securityPolicy: _default.name,
    description: "new rule",
    priority: 100,
    match: {
        versionedExpr: "SRC_IPS_V1",
        config: {
            srcIpRanges: ["10.10.0.0/16"],
        },
    },
    action: "allow",
    preview: true,
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.RegionSecurityPolicy("default",
    region="us-west2",
    name="policyruletest",
    description="basic region security policy",
    type="CLOUD_ARMOR")
policy_rule = gcp.compute.RegionSecurityPolicyRule("policy_rule",
    region="us-west2",
    security_policy=default.name,
    description="new rule",
    priority=100,
    match={
        "versioned_expr": "SRC_IPS_V1",
        "config": {
            "src_ip_ranges": ["10.10.0.0/16"],
        },
    },
    action="allow",
    preview=True)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := compute.NewRegionSecurityPolicy(ctx, "default", &compute.RegionSecurityPolicyArgs{
			Region:      pulumi.String("us-west2"),
			Name:        pulumi.String("policyruletest"),
			Description: pulumi.String("basic region security policy"),
			Type:        pulumi.String("CLOUD_ARMOR"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionSecurityPolicyRule(ctx, "policy_rule", &compute.RegionSecurityPolicyRuleArgs{
			Region:         pulumi.String("us-west2"),
			SecurityPolicy: _default.Name,
			Description:    pulumi.String("new rule"),
			Priority:       pulumi.Int(100),
			Match: &compute.RegionSecurityPolicyRuleMatchArgs{
				VersionedExpr: pulumi.String("SRC_IPS_V1"),
				Config: &compute.RegionSecurityPolicyRuleMatchConfigArgs{
					SrcIpRanges: pulumi.StringArray{
						pulumi.String("10.10.0.0/16"),
					},
				},
			},
			Action:  pulumi.String("allow"),
			Preview: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.Compute.RegionSecurityPolicy("default", new()
    {
        Region = "us-west2",
        Name = "policyruletest",
        Description = "basic region security policy",
        Type = "CLOUD_ARMOR",
    });

    var policyRule = new Gcp.Compute.RegionSecurityPolicyRule("policy_rule", new()
    {
        Region = "us-west2",
        SecurityPolicy = @default.Name,
        Description = "new rule",
        Priority = 100,
        Match = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleMatchArgs
        {
            VersionedExpr = "SRC_IPS_V1",
            Config = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleMatchConfigArgs
            {
                SrcIpRanges = new[]
                {
                    "10.10.0.0/16",
                },
            },
        },
        Action = "allow",
        Preview = true,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.RegionSecurityPolicy;
import com.pulumi.gcp.compute.RegionSecurityPolicyArgs;
import com.pulumi.gcp.compute.RegionSecurityPolicyRule;
import com.pulumi.gcp.compute.RegionSecurityPolicyRuleArgs;
import com.pulumi.gcp.compute.inputs.RegionSecurityPolicyRuleMatchArgs;
import com.pulumi.gcp.compute.inputs.RegionSecurityPolicyRuleMatchConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new RegionSecurityPolicy("default", RegionSecurityPolicyArgs.builder()
            .region("us-west2")
            .name("policyruletest")
            .description("basic region security policy")
            .type("CLOUD_ARMOR")
            .build());

        var policyRule = new RegionSecurityPolicyRule("policyRule", RegionSecurityPolicyRuleArgs.builder()
            .region("us-west2")
            .securityPolicy(default_.name())
            .description("new rule")
            .priority(100)
            .match(RegionSecurityPolicyRuleMatchArgs.builder()
                .versionedExpr("SRC_IPS_V1")
                .config(RegionSecurityPolicyRuleMatchConfigArgs.builder()
                    .srcIpRanges("10.10.0.0/16")
                    .build())
                .build())
            .action("allow")
            .preview(true)
            .build());

    }
}
resources:
  default:
    type: gcp:compute:RegionSecurityPolicy
    properties:
      region: us-west2
      name: policyruletest
      description: basic region security policy
      type: CLOUD_ARMOR
  policyRule:
    type: gcp:compute:RegionSecurityPolicyRule
    name: policy_rule
    properties:
      region: us-west2
      securityPolicy: ${default.name}
      description: new rule
      priority: 100
      match:
        versionedExpr: SRC_IPS_V1
        config:
          srcIpRanges:
            - 10.10.0.0/16
      action: allow
      preview: true

When incoming traffic matches the srcIpRanges in the match configuration, the specified action executes. The priority determines evaluation order (lower numbers first). The versionedExpr field uses “SRC_IPS_V1” for IP-based matching. Setting preview to true logs matches without enforcing the action, useful for testing rules before activation.

Layer multiple rules with priority ordering

Security policies often require multiple rules to handle different IP ranges or conditions.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.compute.RegionSecurityPolicy("default", {
    region: "us-west2",
    name: "policywithmultiplerules",
    description: "basic region security policy",
    type: "CLOUD_ARMOR",
});
const policyRuleOne = new gcp.compute.RegionSecurityPolicyRule("policy_rule_one", {
    region: "us-west2",
    securityPolicy: _default.name,
    description: "new rule one",
    priority: 100,
    match: {
        versionedExpr: "SRC_IPS_V1",
        config: {
            srcIpRanges: ["10.10.0.0/16"],
        },
    },
    action: "allow",
    preview: true,
});
const policyRuleTwo = new gcp.compute.RegionSecurityPolicyRule("policy_rule_two", {
    region: "us-west2",
    securityPolicy: _default.name,
    description: "new rule two",
    priority: 101,
    match: {
        versionedExpr: "SRC_IPS_V1",
        config: {
            srcIpRanges: [
                "192.168.0.0/16",
                "10.0.0.0/8",
            ],
        },
    },
    action: "allow",
    preview: true,
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.RegionSecurityPolicy("default",
    region="us-west2",
    name="policywithmultiplerules",
    description="basic region security policy",
    type="CLOUD_ARMOR")
policy_rule_one = gcp.compute.RegionSecurityPolicyRule("policy_rule_one",
    region="us-west2",
    security_policy=default.name,
    description="new rule one",
    priority=100,
    match={
        "versioned_expr": "SRC_IPS_V1",
        "config": {
            "src_ip_ranges": ["10.10.0.0/16"],
        },
    },
    action="allow",
    preview=True)
policy_rule_two = gcp.compute.RegionSecurityPolicyRule("policy_rule_two",
    region="us-west2",
    security_policy=default.name,
    description="new rule two",
    priority=101,
    match={
        "versioned_expr": "SRC_IPS_V1",
        "config": {
            "src_ip_ranges": [
                "192.168.0.0/16",
                "10.0.0.0/8",
            ],
        },
    },
    action="allow",
    preview=True)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := compute.NewRegionSecurityPolicy(ctx, "default", &compute.RegionSecurityPolicyArgs{
			Region:      pulumi.String("us-west2"),
			Name:        pulumi.String("policywithmultiplerules"),
			Description: pulumi.String("basic region security policy"),
			Type:        pulumi.String("CLOUD_ARMOR"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionSecurityPolicyRule(ctx, "policy_rule_one", &compute.RegionSecurityPolicyRuleArgs{
			Region:         pulumi.String("us-west2"),
			SecurityPolicy: _default.Name,
			Description:    pulumi.String("new rule one"),
			Priority:       pulumi.Int(100),
			Match: &compute.RegionSecurityPolicyRuleMatchArgs{
				VersionedExpr: pulumi.String("SRC_IPS_V1"),
				Config: &compute.RegionSecurityPolicyRuleMatchConfigArgs{
					SrcIpRanges: pulumi.StringArray{
						pulumi.String("10.10.0.0/16"),
					},
				},
			},
			Action:  pulumi.String("allow"),
			Preview: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionSecurityPolicyRule(ctx, "policy_rule_two", &compute.RegionSecurityPolicyRuleArgs{
			Region:         pulumi.String("us-west2"),
			SecurityPolicy: _default.Name,
			Description:    pulumi.String("new rule two"),
			Priority:       pulumi.Int(101),
			Match: &compute.RegionSecurityPolicyRuleMatchArgs{
				VersionedExpr: pulumi.String("SRC_IPS_V1"),
				Config: &compute.RegionSecurityPolicyRuleMatchConfigArgs{
					SrcIpRanges: pulumi.StringArray{
						pulumi.String("192.168.0.0/16"),
						pulumi.String("10.0.0.0/8"),
					},
				},
			},
			Action:  pulumi.String("allow"),
			Preview: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.Compute.RegionSecurityPolicy("default", new()
    {
        Region = "us-west2",
        Name = "policywithmultiplerules",
        Description = "basic region security policy",
        Type = "CLOUD_ARMOR",
    });

    var policyRuleOne = new Gcp.Compute.RegionSecurityPolicyRule("policy_rule_one", new()
    {
        Region = "us-west2",
        SecurityPolicy = @default.Name,
        Description = "new rule one",
        Priority = 100,
        Match = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleMatchArgs
        {
            VersionedExpr = "SRC_IPS_V1",
            Config = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleMatchConfigArgs
            {
                SrcIpRanges = new[]
                {
                    "10.10.0.0/16",
                },
            },
        },
        Action = "allow",
        Preview = true,
    });

    var policyRuleTwo = new Gcp.Compute.RegionSecurityPolicyRule("policy_rule_two", new()
    {
        Region = "us-west2",
        SecurityPolicy = @default.Name,
        Description = "new rule two",
        Priority = 101,
        Match = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleMatchArgs
        {
            VersionedExpr = "SRC_IPS_V1",
            Config = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleMatchConfigArgs
            {
                SrcIpRanges = new[]
                {
                    "192.168.0.0/16",
                    "10.0.0.0/8",
                },
            },
        },
        Action = "allow",
        Preview = true,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.RegionSecurityPolicy;
import com.pulumi.gcp.compute.RegionSecurityPolicyArgs;
import com.pulumi.gcp.compute.RegionSecurityPolicyRule;
import com.pulumi.gcp.compute.RegionSecurityPolicyRuleArgs;
import com.pulumi.gcp.compute.inputs.RegionSecurityPolicyRuleMatchArgs;
import com.pulumi.gcp.compute.inputs.RegionSecurityPolicyRuleMatchConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new RegionSecurityPolicy("default", RegionSecurityPolicyArgs.builder()
            .region("us-west2")
            .name("policywithmultiplerules")
            .description("basic region security policy")
            .type("CLOUD_ARMOR")
            .build());

        var policyRuleOne = new RegionSecurityPolicyRule("policyRuleOne", RegionSecurityPolicyRuleArgs.builder()
            .region("us-west2")
            .securityPolicy(default_.name())
            .description("new rule one")
            .priority(100)
            .match(RegionSecurityPolicyRuleMatchArgs.builder()
                .versionedExpr("SRC_IPS_V1")
                .config(RegionSecurityPolicyRuleMatchConfigArgs.builder()
                    .srcIpRanges("10.10.0.0/16")
                    .build())
                .build())
            .action("allow")
            .preview(true)
            .build());

        var policyRuleTwo = new RegionSecurityPolicyRule("policyRuleTwo", RegionSecurityPolicyRuleArgs.builder()
            .region("us-west2")
            .securityPolicy(default_.name())
            .description("new rule two")
            .priority(101)
            .match(RegionSecurityPolicyRuleMatchArgs.builder()
                .versionedExpr("SRC_IPS_V1")
                .config(RegionSecurityPolicyRuleMatchConfigArgs.builder()
                    .srcIpRanges(                    
                        "192.168.0.0/16",
                        "10.0.0.0/8")
                    .build())
                .build())
            .action("allow")
            .preview(true)
            .build());

    }
}
resources:
  default:
    type: gcp:compute:RegionSecurityPolicy
    properties:
      region: us-west2
      name: policywithmultiplerules
      description: basic region security policy
      type: CLOUD_ARMOR
  policyRuleOne:
    type: gcp:compute:RegionSecurityPolicyRule
    name: policy_rule_one
    properties:
      region: us-west2
      securityPolicy: ${default.name}
      description: new rule one
      priority: 100
      match:
        versionedExpr: SRC_IPS_V1
        config:
          srcIpRanges:
            - 10.10.0.0/16
      action: allow
      preview: true
  policyRuleTwo:
    type: gcp:compute:RegionSecurityPolicyRule
    name: policy_rule_two
    properties:
      region: us-west2
      securityPolicy: ${default.name}
      description: new rule two
      priority: 101
      match:
        versionedExpr: SRC_IPS_V1
        config:
          srcIpRanges:
            - 192.168.0.0/16
            - 10.0.0.0/8
      action: allow
      preview: true

Rules are evaluated from lowest to highest priority value. Here, priority 100 evaluates before 101. Each rule can specify different srcIpRanges and actions. This lets you build layered access control where specific ranges get different treatment.

Set a default deny rule with maximum priority

Security policies typically end with a catch-all rule that denies traffic not explicitly allowed.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.compute.RegionSecurityPolicy("default", {
    region: "us-west2",
    name: "policywithdefaultrule",
    description: "basic region security policy",
    type: "CLOUD_ARMOR",
});
const defaultRule = new gcp.compute.RegionSecurityPolicyRule("default_rule", {
    region: "us-west2",
    securityPolicy: _default.name,
    description: "new rule",
    action: "deny",
    priority: 2147483647,
    match: {
        versionedExpr: "SRC_IPS_V1",
        config: {
            srcIpRanges: ["*"],
        },
    },
});
const policyRule = new gcp.compute.RegionSecurityPolicyRule("policy_rule", {
    region: "us-west2",
    securityPolicy: _default.name,
    description: "new rule",
    priority: 100,
    match: {
        versionedExpr: "SRC_IPS_V1",
        config: {
            srcIpRanges: ["10.10.0.0/16"],
        },
    },
    action: "allow",
    preview: true,
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.RegionSecurityPolicy("default",
    region="us-west2",
    name="policywithdefaultrule",
    description="basic region security policy",
    type="CLOUD_ARMOR")
default_rule = gcp.compute.RegionSecurityPolicyRule("default_rule",
    region="us-west2",
    security_policy=default.name,
    description="new rule",
    action="deny",
    priority=2147483647,
    match={
        "versioned_expr": "SRC_IPS_V1",
        "config": {
            "src_ip_ranges": ["*"],
        },
    })
policy_rule = gcp.compute.RegionSecurityPolicyRule("policy_rule",
    region="us-west2",
    security_policy=default.name,
    description="new rule",
    priority=100,
    match={
        "versioned_expr": "SRC_IPS_V1",
        "config": {
            "src_ip_ranges": ["10.10.0.0/16"],
        },
    },
    action="allow",
    preview=True)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := compute.NewRegionSecurityPolicy(ctx, "default", &compute.RegionSecurityPolicyArgs{
			Region:      pulumi.String("us-west2"),
			Name:        pulumi.String("policywithdefaultrule"),
			Description: pulumi.String("basic region security policy"),
			Type:        pulumi.String("CLOUD_ARMOR"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionSecurityPolicyRule(ctx, "default_rule", &compute.RegionSecurityPolicyRuleArgs{
			Region:         pulumi.String("us-west2"),
			SecurityPolicy: _default.Name,
			Description:    pulumi.String("new rule"),
			Action:         pulumi.String("deny"),
			Priority:       pulumi.Int(2147483647),
			Match: &compute.RegionSecurityPolicyRuleMatchArgs{
				VersionedExpr: pulumi.String("SRC_IPS_V1"),
				Config: &compute.RegionSecurityPolicyRuleMatchConfigArgs{
					SrcIpRanges: pulumi.StringArray{
						pulumi.String("*"),
					},
				},
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionSecurityPolicyRule(ctx, "policy_rule", &compute.RegionSecurityPolicyRuleArgs{
			Region:         pulumi.String("us-west2"),
			SecurityPolicy: _default.Name,
			Description:    pulumi.String("new rule"),
			Priority:       pulumi.Int(100),
			Match: &compute.RegionSecurityPolicyRuleMatchArgs{
				VersionedExpr: pulumi.String("SRC_IPS_V1"),
				Config: &compute.RegionSecurityPolicyRuleMatchConfigArgs{
					SrcIpRanges: pulumi.StringArray{
						pulumi.String("10.10.0.0/16"),
					},
				},
			},
			Action:  pulumi.String("allow"),
			Preview: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.Compute.RegionSecurityPolicy("default", new()
    {
        Region = "us-west2",
        Name = "policywithdefaultrule",
        Description = "basic region security policy",
        Type = "CLOUD_ARMOR",
    });

    var defaultRule = new Gcp.Compute.RegionSecurityPolicyRule("default_rule", new()
    {
        Region = "us-west2",
        SecurityPolicy = @default.Name,
        Description = "new rule",
        Action = "deny",
        Priority = 2147483647,
        Match = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleMatchArgs
        {
            VersionedExpr = "SRC_IPS_V1",
            Config = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleMatchConfigArgs
            {
                SrcIpRanges = new[]
                {
                    "*",
                },
            },
        },
    });

    var policyRule = new Gcp.Compute.RegionSecurityPolicyRule("policy_rule", new()
    {
        Region = "us-west2",
        SecurityPolicy = @default.Name,
        Description = "new rule",
        Priority = 100,
        Match = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleMatchArgs
        {
            VersionedExpr = "SRC_IPS_V1",
            Config = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleMatchConfigArgs
            {
                SrcIpRanges = new[]
                {
                    "10.10.0.0/16",
                },
            },
        },
        Action = "allow",
        Preview = true,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.RegionSecurityPolicy;
import com.pulumi.gcp.compute.RegionSecurityPolicyArgs;
import com.pulumi.gcp.compute.RegionSecurityPolicyRule;
import com.pulumi.gcp.compute.RegionSecurityPolicyRuleArgs;
import com.pulumi.gcp.compute.inputs.RegionSecurityPolicyRuleMatchArgs;
import com.pulumi.gcp.compute.inputs.RegionSecurityPolicyRuleMatchConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new RegionSecurityPolicy("default", RegionSecurityPolicyArgs.builder()
            .region("us-west2")
            .name("policywithdefaultrule")
            .description("basic region security policy")
            .type("CLOUD_ARMOR")
            .build());

        var defaultRule = new RegionSecurityPolicyRule("defaultRule", RegionSecurityPolicyRuleArgs.builder()
            .region("us-west2")
            .securityPolicy(default_.name())
            .description("new rule")
            .action("deny")
            .priority(2147483647)
            .match(RegionSecurityPolicyRuleMatchArgs.builder()
                .versionedExpr("SRC_IPS_V1")
                .config(RegionSecurityPolicyRuleMatchConfigArgs.builder()
                    .srcIpRanges("*")
                    .build())
                .build())
            .build());

        var policyRule = new RegionSecurityPolicyRule("policyRule", RegionSecurityPolicyRuleArgs.builder()
            .region("us-west2")
            .securityPolicy(default_.name())
            .description("new rule")
            .priority(100)
            .match(RegionSecurityPolicyRuleMatchArgs.builder()
                .versionedExpr("SRC_IPS_V1")
                .config(RegionSecurityPolicyRuleMatchConfigArgs.builder()
                    .srcIpRanges("10.10.0.0/16")
                    .build())
                .build())
            .action("allow")
            .preview(true)
            .build());

    }
}
resources:
  default:
    type: gcp:compute:RegionSecurityPolicy
    properties:
      region: us-west2
      name: policywithdefaultrule
      description: basic region security policy
      type: CLOUD_ARMOR
  defaultRule:
    type: gcp:compute:RegionSecurityPolicyRule
    name: default_rule
    properties:
      region: us-west2
      securityPolicy: ${default.name}
      description: new rule
      action: deny
      priority: '2147483647'
      match:
        versionedExpr: SRC_IPS_V1
        config:
          srcIpRanges:
            - '*'
  policyRule:
    type: gcp:compute:RegionSecurityPolicyRule
    name: policy_rule
    properties:
      region: us-west2
      securityPolicy: ${default.name}
      description: new rule
      priority: 100
      match:
        versionedExpr: SRC_IPS_V1
        config:
          srcIpRanges:
            - 10.10.0.0/16
      action: allow
      preview: true

The maximum priority value (2147483647) ensures this rule evaluates last, after all other rules. Using “*” in srcIpRanges matches all traffic. Combined with action “deny”, this implements a default-deny posture where only explicitly allowed traffic passes through.

Exclude paths and parameters from WAF inspection

Web applications often have admin endpoints or form fields that trigger false positives in WAF rule sets.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.compute.RegionSecurityPolicy("default", {
    region: "asia-southeast1",
    name: "policyruletest",
    description: "basic region security policy",
    type: "CLOUD_ARMOR",
});
const policyRule = new gcp.compute.RegionSecurityPolicyRule("policy_rule", {
    region: "asia-southeast1",
    securityPolicy: _default.name,
    description: "new rule",
    priority: 100,
    match: {
        versionedExpr: "SRC_IPS_V1",
        config: {
            srcIpRanges: ["10.10.0.0/16"],
        },
    },
    preconfiguredWafConfig: {
        exclusions: [
            {
                requestUris: [{
                    operator: "STARTS_WITH",
                    value: "/admin",
                }],
                targetRuleSet: "rce-stable",
            },
            {
                requestQueryParams: [
                    {
                        operator: "CONTAINS",
                        value: "password",
                    },
                    {
                        operator: "STARTS_WITH",
                        value: "freeform",
                    },
                    {
                        operator: "EQUALS",
                        value: "description",
                    },
                ],
                targetRuleSet: "xss-stable",
                targetRuleIds: [
                    "owasp-crs-v030001-id941330-xss",
                    "owasp-crs-v030001-id941340-xss",
                ],
            },
        ],
    },
    action: "allow",
    preview: true,
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.RegionSecurityPolicy("default",
    region="asia-southeast1",
    name="policyruletest",
    description="basic region security policy",
    type="CLOUD_ARMOR")
policy_rule = gcp.compute.RegionSecurityPolicyRule("policy_rule",
    region="asia-southeast1",
    security_policy=default.name,
    description="new rule",
    priority=100,
    match={
        "versioned_expr": "SRC_IPS_V1",
        "config": {
            "src_ip_ranges": ["10.10.0.0/16"],
        },
    },
    preconfigured_waf_config={
        "exclusions": [
            {
                "request_uris": [{
                    "operator": "STARTS_WITH",
                    "value": "/admin",
                }],
                "target_rule_set": "rce-stable",
            },
            {
                "request_query_params": [
                    {
                        "operator": "CONTAINS",
                        "value": "password",
                    },
                    {
                        "operator": "STARTS_WITH",
                        "value": "freeform",
                    },
                    {
                        "operator": "EQUALS",
                        "value": "description",
                    },
                ],
                "target_rule_set": "xss-stable",
                "target_rule_ids": [
                    "owasp-crs-v030001-id941330-xss",
                    "owasp-crs-v030001-id941340-xss",
                ],
            },
        ],
    },
    action="allow",
    preview=True)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := compute.NewRegionSecurityPolicy(ctx, "default", &compute.RegionSecurityPolicyArgs{
			Region:      pulumi.String("asia-southeast1"),
			Name:        pulumi.String("policyruletest"),
			Description: pulumi.String("basic region security policy"),
			Type:        pulumi.String("CLOUD_ARMOR"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionSecurityPolicyRule(ctx, "policy_rule", &compute.RegionSecurityPolicyRuleArgs{
			Region:         pulumi.String("asia-southeast1"),
			SecurityPolicy: _default.Name,
			Description:    pulumi.String("new rule"),
			Priority:       pulumi.Int(100),
			Match: &compute.RegionSecurityPolicyRuleMatchArgs{
				VersionedExpr: pulumi.String("SRC_IPS_V1"),
				Config: &compute.RegionSecurityPolicyRuleMatchConfigArgs{
					SrcIpRanges: pulumi.StringArray{
						pulumi.String("10.10.0.0/16"),
					},
				},
			},
			PreconfiguredWafConfig: &compute.RegionSecurityPolicyRulePreconfiguredWafConfigArgs{
				Exclusions: compute.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionArray{
					&compute.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionArgs{
						RequestUris: compute.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestUriArray{
							&compute.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestUriArgs{
								Operator: pulumi.String("STARTS_WITH"),
								Value:    pulumi.String("/admin"),
							},
						},
						TargetRuleSet: pulumi.String("rce-stable"),
					},
					&compute.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionArgs{
						RequestQueryParams: compute.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestQueryParamArray{
							&compute.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestQueryParamArgs{
								Operator: pulumi.String("CONTAINS"),
								Value:    pulumi.String("password"),
							},
							&compute.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestQueryParamArgs{
								Operator: pulumi.String("STARTS_WITH"),
								Value:    pulumi.String("freeform"),
							},
							&compute.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestQueryParamArgs{
								Operator: pulumi.String("EQUALS"),
								Value:    pulumi.String("description"),
							},
						},
						TargetRuleSet: pulumi.String("xss-stable"),
						TargetRuleIds: pulumi.StringArray{
							pulumi.String("owasp-crs-v030001-id941330-xss"),
							pulumi.String("owasp-crs-v030001-id941340-xss"),
						},
					},
				},
			},
			Action:  pulumi.String("allow"),
			Preview: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.Compute.RegionSecurityPolicy("default", new()
    {
        Region = "asia-southeast1",
        Name = "policyruletest",
        Description = "basic region security policy",
        Type = "CLOUD_ARMOR",
    });

    var policyRule = new Gcp.Compute.RegionSecurityPolicyRule("policy_rule", new()
    {
        Region = "asia-southeast1",
        SecurityPolicy = @default.Name,
        Description = "new rule",
        Priority = 100,
        Match = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleMatchArgs
        {
            VersionedExpr = "SRC_IPS_V1",
            Config = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleMatchConfigArgs
            {
                SrcIpRanges = new[]
                {
                    "10.10.0.0/16",
                },
            },
        },
        PreconfiguredWafConfig = new Gcp.Compute.Inputs.RegionSecurityPolicyRulePreconfiguredWafConfigArgs
        {
            Exclusions = new[]
            {
                new Gcp.Compute.Inputs.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionArgs
                {
                    RequestUris = new[]
                    {
                        new Gcp.Compute.Inputs.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestUriArgs
                        {
                            Operator = "STARTS_WITH",
                            Value = "/admin",
                        },
                    },
                    TargetRuleSet = "rce-stable",
                },
                new Gcp.Compute.Inputs.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionArgs
                {
                    RequestQueryParams = new[]
                    {
                        new Gcp.Compute.Inputs.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestQueryParamArgs
                        {
                            Operator = "CONTAINS",
                            Value = "password",
                        },
                        new Gcp.Compute.Inputs.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestQueryParamArgs
                        {
                            Operator = "STARTS_WITH",
                            Value = "freeform",
                        },
                        new Gcp.Compute.Inputs.RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestQueryParamArgs
                        {
                            Operator = "EQUALS",
                            Value = "description",
                        },
                    },
                    TargetRuleSet = "xss-stable",
                    TargetRuleIds = new[]
                    {
                        "owasp-crs-v030001-id941330-xss",
                        "owasp-crs-v030001-id941340-xss",
                    },
                },
            },
        },
        Action = "allow",
        Preview = true,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.RegionSecurityPolicy;
import com.pulumi.gcp.compute.RegionSecurityPolicyArgs;
import com.pulumi.gcp.compute.RegionSecurityPolicyRule;
import com.pulumi.gcp.compute.RegionSecurityPolicyRuleArgs;
import com.pulumi.gcp.compute.inputs.RegionSecurityPolicyRuleMatchArgs;
import com.pulumi.gcp.compute.inputs.RegionSecurityPolicyRuleMatchConfigArgs;
import com.pulumi.gcp.compute.inputs.RegionSecurityPolicyRulePreconfiguredWafConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new RegionSecurityPolicy("default", RegionSecurityPolicyArgs.builder()
            .region("asia-southeast1")
            .name("policyruletest")
            .description("basic region security policy")
            .type("CLOUD_ARMOR")
            .build());

        var policyRule = new RegionSecurityPolicyRule("policyRule", RegionSecurityPolicyRuleArgs.builder()
            .region("asia-southeast1")
            .securityPolicy(default_.name())
            .description("new rule")
            .priority(100)
            .match(RegionSecurityPolicyRuleMatchArgs.builder()
                .versionedExpr("SRC_IPS_V1")
                .config(RegionSecurityPolicyRuleMatchConfigArgs.builder()
                    .srcIpRanges("10.10.0.0/16")
                    .build())
                .build())
            .preconfiguredWafConfig(RegionSecurityPolicyRulePreconfiguredWafConfigArgs.builder()
                .exclusions(                
                    RegionSecurityPolicyRulePreconfiguredWafConfigExclusionArgs.builder()
                        .requestUris(RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestUriArgs.builder()
                            .operator("STARTS_WITH")
                            .value("/admin")
                            .build())
                        .targetRuleSet("rce-stable")
                        .build(),
                    RegionSecurityPolicyRulePreconfiguredWafConfigExclusionArgs.builder()
                        .requestQueryParams(                        
                            RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestQueryParamArgs.builder()
                                .operator("CONTAINS")
                                .value("password")
                                .build(),
                            RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestQueryParamArgs.builder()
                                .operator("STARTS_WITH")
                                .value("freeform")
                                .build(),
                            RegionSecurityPolicyRulePreconfiguredWafConfigExclusionRequestQueryParamArgs.builder()
                                .operator("EQUALS")
                                .value("description")
                                .build())
                        .targetRuleSet("xss-stable")
                        .targetRuleIds(                        
                            "owasp-crs-v030001-id941330-xss",
                            "owasp-crs-v030001-id941340-xss")
                        .build())
                .build())
            .action("allow")
            .preview(true)
            .build());

    }
}
resources:
  default:
    type: gcp:compute:RegionSecurityPolicy
    properties:
      region: asia-southeast1
      name: policyruletest
      description: basic region security policy
      type: CLOUD_ARMOR
  policyRule:
    type: gcp:compute:RegionSecurityPolicyRule
    name: policy_rule
    properties:
      region: asia-southeast1
      securityPolicy: ${default.name}
      description: new rule
      priority: 100
      match:
        versionedExpr: SRC_IPS_V1
        config:
          srcIpRanges:
            - 10.10.0.0/16
      preconfiguredWafConfig:
        exclusions:
          - requestUris:
              - operator: STARTS_WITH
                value: /admin
            targetRuleSet: rce-stable
          - requestQueryParams:
              - operator: CONTAINS
                value: password
              - operator: STARTS_WITH
                value: freeform
              - operator: EQUALS
                value: description
            targetRuleSet: xss-stable
            targetRuleIds:
              - owasp-crs-v030001-id941330-xss
              - owasp-crs-v030001-id941340-xss
      action: allow
      preview: true

The preconfiguredWafConfig property defines exclusions that bypass specific WAF rules for certain request patterns. Each exclusion targets a ruleSet (like “rce-stable” or “xss-stable”) and can filter by requestUris or requestQueryParams. The operator field controls matching behavior: STARTS_WITH, CONTAINS, or EQUALS. This lets you keep WAF protection active while excluding known safe patterns.

Match packets using custom header fields

Advanced DDoS protection scenarios require matching on packet-level details beyond IP addresses.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

// First activate advanced network DDoS protection for the desired region
const policyddosprotection = new gcp.compute.RegionSecurityPolicy("policyddosprotection", {
    region: "us-west2",
    name: "policyddosprotection",
    description: "policy for activating network DDoS protection for the desired region",
    type: "CLOUD_ARMOR_NETWORK",
    ddosProtectionConfig: {
        ddosProtection: "ADVANCED_PREVIEW",
    },
});
const edgeSecService = new gcp.compute.NetworkEdgeSecurityService("edge_sec_service", {
    region: "us-west2",
    name: "edgesecservice",
    description: "linking policy to edge security service",
    securityPolicy: policyddosprotection.selfLink,
});
// Add the desired policy and custom rule.
const policynetworkmatch = new gcp.compute.RegionSecurityPolicy("policynetworkmatch", {
    region: "us-west2",
    name: "policyfornetworkmatch",
    description: "region security policy for network match",
    type: "CLOUD_ARMOR_NETWORK",
    userDefinedFields: [{
        name: "SIG1_AT_0",
        base: "TCP",
        offset: 8,
        size: 2,
        mask: "0x8F00",
    }],
}, {
    dependsOn: [edgeSecService],
});
const policyRuleNetworkMatch = new gcp.compute.RegionSecurityPolicyRule("policy_rule_network_match", {
    region: "us-west2",
    securityPolicy: policynetworkmatch.name,
    description: "custom rule for network match",
    priority: 100,
    networkMatch: {
        srcIpRanges: ["10.10.0.0/16"],
        userDefinedFields: [{
            name: "SIG1_AT_0",
            values: ["0x8F00"],
        }],
    },
    action: "allow",
    preview: true,
});
import pulumi
import pulumi_gcp as gcp

# First activate advanced network DDoS protection for the desired region
policyddosprotection = gcp.compute.RegionSecurityPolicy("policyddosprotection",
    region="us-west2",
    name="policyddosprotection",
    description="policy for activating network DDoS protection for the desired region",
    type="CLOUD_ARMOR_NETWORK",
    ddos_protection_config={
        "ddos_protection": "ADVANCED_PREVIEW",
    })
edge_sec_service = gcp.compute.NetworkEdgeSecurityService("edge_sec_service",
    region="us-west2",
    name="edgesecservice",
    description="linking policy to edge security service",
    security_policy=policyddosprotection.self_link)
# Add the desired policy and custom rule.
policynetworkmatch = gcp.compute.RegionSecurityPolicy("policynetworkmatch",
    region="us-west2",
    name="policyfornetworkmatch",
    description="region security policy for network match",
    type="CLOUD_ARMOR_NETWORK",
    user_defined_fields=[{
        "name": "SIG1_AT_0",
        "base": "TCP",
        "offset": 8,
        "size": 2,
        "mask": "0x8F00",
    }],
    opts = pulumi.ResourceOptions(depends_on=[edge_sec_service]))
policy_rule_network_match = gcp.compute.RegionSecurityPolicyRule("policy_rule_network_match",
    region="us-west2",
    security_policy=policynetworkmatch.name,
    description="custom rule for network match",
    priority=100,
    network_match={
        "src_ip_ranges": ["10.10.0.0/16"],
        "user_defined_fields": [{
            "name": "SIG1_AT_0",
            "values": ["0x8F00"],
        }],
    },
    action="allow",
    preview=True)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		// First activate advanced network DDoS protection for the desired region
		policyddosprotection, err := compute.NewRegionSecurityPolicy(ctx, "policyddosprotection", &compute.RegionSecurityPolicyArgs{
			Region:      pulumi.String("us-west2"),
			Name:        pulumi.String("policyddosprotection"),
			Description: pulumi.String("policy for activating network DDoS protection for the desired region"),
			Type:        pulumi.String("CLOUD_ARMOR_NETWORK"),
			DdosProtectionConfig: &compute.RegionSecurityPolicyDdosProtectionConfigArgs{
				DdosProtection: pulumi.String("ADVANCED_PREVIEW"),
			},
		})
		if err != nil {
			return err
		}
		edgeSecService, err := compute.NewNetworkEdgeSecurityService(ctx, "edge_sec_service", &compute.NetworkEdgeSecurityServiceArgs{
			Region:         pulumi.String("us-west2"),
			Name:           pulumi.String("edgesecservice"),
			Description:    pulumi.String("linking policy to edge security service"),
			SecurityPolicy: policyddosprotection.SelfLink,
		})
		if err != nil {
			return err
		}
		// Add the desired policy and custom rule.
		policynetworkmatch, err := compute.NewRegionSecurityPolicy(ctx, "policynetworkmatch", &compute.RegionSecurityPolicyArgs{
			Region:      pulumi.String("us-west2"),
			Name:        pulumi.String("policyfornetworkmatch"),
			Description: pulumi.String("region security policy for network match"),
			Type:        pulumi.String("CLOUD_ARMOR_NETWORK"),
			UserDefinedFields: compute.RegionSecurityPolicyUserDefinedFieldArray{
				&compute.RegionSecurityPolicyUserDefinedFieldArgs{
					Name:   pulumi.String("SIG1_AT_0"),
					Base:   pulumi.String("TCP"),
					Offset: pulumi.Int(8),
					Size:   pulumi.Int(2),
					Mask:   pulumi.String("0x8F00"),
				},
			},
		}, pulumi.DependsOn([]pulumi.Resource{
			edgeSecService,
		}))
		if err != nil {
			return err
		}
		_, err = compute.NewRegionSecurityPolicyRule(ctx, "policy_rule_network_match", &compute.RegionSecurityPolicyRuleArgs{
			Region:         pulumi.String("us-west2"),
			SecurityPolicy: policynetworkmatch.Name,
			Description:    pulumi.String("custom rule for network match"),
			Priority:       pulumi.Int(100),
			NetworkMatch: &compute.RegionSecurityPolicyRuleNetworkMatchArgs{
				SrcIpRanges: pulumi.StringArray{
					pulumi.String("10.10.0.0/16"),
				},
				UserDefinedFields: compute.RegionSecurityPolicyRuleNetworkMatchUserDefinedFieldArray{
					&compute.RegionSecurityPolicyRuleNetworkMatchUserDefinedFieldArgs{
						Name: pulumi.String("SIG1_AT_0"),
						Values: pulumi.StringArray{
							pulumi.String("0x8F00"),
						},
					},
				},
			},
			Action:  pulumi.String("allow"),
			Preview: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    // First activate advanced network DDoS protection for the desired region
    var policyddosprotection = new Gcp.Compute.RegionSecurityPolicy("policyddosprotection", new()
    {
        Region = "us-west2",
        Name = "policyddosprotection",
        Description = "policy for activating network DDoS protection for the desired region",
        Type = "CLOUD_ARMOR_NETWORK",
        DdosProtectionConfig = new Gcp.Compute.Inputs.RegionSecurityPolicyDdosProtectionConfigArgs
        {
            DdosProtection = "ADVANCED_PREVIEW",
        },
    });

    var edgeSecService = new Gcp.Compute.NetworkEdgeSecurityService("edge_sec_service", new()
    {
        Region = "us-west2",
        Name = "edgesecservice",
        Description = "linking policy to edge security service",
        SecurityPolicy = policyddosprotection.SelfLink,
    });

    // Add the desired policy and custom rule.
    var policynetworkmatch = new Gcp.Compute.RegionSecurityPolicy("policynetworkmatch", new()
    {
        Region = "us-west2",
        Name = "policyfornetworkmatch",
        Description = "region security policy for network match",
        Type = "CLOUD_ARMOR_NETWORK",
        UserDefinedFields = new[]
        {
            new Gcp.Compute.Inputs.RegionSecurityPolicyUserDefinedFieldArgs
            {
                Name = "SIG1_AT_0",
                Base = "TCP",
                Offset = 8,
                Size = 2,
                Mask = "0x8F00",
            },
        },
    }, new CustomResourceOptions
    {
        DependsOn =
        {
            edgeSecService,
        },
    });

    var policyRuleNetworkMatch = new Gcp.Compute.RegionSecurityPolicyRule("policy_rule_network_match", new()
    {
        Region = "us-west2",
        SecurityPolicy = policynetworkmatch.Name,
        Description = "custom rule for network match",
        Priority = 100,
        NetworkMatch = new Gcp.Compute.Inputs.RegionSecurityPolicyRuleNetworkMatchArgs
        {
            SrcIpRanges = new[]
            {
                "10.10.0.0/16",
            },
            UserDefinedFields = new[]
            {
                new Gcp.Compute.Inputs.RegionSecurityPolicyRuleNetworkMatchUserDefinedFieldArgs
                {
                    Name = "SIG1_AT_0",
                    Values = new[]
                    {
                        "0x8F00",
                    },
                },
            },
        },
        Action = "allow",
        Preview = true,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.RegionSecurityPolicy;
import com.pulumi.gcp.compute.RegionSecurityPolicyArgs;
import com.pulumi.gcp.compute.inputs.RegionSecurityPolicyDdosProtectionConfigArgs;
import com.pulumi.gcp.compute.NetworkEdgeSecurityService;
import com.pulumi.gcp.compute.NetworkEdgeSecurityServiceArgs;
import com.pulumi.gcp.compute.inputs.RegionSecurityPolicyUserDefinedFieldArgs;
import com.pulumi.gcp.compute.RegionSecurityPolicyRule;
import com.pulumi.gcp.compute.RegionSecurityPolicyRuleArgs;
import com.pulumi.gcp.compute.inputs.RegionSecurityPolicyRuleNetworkMatchArgs;
import com.pulumi.resources.CustomResourceOptions;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        // First activate advanced network DDoS protection for the desired region
        var policyddosprotection = new RegionSecurityPolicy("policyddosprotection", RegionSecurityPolicyArgs.builder()
            .region("us-west2")
            .name("policyddosprotection")
            .description("policy for activating network DDoS protection for the desired region")
            .type("CLOUD_ARMOR_NETWORK")
            .ddosProtectionConfig(RegionSecurityPolicyDdosProtectionConfigArgs.builder()
                .ddosProtection("ADVANCED_PREVIEW")
                .build())
            .build());

        var edgeSecService = new NetworkEdgeSecurityService("edgeSecService", NetworkEdgeSecurityServiceArgs.builder()
            .region("us-west2")
            .name("edgesecservice")
            .description("linking policy to edge security service")
            .securityPolicy(policyddosprotection.selfLink())
            .build());

        // Add the desired policy and custom rule.
        var policynetworkmatch = new RegionSecurityPolicy("policynetworkmatch", RegionSecurityPolicyArgs.builder()
            .region("us-west2")
            .name("policyfornetworkmatch")
            .description("region security policy for network match")
            .type("CLOUD_ARMOR_NETWORK")
            .userDefinedFields(RegionSecurityPolicyUserDefinedFieldArgs.builder()
                .name("SIG1_AT_0")
                .base("TCP")
                .offset(8)
                .size(2)
                .mask("0x8F00")
                .build())
            .build(), CustomResourceOptions.builder()
                .dependsOn(edgeSecService)
                .build());

        var policyRuleNetworkMatch = new RegionSecurityPolicyRule("policyRuleNetworkMatch", RegionSecurityPolicyRuleArgs.builder()
            .region("us-west2")
            .securityPolicy(policynetworkmatch.name())
            .description("custom rule for network match")
            .priority(100)
            .networkMatch(RegionSecurityPolicyRuleNetworkMatchArgs.builder()
                .srcIpRanges("10.10.0.0/16")
                .userDefinedFields(RegionSecurityPolicyRuleNetworkMatchUserDefinedFieldArgs.builder()
                    .name("SIG1_AT_0")
                    .values("0x8F00")
                    .build())
                .build())
            .action("allow")
            .preview(true)
            .build());

    }
}
resources:
  # First activate advanced network DDoS protection for the desired region
  policyddosprotection:
    type: gcp:compute:RegionSecurityPolicy
    properties:
      region: us-west2
      name: policyddosprotection
      description: policy for activating network DDoS protection for the desired region
      type: CLOUD_ARMOR_NETWORK
      ddosProtectionConfig:
        ddosProtection: ADVANCED_PREVIEW
  edgeSecService:
    type: gcp:compute:NetworkEdgeSecurityService
    name: edge_sec_service
    properties:
      region: us-west2
      name: edgesecservice
      description: linking policy to edge security service
      securityPolicy: ${policyddosprotection.selfLink}
  # Add the desired policy and custom rule.
  policynetworkmatch:
    type: gcp:compute:RegionSecurityPolicy
    properties:
      region: us-west2
      name: policyfornetworkmatch
      description: region security policy for network match
      type: CLOUD_ARMOR_NETWORK
      userDefinedFields:
        - name: SIG1_AT_0
          base: TCP
          offset: 8
          size: 2
          mask: 0x8F00
    options:
      dependsOn:
        - ${edgeSecService}
  policyRuleNetworkMatch:
    type: gcp:compute:RegionSecurityPolicyRule
    name: policy_rule_network_match
    properties:
      region: us-west2
      securityPolicy: ${policynetworkmatch.name}
      description: custom rule for network match
      priority: 100
      networkMatch:
        srcIpRanges:
          - 10.10.0.0/16
        userDefinedFields:
          - name: SIG1_AT_0
            values:
              - 0x8F00
      action: allow
      preview: true

Network match rules use the networkMatch property instead of match. They operate on CLOUD_ARMOR_NETWORK policies with advanced DDoS protection enabled. The userDefinedFields array references custom fields defined in the parent security policy, extracted from TCP headers. This example matches packets from specific IP ranges with a particular TCP header value, enabling protocol-specific filtering for DDoS mitigation.

Beyond these examples

These snippets focus on specific rule-level features: IP-based access control and priority ordering, WAF exclusions for false positive handling, and network-level packet matching for DDoS protection. They’re intentionally minimal rather than full security configurations.

The examples reference pre-existing infrastructure such as RegionSecurityPolicy resources, NetworkEdgeSecurityService (for network match rules), and advanced DDoS protection activation (for network match rules). They focus on configuring individual rules rather than provisioning the entire security stack.

To keep things focused, common rule patterns are omitted, including:

  • Rate limiting and ban actions (rateLimitOptions)
  • Redirect actions and reCAPTCHA integration
  • Geographic restrictions (srcRegionCodes)
  • Expression-based matching beyond IP ranges

These omissions are intentional: the goal is to illustrate how each rule feature is wired, not provide drop-in security modules. See the RegionSecurityPolicyRule resource reference for all available configuration options.

Let's configure GCP Region Security Policy Rules

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Rule Configuration & Priority
How does rule priority work?
Priority must be an integer between 0 and 2147483647. Rules are evaluated from highest to lowest priority, where 0 is the highest priority and 2147483647 is the lowest.
What properties can't I change after creating a rule?
The priority, region, securityPolicy, and project properties are immutable. Changing these requires recreating the rule.
How do I create a default catch-all rule?
Set priority to 2147483647 (the lowest priority) and configure srcIpRanges to ["*"] to match all traffic not handled by higher-priority rules.
Actions & Rate Limiting
What actions can I configure for a security policy rule?
You can use allow, deny(STATUS) (where STATUS is 403, 404, or 502), rate_based_ban, redirect, or throttle. The redirect action is only supported in Global Security Policies of type CLOUD_ARMOR.
When is rateLimitOptions required?
You must specify rateLimitOptions when action is rate_based_ban or throttle. It cannot be used with other actions like allow or deny.
Match Conditions
What's the difference between match and networkMatch?
Use match for standard Cloud Armor policies to evaluate incoming traffic. Use networkMatch for CLOUD_ARMOR_NETWORK policies, which supports packet-level matching with srcIpRanges and userDefinedFields.
Can I use multiple IP ranges in a single rule?
Yes, you can specify multiple IP ranges in srcIpRanges as an array. The rule matches if the source IP is in any of the specified ranges.
How do I use user-defined fields in network matching?
For CLOUD_ARMOR_NETWORK policies, define fields in the parent security policy’s userDefinedFields (with name, base, offset, size, mask), then reference them in the rule’s networkMatch.userDefinedFields with matching values.
Testing & WAF Configuration
How do I test a rule without enforcing it?
Set preview to true. The rule will be evaluated but the specified action won’t be enforced, allowing you to test the rule’s behavior safely.
Why isn't my preconfiguredWafConfig taking effect?
The preconfiguredWafConfig has no effect unless the rule uses evaluatePreconfiguredWaf() to evaluate preconfigured WAF rules. Configure both the WAF config and ensure the evaluation function is called.

Using a different cloud?

Explore security guides for other cloud providers: