The gcp:compute/regionSecurityPolicyRule:RegionSecurityPolicyRule resource, part of the Pulumi GCP provider, defines individual rules within a RegionSecurityPolicy that match traffic patterns and enforce allow, deny, or rate-limiting actions. This guide focuses on four capabilities: IP-based access control, default-deny patterns, WAF exclusion configuration, and packet-level network matching.
Rules belong to a RegionSecurityPolicy and reference its name. Network match rules require advanced DDoS protection and 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 a request arrives, Cloud Armor evaluates it against the match condition. The versionedExpr field specifies the match type (SRC_IPS_V1 for IP-based matching), and srcIpRanges lists the CIDR blocks to match. The priority determines evaluation order: lower numbers are evaluated first. The action specifies what happens when the rule matches (allow or deny).
Configure a default deny rule with exceptions
Security policies often use a default-deny approach where all traffic is blocked unless explicitly allowed by higher-priority rules.
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 default rule uses priority 2147483647 (the lowest possible value) to catch everything not matched earlier. The srcIpRanges value “*” matches all traffic. Higher-priority rules (lower numbers like 100) are evaluated first, so allowed IPs pass through before reaching the default deny.
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 rule set (like “rce-stable” or “xss-stable”) and specifies which request components to skip: URIs, query parameters, headers, or cookies. The operator field controls matching behavior (STARTS_WITH, CONTAINS, EQUALS). You can exclude entire rule sets or specific rule IDs within a set.
Match packets using custom header fields
Advanced DDoS protection scenarios require matching on packet-level details beyond source IPs, such as TCP flags or custom protocol fields.
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 operate at the packet level for CLOUD_ARMOR_NETWORK policies. The networkMatch property replaces the standard match property and supports userDefinedFields that extract values from packet headers. The security policy must define these fields (name, base protocol, offset, size, mask) before rules can reference them. This example matches packets from specific IP ranges with a custom TCP header field value.
Beyond these examples
These snippets focus on specific rule-level features: IP-based access control and default-deny patterns, WAF exclusions for false positive handling, and packet-level matching with custom header fields. 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 CLOUD_ARMOR_NETWORK). 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)
- Geographic restrictions (srcRegionCodes)
- Expression-based matching beyond IP ranges
- Redirect actions and reCAPTCHA integration
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 FREEFrequently Asked Questions
Rule Configuration & Priorities
priority, project, region, and securityPolicy are immutable. Changing any of these requires recreating the rule.priority to 2147483647 (lowest priority), action to “deny”, and srcIpRanges to ["*"] in your match configuration. This catches all traffic not matched by higher-priority rules.RegionSecurityPolicyRule resources with different priorities, all referencing the same securityPolicy name. Each rule needs a unique priority value.Actions & Rate Limiting
allow (permit traffic), deny(STATUS) (block with HTTP status 403/404/502), rate_based_ban (rate limit and ban), redirect (reCAPTCHA or external URL), or throttle (rate limit only).rateLimitOptions when using rate_based_ban or throttle actions. You cannot use rateLimitOptions with any other action types.preview: true tests the rule without enforcing any action, while action: "allow" actively permits matching traffic when the rule is enforced.Match Conditions & Filtering
match for standard CLOUD_ARMOR policies with IP-based filtering. Use networkMatch for CLOUD_ARMOR_NETWORK policies that support user-defined packet fields and advanced network filtering.match block with versionedExpr: "SRC_IPS_V1" and specify IP ranges in config.srcIpRanges, such as [“10.10.0.0/16”].preconfiguredWafConfig.exclusions to specify request URIs, query parameters, or headers that should bypass WAF rules. You can target specific rule sets and rule IDs.