Configure GCP Network Security Profiles

The gcp:networksecurity/securityProfile:SecurityProfile resource, part of the Pulumi GCP provider, defines security profiles that control threat prevention, URL filtering, or traffic mirroring behavior at the organization level. This guide focuses on three capabilities: threat prevention with severity overrides, URL filtering with priority rules, and traffic mirroring to external collectors.

Security profiles are created at the organization level and may reference VPC networks, deployment groups, and endpoint groups for mirroring or intercept configurations. The examples are intentionally small. Combine them with your own firewall policies and enforcement points.

Create a threat prevention profile with labels

Organizations deploying Cloud Firewall start by creating security profiles that define threat prevention behavior at the organization level.

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

const _default = new gcp.networksecurity.SecurityProfile("default", {
    name: "my-security-profile",
    parent: "organizations/123456789",
    description: "my description",
    type: "THREAT_PREVENTION",
    labels: {
        foo: "bar",
    },
});
import pulumi
import pulumi_gcp as gcp

default = gcp.networksecurity.SecurityProfile("default",
    name="my-security-profile",
    parent="organizations/123456789",
    description="my description",
    type="THREAT_PREVENTION",
    labels={
        "foo": "bar",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := networksecurity.NewSecurityProfile(ctx, "default", &networksecurity.SecurityProfileArgs{
			Name:        pulumi.String("my-security-profile"),
			Parent:      pulumi.String("organizations/123456789"),
			Description: pulumi.String("my description"),
			Type:        pulumi.String("THREAT_PREVENTION"),
			Labels: pulumi.StringMap{
				"foo": pulumi.String("bar"),
			},
		})
		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.NetworkSecurity.SecurityProfile("default", new()
    {
        Name = "my-security-profile",
        Parent = "organizations/123456789",
        Description = "my description",
        Type = "THREAT_PREVENTION",
        Labels = 
        {
            { "foo", "bar" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networksecurity.SecurityProfile;
import com.pulumi.gcp.networksecurity.SecurityProfileArgs;
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 SecurityProfile("default", SecurityProfileArgs.builder()
            .name("my-security-profile")
            .parent("organizations/123456789")
            .description("my description")
            .type("THREAT_PREVENTION")
            .labels(Map.of("foo", "bar"))
            .build());

    }
}
resources:
  default:
    type: gcp:networksecurity:SecurityProfile
    properties:
      name: my-security-profile
      parent: organizations/123456789
      description: my description
      type: THREAT_PREVENTION
      labels:
        foo: bar

The type property determines the profile’s behavior; THREAT_PREVENTION enables Google’s threat intelligence. The parent property specifies the organization scope using the format “organizations/{organization_id}”. Labels provide metadata for organization and cost tracking.

Override threat severity and antivirus actions

Security teams often need to tune threat prevention by adjusting responses to specific threat severities, individual threat IDs, or protocol-specific antivirus detections.

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

const _default = new gcp.networksecurity.SecurityProfile("default", {
    name: "my-security-profile",
    parent: "organizations/123456789",
    description: "my description",
    type: "THREAT_PREVENTION",
    threatPreventionProfile: {
        severityOverrides: [
            {
                action: "ALLOW",
                severity: "INFORMATIONAL",
            },
            {
                action: "DENY",
                severity: "HIGH",
            },
        ],
        threatOverrides: [{
            action: "ALLOW",
            threatId: "280647",
        }],
        antivirusOverrides: [{
            protocol: "SMTP",
            action: "ALLOW",
        }],
    },
});
import pulumi
import pulumi_gcp as gcp

default = gcp.networksecurity.SecurityProfile("default",
    name="my-security-profile",
    parent="organizations/123456789",
    description="my description",
    type="THREAT_PREVENTION",
    threat_prevention_profile={
        "severity_overrides": [
            {
                "action": "ALLOW",
                "severity": "INFORMATIONAL",
            },
            {
                "action": "DENY",
                "severity": "HIGH",
            },
        ],
        "threat_overrides": [{
            "action": "ALLOW",
            "threat_id": "280647",
        }],
        "antivirus_overrides": [{
            "protocol": "SMTP",
            "action": "ALLOW",
        }],
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := networksecurity.NewSecurityProfile(ctx, "default", &networksecurity.SecurityProfileArgs{
			Name:        pulumi.String("my-security-profile"),
			Parent:      pulumi.String("organizations/123456789"),
			Description: pulumi.String("my description"),
			Type:        pulumi.String("THREAT_PREVENTION"),
			ThreatPreventionProfile: &networksecurity.SecurityProfileThreatPreventionProfileArgs{
				SeverityOverrides: networksecurity.SecurityProfileThreatPreventionProfileSeverityOverrideArray{
					&networksecurity.SecurityProfileThreatPreventionProfileSeverityOverrideArgs{
						Action:   pulumi.String("ALLOW"),
						Severity: pulumi.String("INFORMATIONAL"),
					},
					&networksecurity.SecurityProfileThreatPreventionProfileSeverityOverrideArgs{
						Action:   pulumi.String("DENY"),
						Severity: pulumi.String("HIGH"),
					},
				},
				ThreatOverrides: networksecurity.SecurityProfileThreatPreventionProfileThreatOverrideArray{
					&networksecurity.SecurityProfileThreatPreventionProfileThreatOverrideArgs{
						Action:   pulumi.String("ALLOW"),
						ThreatId: pulumi.String("280647"),
					},
				},
				AntivirusOverrides: networksecurity.SecurityProfileThreatPreventionProfileAntivirusOverrideArray{
					&networksecurity.SecurityProfileThreatPreventionProfileAntivirusOverrideArgs{
						Protocol: pulumi.String("SMTP"),
						Action:   pulumi.String("ALLOW"),
					},
				},
			},
		})
		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.NetworkSecurity.SecurityProfile("default", new()
    {
        Name = "my-security-profile",
        Parent = "organizations/123456789",
        Description = "my description",
        Type = "THREAT_PREVENTION",
        ThreatPreventionProfile = new Gcp.NetworkSecurity.Inputs.SecurityProfileThreatPreventionProfileArgs
        {
            SeverityOverrides = new[]
            {
                new Gcp.NetworkSecurity.Inputs.SecurityProfileThreatPreventionProfileSeverityOverrideArgs
                {
                    Action = "ALLOW",
                    Severity = "INFORMATIONAL",
                },
                new Gcp.NetworkSecurity.Inputs.SecurityProfileThreatPreventionProfileSeverityOverrideArgs
                {
                    Action = "DENY",
                    Severity = "HIGH",
                },
            },
            ThreatOverrides = new[]
            {
                new Gcp.NetworkSecurity.Inputs.SecurityProfileThreatPreventionProfileThreatOverrideArgs
                {
                    Action = "ALLOW",
                    ThreatId = "280647",
                },
            },
            AntivirusOverrides = new[]
            {
                new Gcp.NetworkSecurity.Inputs.SecurityProfileThreatPreventionProfileAntivirusOverrideArgs
                {
                    Protocol = "SMTP",
                    Action = "ALLOW",
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networksecurity.SecurityProfile;
import com.pulumi.gcp.networksecurity.SecurityProfileArgs;
import com.pulumi.gcp.networksecurity.inputs.SecurityProfileThreatPreventionProfileArgs;
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 SecurityProfile("default", SecurityProfileArgs.builder()
            .name("my-security-profile")
            .parent("organizations/123456789")
            .description("my description")
            .type("THREAT_PREVENTION")
            .threatPreventionProfile(SecurityProfileThreatPreventionProfileArgs.builder()
                .severityOverrides(                
                    SecurityProfileThreatPreventionProfileSeverityOverrideArgs.builder()
                        .action("ALLOW")
                        .severity("INFORMATIONAL")
                        .build(),
                    SecurityProfileThreatPreventionProfileSeverityOverrideArgs.builder()
                        .action("DENY")
                        .severity("HIGH")
                        .build())
                .threatOverrides(SecurityProfileThreatPreventionProfileThreatOverrideArgs.builder()
                    .action("ALLOW")
                    .threatId("280647")
                    .build())
                .antivirusOverrides(SecurityProfileThreatPreventionProfileAntivirusOverrideArgs.builder()
                    .protocol("SMTP")
                    .action("ALLOW")
                    .build())
                .build())
            .build());

    }
}
resources:
  default:
    type: gcp:networksecurity:SecurityProfile
    properties:
      name: my-security-profile
      parent: organizations/123456789
      description: my description
      type: THREAT_PREVENTION
      threatPreventionProfile:
        severityOverrides:
          - action: ALLOW
            severity: INFORMATIONAL
          - action: DENY
            severity: HIGH
        threatOverrides:
          - action: ALLOW
            threatId: '280647'
        antivirusOverrides:
          - protocol: SMTP
            action: ALLOW

The threatPreventionProfile block contains three override types. The severityOverrides array maps threat severity levels (INFORMATIONAL, LOW, MEDIUM, HIGH, CRITICAL) to actions (ALLOW, ALERT, DENY). The threatOverrides array targets specific threat IDs by number. The antivirusOverrides array controls protocol-specific antivirus behavior for protocols like SMTP, POP3, and IMAP.

Filter traffic by URL patterns and priorities

Organizations enforcing acceptable use policies need to control which URLs users can access through priority-based evaluation.

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

const _default = new gcp.networksecurity.SecurityProfile("default", {
    name: "my-security-profile",
    parent: "organizations/123456789",
    description: "my description",
    type: "URL_FILTERING",
    urlFilteringProfile: {
        urlFilters: [
            {
                priority: 1,
                filteringAction: "ALLOW",
                urls: [
                    "*example.com",
                    "*about.example.com",
                    "*help.example.com",
                ],
            },
            {
                priority: 2,
                filteringAction: "DENY",
                urls: ["*restricted.example.com"],
            },
        ],
    },
    labels: {
        foo: "bar",
    },
});
import pulumi
import pulumi_gcp as gcp

default = gcp.networksecurity.SecurityProfile("default",
    name="my-security-profile",
    parent="organizations/123456789",
    description="my description",
    type="URL_FILTERING",
    url_filtering_profile={
        "url_filters": [
            {
                "priority": 1,
                "filtering_action": "ALLOW",
                "urls": [
                    "*example.com",
                    "*about.example.com",
                    "*help.example.com",
                ],
            },
            {
                "priority": 2,
                "filtering_action": "DENY",
                "urls": ["*restricted.example.com"],
            },
        ],
    },
    labels={
        "foo": "bar",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := networksecurity.NewSecurityProfile(ctx, "default", &networksecurity.SecurityProfileArgs{
			Name:        pulumi.String("my-security-profile"),
			Parent:      pulumi.String("organizations/123456789"),
			Description: pulumi.String("my description"),
			Type:        pulumi.String("URL_FILTERING"),
			UrlFilteringProfile: &networksecurity.SecurityProfileUrlFilteringProfileArgs{
				UrlFilters: networksecurity.SecurityProfileUrlFilteringProfileUrlFilterArray{
					&networksecurity.SecurityProfileUrlFilteringProfileUrlFilterArgs{
						Priority:        pulumi.Int(1),
						FilteringAction: pulumi.String("ALLOW"),
						Urls: pulumi.StringArray{
							pulumi.String("*example.com"),
							pulumi.String("*about.example.com"),
							pulumi.String("*help.example.com"),
						},
					},
					&networksecurity.SecurityProfileUrlFilteringProfileUrlFilterArgs{
						Priority:        pulumi.Int(2),
						FilteringAction: pulumi.String("DENY"),
						Urls: pulumi.StringArray{
							pulumi.String("*restricted.example.com"),
						},
					},
				},
			},
			Labels: pulumi.StringMap{
				"foo": pulumi.String("bar"),
			},
		})
		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.NetworkSecurity.SecurityProfile("default", new()
    {
        Name = "my-security-profile",
        Parent = "organizations/123456789",
        Description = "my description",
        Type = "URL_FILTERING",
        UrlFilteringProfile = new Gcp.NetworkSecurity.Inputs.SecurityProfileUrlFilteringProfileArgs
        {
            UrlFilters = new[]
            {
                new Gcp.NetworkSecurity.Inputs.SecurityProfileUrlFilteringProfileUrlFilterArgs
                {
                    Priority = 1,
                    FilteringAction = "ALLOW",
                    Urls = new[]
                    {
                        "*example.com",
                        "*about.example.com",
                        "*help.example.com",
                    },
                },
                new Gcp.NetworkSecurity.Inputs.SecurityProfileUrlFilteringProfileUrlFilterArgs
                {
                    Priority = 2,
                    FilteringAction = "DENY",
                    Urls = new[]
                    {
                        "*restricted.example.com",
                    },
                },
            },
        },
        Labels = 
        {
            { "foo", "bar" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networksecurity.SecurityProfile;
import com.pulumi.gcp.networksecurity.SecurityProfileArgs;
import com.pulumi.gcp.networksecurity.inputs.SecurityProfileUrlFilteringProfileArgs;
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 SecurityProfile("default", SecurityProfileArgs.builder()
            .name("my-security-profile")
            .parent("organizations/123456789")
            .description("my description")
            .type("URL_FILTERING")
            .urlFilteringProfile(SecurityProfileUrlFilteringProfileArgs.builder()
                .urlFilters(                
                    SecurityProfileUrlFilteringProfileUrlFilterArgs.builder()
                        .priority(1)
                        .filteringAction("ALLOW")
                        .urls(                        
                            "*example.com",
                            "*about.example.com",
                            "*help.example.com")
                        .build(),
                    SecurityProfileUrlFilteringProfileUrlFilterArgs.builder()
                        .priority(2)
                        .filteringAction("DENY")
                        .urls("*restricted.example.com")
                        .build())
                .build())
            .labels(Map.of("foo", "bar"))
            .build());

    }
}
resources:
  default:
    type: gcp:networksecurity:SecurityProfile
    properties:
      name: my-security-profile
      parent: organizations/123456789
      description: my description
      type: URL_FILTERING
      urlFilteringProfile:
        urlFilters:
          - priority: 1
            filteringAction: ALLOW
            urls:
              - '*example.com'
              - '*about.example.com'
              - '*help.example.com'
          - priority: 2
            filteringAction: DENY
            urls:
              - '*restricted.example.com'
      labels:
        foo: bar

The urlFilteringProfile block contains a urlFilters array where each entry has a priority (lower numbers evaluate first), a filteringAction (ALLOW or DENY), and a urls array supporting wildcards. In this configuration, priority 1 allows access to example.com domains, while priority 2 denies restricted.example.com.

Mirror traffic to third-party collectors

Security operations teams running third-party analysis tools need to mirror network traffic to external collectors for inspection.

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

const _default = new gcp.compute.Network("default", {
    name: "my-network",
    autoCreateSubnetworks: false,
});
const defaultMirroringDeploymentGroup = new gcp.networksecurity.MirroringDeploymentGroup("default", {
    mirroringDeploymentGroupId: "my-dg",
    location: "global",
    network: _default.id,
});
const defaultMirroringEndpointGroup = new gcp.networksecurity.MirroringEndpointGroup("default", {
    mirroringEndpointGroupId: "my-eg",
    location: "global",
    mirroringDeploymentGroup: defaultMirroringDeploymentGroup.id,
});
const defaultSecurityProfile = new gcp.networksecurity.SecurityProfile("default", {
    name: "my-security-profile",
    parent: "organizations/123456789",
    description: "my description",
    type: "CUSTOM_MIRRORING",
    customMirroringProfile: {
        mirroringEndpointGroup: defaultMirroringEndpointGroup.id,
    },
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.Network("default",
    name="my-network",
    auto_create_subnetworks=False)
default_mirroring_deployment_group = gcp.networksecurity.MirroringDeploymentGroup("default",
    mirroring_deployment_group_id="my-dg",
    location="global",
    network=default.id)
default_mirroring_endpoint_group = gcp.networksecurity.MirroringEndpointGroup("default",
    mirroring_endpoint_group_id="my-eg",
    location="global",
    mirroring_deployment_group=default_mirroring_deployment_group.id)
default_security_profile = gcp.networksecurity.SecurityProfile("default",
    name="my-security-profile",
    parent="organizations/123456789",
    description="my description",
    type="CUSTOM_MIRRORING",
    custom_mirroring_profile={
        "mirroring_endpoint_group": default_mirroring_endpoint_group.id,
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := compute.NewNetwork(ctx, "default", &compute.NetworkArgs{
			Name:                  pulumi.String("my-network"),
			AutoCreateSubnetworks: pulumi.Bool(false),
		})
		if err != nil {
			return err
		}
		defaultMirroringDeploymentGroup, err := networksecurity.NewMirroringDeploymentGroup(ctx, "default", &networksecurity.MirroringDeploymentGroupArgs{
			MirroringDeploymentGroupId: pulumi.String("my-dg"),
			Location:                   pulumi.String("global"),
			Network:                    _default.ID(),
		})
		if err != nil {
			return err
		}
		defaultMirroringEndpointGroup, err := networksecurity.NewMirroringEndpointGroup(ctx, "default", &networksecurity.MirroringEndpointGroupArgs{
			MirroringEndpointGroupId: pulumi.String("my-eg"),
			Location:                 pulumi.String("global"),
			MirroringDeploymentGroup: defaultMirroringDeploymentGroup.ID(),
		})
		if err != nil {
			return err
		}
		_, err = networksecurity.NewSecurityProfile(ctx, "default", &networksecurity.SecurityProfileArgs{
			Name:        pulumi.String("my-security-profile"),
			Parent:      pulumi.String("organizations/123456789"),
			Description: pulumi.String("my description"),
			Type:        pulumi.String("CUSTOM_MIRRORING"),
			CustomMirroringProfile: &networksecurity.SecurityProfileCustomMirroringProfileArgs{
				MirroringEndpointGroup: defaultMirroringEndpointGroup.ID(),
			},
		})
		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.Network("default", new()
    {
        Name = "my-network",
        AutoCreateSubnetworks = false,
    });

    var defaultMirroringDeploymentGroup = new Gcp.NetworkSecurity.MirroringDeploymentGroup("default", new()
    {
        MirroringDeploymentGroupId = "my-dg",
        Location = "global",
        Network = @default.Id,
    });

    var defaultMirroringEndpointGroup = new Gcp.NetworkSecurity.MirroringEndpointGroup("default", new()
    {
        MirroringEndpointGroupId = "my-eg",
        Location = "global",
        MirroringDeploymentGroup = defaultMirroringDeploymentGroup.Id,
    });

    var defaultSecurityProfile = new Gcp.NetworkSecurity.SecurityProfile("default", new()
    {
        Name = "my-security-profile",
        Parent = "organizations/123456789",
        Description = "my description",
        Type = "CUSTOM_MIRRORING",
        CustomMirroringProfile = new Gcp.NetworkSecurity.Inputs.SecurityProfileCustomMirroringProfileArgs
        {
            MirroringEndpointGroup = defaultMirroringEndpointGroup.Id,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.networksecurity.MirroringDeploymentGroup;
import com.pulumi.gcp.networksecurity.MirroringDeploymentGroupArgs;
import com.pulumi.gcp.networksecurity.MirroringEndpointGroup;
import com.pulumi.gcp.networksecurity.MirroringEndpointGroupArgs;
import com.pulumi.gcp.networksecurity.SecurityProfile;
import com.pulumi.gcp.networksecurity.SecurityProfileArgs;
import com.pulumi.gcp.networksecurity.inputs.SecurityProfileCustomMirroringProfileArgs;
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 Network("default", NetworkArgs.builder()
            .name("my-network")
            .autoCreateSubnetworks(false)
            .build());

        var defaultMirroringDeploymentGroup = new MirroringDeploymentGroup("defaultMirroringDeploymentGroup", MirroringDeploymentGroupArgs.builder()
            .mirroringDeploymentGroupId("my-dg")
            .location("global")
            .network(default_.id())
            .build());

        var defaultMirroringEndpointGroup = new MirroringEndpointGroup("defaultMirroringEndpointGroup", MirroringEndpointGroupArgs.builder()
            .mirroringEndpointGroupId("my-eg")
            .location("global")
            .mirroringDeploymentGroup(defaultMirroringDeploymentGroup.id())
            .build());

        var defaultSecurityProfile = new SecurityProfile("defaultSecurityProfile", SecurityProfileArgs.builder()
            .name("my-security-profile")
            .parent("organizations/123456789")
            .description("my description")
            .type("CUSTOM_MIRRORING")
            .customMirroringProfile(SecurityProfileCustomMirroringProfileArgs.builder()
                .mirroringEndpointGroup(defaultMirroringEndpointGroup.id())
                .build())
            .build());

    }
}
resources:
  default:
    type: gcp:compute:Network
    properties:
      name: my-network
      autoCreateSubnetworks: false
  defaultMirroringDeploymentGroup:
    type: gcp:networksecurity:MirroringDeploymentGroup
    name: default
    properties:
      mirroringDeploymentGroupId: my-dg
      location: global
      network: ${default.id}
  defaultMirroringEndpointGroup:
    type: gcp:networksecurity:MirroringEndpointGroup
    name: default
    properties:
      mirroringEndpointGroupId: my-eg
      location: global
      mirroringDeploymentGroup: ${defaultMirroringDeploymentGroup.id}
  defaultSecurityProfile:
    type: gcp:networksecurity:SecurityProfile
    name: default
    properties:
      name: my-security-profile
      parent: organizations/123456789
      description: my description
      type: CUSTOM_MIRRORING
      customMirroringProfile:
        mirroringEndpointGroup: ${defaultMirroringEndpointGroup.id}

The customMirroringProfile block references a MirroringEndpointGroup, which defines where traffic copies are sent. The endpoint group itself references a MirroringDeploymentGroup that’s attached to a VPC network. This creates a chain: network → deployment group → endpoint group → security profile.

Beyond these examples

These snippets focus on specific security profile features: threat prevention with severity and protocol overrides, URL filtering with priority-based rules, and traffic mirroring to third-party collectors. They’re intentionally minimal rather than full security deployments.

The examples may reference pre-existing infrastructure such as organization ID (parent parameter) and VPC networks for mirroring and intercept profiles. They focus on configuring the security profile rather than provisioning the surrounding infrastructure.

To keep things focused, common security profile patterns are omitted, including:

  • Intercept profiles for inline third-party firewalls (CUSTOM_INTERCEPT)
  • Broker-based mirroring with multiple deployment groups
  • Attachment to firewall policies and enforcement points
  • Location-specific profiles (defaults to global)

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

Let's configure GCP Network Security Profiles

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Profile Types & Configuration
What security profile types are available?
Four types are available: THREAT_PREVENTION (threat detection and prevention), URL_FILTERING (URL-based filtering), CUSTOM_MIRRORING (traffic mirroring to third-party collectors), and CUSTOM_INTERCEPT (traffic interception to third-party firewalls).
Which configuration is required for each profile type?

Each type requires a corresponding profile configuration:

  • THREAT_PREVENTION requires threatPreventionProfile
  • URL_FILTERING requires urlFilteringProfile
  • CUSTOM_MIRRORING requires customMirroringProfile
  • CUSTOM_INTERCEPT requires customInterceptProfile
What format does the parent parameter require?
The parent parameter must use the format organizations/{organization_id}, where {organization_id} is your GCP organization ID.
Immutability & Constraints
What properties can't I change after creating a security profile?
Four properties are immutable: name, type, parent, and location. Changing any of these requires destroying and recreating the resource.
What's the maximum length for the description field?
The description field has a maximum length of 512 characters.
Labels & Metadata
Why aren't all my labels showing up in the labels field?
The labels field is non-authoritative and only manages labels in your Pulumi configuration. To see all labels on the resource (including those set by other clients), use effectiveLabels.
Threat Prevention Configuration
How do I configure threat prevention with custom overrides?

Set threatPreventionProfile with three types of overrides:

  • severityOverrides: Override actions for severity levels (e.g., ALLOW for INFORMATIONAL, DENY for HIGH)
  • threatOverrides: Override actions for specific threat IDs
  • antivirusOverrides: Override actions for specific protocols (e.g., SMTP)
Custom Mirroring & Interception
How do I set up custom traffic mirroring to third-party collectors?
Use type: "CUSTOM_MIRRORING" with customMirroringProfile containing a mirroringEndpointGroup reference. You’ll need to create a MirroringDeploymentGroup and MirroringEndpointGroup first.
How do I configure traffic interception to third-party firewalls?
Use type: "CUSTOM_INTERCEPT" with customInterceptProfile containing an interceptEndpointGroup reference. You’ll need to create an InterceptDeploymentGroup and InterceptEndpointGroup first.
URL Filtering Configuration
How do I configure URL filtering rules?

Set urlFilteringProfile with a urlFilters array. Each filter requires:

  • priority: Numeric priority (lower numbers evaluated first)
  • filteringAction: Either ALLOW or DENY
  • urls: Array of URL patterns (supports wildcards like *example.com)

Using a different cloud?

Explore security guides for other cloud providers: