The gcp:networksecurity/securityProfileGroup:SecurityProfileGroup resource, part of the Pulumi GCP provider, defines a container that groups security profiles for threat prevention, URL filtering, traffic mirroring, or inline inspection. This guide focuses on three capabilities: threat prevention profiles, traffic mirroring and inline inspection, and URL filtering policies.
Security profile groups reference SecurityProfile resources and belong to GCP organizations. Mirroring and intercept configurations require VPC networks, deployment groups, and endpoint groups. The examples are intentionally small. Combine them with your own firewall policies and network infrastructure.
Apply threat prevention to network traffic
Organizations protecting cloud workloads often start by applying threat prevention profiles that detect and block malicious traffic at the network layer.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const securityProfile = new gcp.networksecurity.SecurityProfile("security_profile", {
name: "sec-profile",
type: "THREAT_PREVENTION",
parent: "organizations/123456789",
location: "global",
});
const _default = new gcp.networksecurity.SecurityProfileGroup("default", {
name: "sec-profile-group",
parent: "organizations/123456789",
description: "my description",
threatPreventionProfile: securityProfile.id,
labels: {
foo: "bar",
},
});
import pulumi
import pulumi_gcp as gcp
security_profile = gcp.networksecurity.SecurityProfile("security_profile",
name="sec-profile",
type="THREAT_PREVENTION",
parent="organizations/123456789",
location="global")
default = gcp.networksecurity.SecurityProfileGroup("default",
name="sec-profile-group",
parent="organizations/123456789",
description="my description",
threat_prevention_profile=security_profile.id,
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 {
securityProfile, err := networksecurity.NewSecurityProfile(ctx, "security_profile", &networksecurity.SecurityProfileArgs{
Name: pulumi.String("sec-profile"),
Type: pulumi.String("THREAT_PREVENTION"),
Parent: pulumi.String("organizations/123456789"),
Location: pulumi.String("global"),
})
if err != nil {
return err
}
_, err = networksecurity.NewSecurityProfileGroup(ctx, "default", &networksecurity.SecurityProfileGroupArgs{
Name: pulumi.String("sec-profile-group"),
Parent: pulumi.String("organizations/123456789"),
Description: pulumi.String("my description"),
ThreatPreventionProfile: securityProfile.ID(),
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 securityProfile = new Gcp.NetworkSecurity.SecurityProfile("security_profile", new()
{
Name = "sec-profile",
Type = "THREAT_PREVENTION",
Parent = "organizations/123456789",
Location = "global",
});
var @default = new Gcp.NetworkSecurity.SecurityProfileGroup("default", new()
{
Name = "sec-profile-group",
Parent = "organizations/123456789",
Description = "my description",
ThreatPreventionProfile = securityProfile.Id,
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.SecurityProfileGroup;
import com.pulumi.gcp.networksecurity.SecurityProfileGroupArgs;
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 securityProfile = new SecurityProfile("securityProfile", SecurityProfileArgs.builder()
.name("sec-profile")
.type("THREAT_PREVENTION")
.parent("organizations/123456789")
.location("global")
.build());
var default_ = new SecurityProfileGroup("default", SecurityProfileGroupArgs.builder()
.name("sec-profile-group")
.parent("organizations/123456789")
.description("my description")
.threatPreventionProfile(securityProfile.id())
.labels(Map.of("foo", "bar"))
.build());
}
}
resources:
default:
type: gcp:networksecurity:SecurityProfileGroup
properties:
name: sec-profile-group
parent: organizations/123456789
description: my description
threatPreventionProfile: ${securityProfile.id}
labels:
foo: bar
securityProfile:
type: gcp:networksecurity:SecurityProfile
name: security_profile
properties:
name: sec-profile
type: THREAT_PREVENTION
parent: organizations/123456789
location: global
The threatPreventionProfile property references a SecurityProfile configured with Google’s threat intelligence. The parent property specifies the organization scope (format: organizations/{organization_id}), and location defaults to global for organization-wide application. The profile group acts as a container; you attach it to firewall policies to enforce protection.
Mirror traffic to inspection endpoints
Security teams analyzing network behavior deploy mirroring profiles to copy traffic to dedicated inspection endpoints without disrupting production flows.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const _default = new gcp.compute.Network("default", {
name: "network",
autoCreateSubnetworks: false,
});
const defaultMirroringDeploymentGroup = new gcp.networksecurity.MirroringDeploymentGroup("default", {
mirroringDeploymentGroupId: "deployment-group",
location: "global",
network: _default.id,
});
const defaultMirroringEndpointGroup = new gcp.networksecurity.MirroringEndpointGroup("default", {
mirroringEndpointGroupId: "endpoint-group",
location: "global",
mirroringDeploymentGroup: defaultMirroringDeploymentGroup.id,
});
const defaultSecurityProfile = new gcp.networksecurity.SecurityProfile("default", {
name: "sec-profile",
parent: "organizations/123456789",
description: "my description",
type: "CUSTOM_MIRRORING",
customMirroringProfile: {
mirroringEndpointGroup: defaultMirroringEndpointGroup.id,
},
});
const defaultSecurityProfileGroup = new gcp.networksecurity.SecurityProfileGroup("default", {
name: "sec-profile-group",
parent: "organizations/123456789",
description: "my description",
customMirroringProfile: defaultSecurityProfile.id,
});
import pulumi
import pulumi_gcp as gcp
default = gcp.compute.Network("default",
name="network",
auto_create_subnetworks=False)
default_mirroring_deployment_group = gcp.networksecurity.MirroringDeploymentGroup("default",
mirroring_deployment_group_id="deployment-group",
location="global",
network=default.id)
default_mirroring_endpoint_group = gcp.networksecurity.MirroringEndpointGroup("default",
mirroring_endpoint_group_id="endpoint-group",
location="global",
mirroring_deployment_group=default_mirroring_deployment_group.id)
default_security_profile = gcp.networksecurity.SecurityProfile("default",
name="sec-profile",
parent="organizations/123456789",
description="my description",
type="CUSTOM_MIRRORING",
custom_mirroring_profile={
"mirroring_endpoint_group": default_mirroring_endpoint_group.id,
})
default_security_profile_group = gcp.networksecurity.SecurityProfileGroup("default",
name="sec-profile-group",
parent="organizations/123456789",
description="my description",
custom_mirroring_profile=default_security_profile.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("network"),
AutoCreateSubnetworks: pulumi.Bool(false),
})
if err != nil {
return err
}
defaultMirroringDeploymentGroup, err := networksecurity.NewMirroringDeploymentGroup(ctx, "default", &networksecurity.MirroringDeploymentGroupArgs{
MirroringDeploymentGroupId: pulumi.String("deployment-group"),
Location: pulumi.String("global"),
Network: _default.ID(),
})
if err != nil {
return err
}
defaultMirroringEndpointGroup, err := networksecurity.NewMirroringEndpointGroup(ctx, "default", &networksecurity.MirroringEndpointGroupArgs{
MirroringEndpointGroupId: pulumi.String("endpoint-group"),
Location: pulumi.String("global"),
MirroringDeploymentGroup: defaultMirroringDeploymentGroup.ID(),
})
if err != nil {
return err
}
defaultSecurityProfile, err := networksecurity.NewSecurityProfile(ctx, "default", &networksecurity.SecurityProfileArgs{
Name: pulumi.String("sec-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
}
_, err = networksecurity.NewSecurityProfileGroup(ctx, "default", &networksecurity.SecurityProfileGroupArgs{
Name: pulumi.String("sec-profile-group"),
Parent: pulumi.String("organizations/123456789"),
Description: pulumi.String("my description"),
CustomMirroringProfile: defaultSecurityProfile.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 = "network",
AutoCreateSubnetworks = false,
});
var defaultMirroringDeploymentGroup = new Gcp.NetworkSecurity.MirroringDeploymentGroup("default", new()
{
MirroringDeploymentGroupId = "deployment-group",
Location = "global",
Network = @default.Id,
});
var defaultMirroringEndpointGroup = new Gcp.NetworkSecurity.MirroringEndpointGroup("default", new()
{
MirroringEndpointGroupId = "endpoint-group",
Location = "global",
MirroringDeploymentGroup = defaultMirroringDeploymentGroup.Id,
});
var defaultSecurityProfile = new Gcp.NetworkSecurity.SecurityProfile("default", new()
{
Name = "sec-profile",
Parent = "organizations/123456789",
Description = "my description",
Type = "CUSTOM_MIRRORING",
CustomMirroringProfile = new Gcp.NetworkSecurity.Inputs.SecurityProfileCustomMirroringProfileArgs
{
MirroringEndpointGroup = defaultMirroringEndpointGroup.Id,
},
});
var defaultSecurityProfileGroup = new Gcp.NetworkSecurity.SecurityProfileGroup("default", new()
{
Name = "sec-profile-group",
Parent = "organizations/123456789",
Description = "my description",
CustomMirroringProfile = defaultSecurityProfile.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 com.pulumi.gcp.networksecurity.SecurityProfileGroup;
import com.pulumi.gcp.networksecurity.SecurityProfileGroupArgs;
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("network")
.autoCreateSubnetworks(false)
.build());
var defaultMirroringDeploymentGroup = new MirroringDeploymentGroup("defaultMirroringDeploymentGroup", MirroringDeploymentGroupArgs.builder()
.mirroringDeploymentGroupId("deployment-group")
.location("global")
.network(default_.id())
.build());
var defaultMirroringEndpointGroup = new MirroringEndpointGroup("defaultMirroringEndpointGroup", MirroringEndpointGroupArgs.builder()
.mirroringEndpointGroupId("endpoint-group")
.location("global")
.mirroringDeploymentGroup(defaultMirroringDeploymentGroup.id())
.build());
var defaultSecurityProfile = new SecurityProfile("defaultSecurityProfile", SecurityProfileArgs.builder()
.name("sec-profile")
.parent("organizations/123456789")
.description("my description")
.type("CUSTOM_MIRRORING")
.customMirroringProfile(SecurityProfileCustomMirroringProfileArgs.builder()
.mirroringEndpointGroup(defaultMirroringEndpointGroup.id())
.build())
.build());
var defaultSecurityProfileGroup = new SecurityProfileGroup("defaultSecurityProfileGroup", SecurityProfileGroupArgs.builder()
.name("sec-profile-group")
.parent("organizations/123456789")
.description("my description")
.customMirroringProfile(defaultSecurityProfile.id())
.build());
}
}
resources:
default:
type: gcp:compute:Network
properties:
name: network
autoCreateSubnetworks: false
defaultMirroringDeploymentGroup:
type: gcp:networksecurity:MirroringDeploymentGroup
name: default
properties:
mirroringDeploymentGroupId: deployment-group
location: global
network: ${default.id}
defaultMirroringEndpointGroup:
type: gcp:networksecurity:MirroringEndpointGroup
name: default
properties:
mirroringEndpointGroupId: endpoint-group
location: global
mirroringDeploymentGroup: ${defaultMirroringDeploymentGroup.id}
defaultSecurityProfile:
type: gcp:networksecurity:SecurityProfile
name: default
properties:
name: sec-profile
parent: organizations/123456789
description: my description
type: CUSTOM_MIRRORING
customMirroringProfile:
mirroringEndpointGroup: ${defaultMirroringEndpointGroup.id}
defaultSecurityProfileGroup:
type: gcp:networksecurity:SecurityProfileGroup
name: default
properties:
name: sec-profile-group
parent: organizations/123456789
description: my description
customMirroringProfile: ${defaultSecurityProfile.id}
Traffic mirroring requires three components: a VPC network, a MirroringDeploymentGroup that defines where mirroring occurs, and a MirroringEndpointGroup that specifies inspection destinations. The customMirroringProfile property references a SecurityProfile of type CUSTOM_MIRRORING that ties these together. Mirrored traffic flows to your endpoints while original traffic continues unmodified.
Intercept and inspect traffic inline
Applications requiring deep packet inspection deploy intercept profiles to route traffic through inline security appliances before reaching destinations.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const _default = new gcp.compute.Network("default", {
name: "network",
autoCreateSubnetworks: false,
});
const defaultInterceptDeploymentGroup = new gcp.networksecurity.InterceptDeploymentGroup("default", {
interceptDeploymentGroupId: "deployment-group",
location: "global",
network: _default.id,
});
const defaultInterceptEndpointGroup = new gcp.networksecurity.InterceptEndpointGroup("default", {
interceptEndpointGroupId: "endpoint-group",
location: "global",
interceptDeploymentGroup: defaultInterceptDeploymentGroup.id,
});
const defaultSecurityProfile = new gcp.networksecurity.SecurityProfile("default", {
name: "sec-profile",
parent: "organizations/123456789",
description: "my description",
type: "CUSTOM_INTERCEPT",
customInterceptProfile: {
interceptEndpointGroup: defaultInterceptEndpointGroup.id,
},
});
const defaultSecurityProfileGroup = new gcp.networksecurity.SecurityProfileGroup("default", {
name: "sec-profile-group",
parent: "organizations/123456789",
description: "my description",
customInterceptProfile: defaultSecurityProfile.id,
});
import pulumi
import pulumi_gcp as gcp
default = gcp.compute.Network("default",
name="network",
auto_create_subnetworks=False)
default_intercept_deployment_group = gcp.networksecurity.InterceptDeploymentGroup("default",
intercept_deployment_group_id="deployment-group",
location="global",
network=default.id)
default_intercept_endpoint_group = gcp.networksecurity.InterceptEndpointGroup("default",
intercept_endpoint_group_id="endpoint-group",
location="global",
intercept_deployment_group=default_intercept_deployment_group.id)
default_security_profile = gcp.networksecurity.SecurityProfile("default",
name="sec-profile",
parent="organizations/123456789",
description="my description",
type="CUSTOM_INTERCEPT",
custom_intercept_profile={
"intercept_endpoint_group": default_intercept_endpoint_group.id,
})
default_security_profile_group = gcp.networksecurity.SecurityProfileGroup("default",
name="sec-profile-group",
parent="organizations/123456789",
description="my description",
custom_intercept_profile=default_security_profile.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("network"),
AutoCreateSubnetworks: pulumi.Bool(false),
})
if err != nil {
return err
}
defaultInterceptDeploymentGroup, err := networksecurity.NewInterceptDeploymentGroup(ctx, "default", &networksecurity.InterceptDeploymentGroupArgs{
InterceptDeploymentGroupId: pulumi.String("deployment-group"),
Location: pulumi.String("global"),
Network: _default.ID(),
})
if err != nil {
return err
}
defaultInterceptEndpointGroup, err := networksecurity.NewInterceptEndpointGroup(ctx, "default", &networksecurity.InterceptEndpointGroupArgs{
InterceptEndpointGroupId: pulumi.String("endpoint-group"),
Location: pulumi.String("global"),
InterceptDeploymentGroup: defaultInterceptDeploymentGroup.ID(),
})
if err != nil {
return err
}
defaultSecurityProfile, err := networksecurity.NewSecurityProfile(ctx, "default", &networksecurity.SecurityProfileArgs{
Name: pulumi.String("sec-profile"),
Parent: pulumi.String("organizations/123456789"),
Description: pulumi.String("my description"),
Type: pulumi.String("CUSTOM_INTERCEPT"),
CustomInterceptProfile: &networksecurity.SecurityProfileCustomInterceptProfileArgs{
InterceptEndpointGroup: defaultInterceptEndpointGroup.ID(),
},
})
if err != nil {
return err
}
_, err = networksecurity.NewSecurityProfileGroup(ctx, "default", &networksecurity.SecurityProfileGroupArgs{
Name: pulumi.String("sec-profile-group"),
Parent: pulumi.String("organizations/123456789"),
Description: pulumi.String("my description"),
CustomInterceptProfile: defaultSecurityProfile.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 = "network",
AutoCreateSubnetworks = false,
});
var defaultInterceptDeploymentGroup = new Gcp.NetworkSecurity.InterceptDeploymentGroup("default", new()
{
InterceptDeploymentGroupId = "deployment-group",
Location = "global",
Network = @default.Id,
});
var defaultInterceptEndpointGroup = new Gcp.NetworkSecurity.InterceptEndpointGroup("default", new()
{
InterceptEndpointGroupId = "endpoint-group",
Location = "global",
InterceptDeploymentGroup = defaultInterceptDeploymentGroup.Id,
});
var defaultSecurityProfile = new Gcp.NetworkSecurity.SecurityProfile("default", new()
{
Name = "sec-profile",
Parent = "organizations/123456789",
Description = "my description",
Type = "CUSTOM_INTERCEPT",
CustomInterceptProfile = new Gcp.NetworkSecurity.Inputs.SecurityProfileCustomInterceptProfileArgs
{
InterceptEndpointGroup = defaultInterceptEndpointGroup.Id,
},
});
var defaultSecurityProfileGroup = new Gcp.NetworkSecurity.SecurityProfileGroup("default", new()
{
Name = "sec-profile-group",
Parent = "organizations/123456789",
Description = "my description",
CustomInterceptProfile = defaultSecurityProfile.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.InterceptDeploymentGroup;
import com.pulumi.gcp.networksecurity.InterceptDeploymentGroupArgs;
import com.pulumi.gcp.networksecurity.InterceptEndpointGroup;
import com.pulumi.gcp.networksecurity.InterceptEndpointGroupArgs;
import com.pulumi.gcp.networksecurity.SecurityProfile;
import com.pulumi.gcp.networksecurity.SecurityProfileArgs;
import com.pulumi.gcp.networksecurity.inputs.SecurityProfileCustomInterceptProfileArgs;
import com.pulumi.gcp.networksecurity.SecurityProfileGroup;
import com.pulumi.gcp.networksecurity.SecurityProfileGroupArgs;
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("network")
.autoCreateSubnetworks(false)
.build());
var defaultInterceptDeploymentGroup = new InterceptDeploymentGroup("defaultInterceptDeploymentGroup", InterceptDeploymentGroupArgs.builder()
.interceptDeploymentGroupId("deployment-group")
.location("global")
.network(default_.id())
.build());
var defaultInterceptEndpointGroup = new InterceptEndpointGroup("defaultInterceptEndpointGroup", InterceptEndpointGroupArgs.builder()
.interceptEndpointGroupId("endpoint-group")
.location("global")
.interceptDeploymentGroup(defaultInterceptDeploymentGroup.id())
.build());
var defaultSecurityProfile = new SecurityProfile("defaultSecurityProfile", SecurityProfileArgs.builder()
.name("sec-profile")
.parent("organizations/123456789")
.description("my description")
.type("CUSTOM_INTERCEPT")
.customInterceptProfile(SecurityProfileCustomInterceptProfileArgs.builder()
.interceptEndpointGroup(defaultInterceptEndpointGroup.id())
.build())
.build());
var defaultSecurityProfileGroup = new SecurityProfileGroup("defaultSecurityProfileGroup", SecurityProfileGroupArgs.builder()
.name("sec-profile-group")
.parent("organizations/123456789")
.description("my description")
.customInterceptProfile(defaultSecurityProfile.id())
.build());
}
}
resources:
default:
type: gcp:compute:Network
properties:
name: network
autoCreateSubnetworks: false
defaultInterceptDeploymentGroup:
type: gcp:networksecurity:InterceptDeploymentGroup
name: default
properties:
interceptDeploymentGroupId: deployment-group
location: global
network: ${default.id}
defaultInterceptEndpointGroup:
type: gcp:networksecurity:InterceptEndpointGroup
name: default
properties:
interceptEndpointGroupId: endpoint-group
location: global
interceptDeploymentGroup: ${defaultInterceptDeploymentGroup.id}
defaultSecurityProfile:
type: gcp:networksecurity:SecurityProfile
name: default
properties:
name: sec-profile
parent: organizations/123456789
description: my description
type: CUSTOM_INTERCEPT
customInterceptProfile:
interceptEndpointGroup: ${defaultInterceptEndpointGroup.id}
defaultSecurityProfileGroup:
type: gcp:networksecurity:SecurityProfileGroup
name: default
properties:
name: sec-profile-group
parent: organizations/123456789
description: my description
customInterceptProfile: ${defaultSecurityProfile.id}
Intercept deployment works similarly to mirroring but modifies the traffic path. The InterceptDeploymentGroup and InterceptEndpointGroup define where and how traffic is redirected. The customInterceptProfile property references a SecurityProfile of type CUSTOM_INTERCEPT. Unlike mirroring, intercepted traffic must pass through your inspection endpoints before reaching its destination.
Filter traffic by URL patterns
Organizations enforcing acceptable use policies apply URL filtering to allow or block traffic based on domain patterns and URL paths.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const securityProfile = new gcp.networksecurity.SecurityProfile("security_profile", {
name: "sec-profile",
location: "global",
type: "URL_FILTERING",
urlFilteringProfile: {
urlFilters: [{
priority: 1,
filteringAction: "ALLOW",
urls: [
"*example.com",
"*about.example.com",
"*help.example.com",
],
}],
},
parent: "organizations/123456789",
});
const _default = new gcp.networksecurity.SecurityProfileGroup("default", {
name: "sec-profile-group",
parent: "organizations/123456789",
description: "my description",
urlFilteringProfile: securityProfile.id,
labels: {
foo: "bar",
},
});
import pulumi
import pulumi_gcp as gcp
security_profile = gcp.networksecurity.SecurityProfile("security_profile",
name="sec-profile",
location="global",
type="URL_FILTERING",
url_filtering_profile={
"url_filters": [{
"priority": 1,
"filtering_action": "ALLOW",
"urls": [
"*example.com",
"*about.example.com",
"*help.example.com",
],
}],
},
parent="organizations/123456789")
default = gcp.networksecurity.SecurityProfileGroup("default",
name="sec-profile-group",
parent="organizations/123456789",
description="my description",
url_filtering_profile=security_profile.id,
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 {
securityProfile, err := networksecurity.NewSecurityProfile(ctx, "security_profile", &networksecurity.SecurityProfileArgs{
Name: pulumi.String("sec-profile"),
Location: pulumi.String("global"),
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"),
},
},
},
},
Parent: pulumi.String("organizations/123456789"),
})
if err != nil {
return err
}
_, err = networksecurity.NewSecurityProfileGroup(ctx, "default", &networksecurity.SecurityProfileGroupArgs{
Name: pulumi.String("sec-profile-group"),
Parent: pulumi.String("organizations/123456789"),
Description: pulumi.String("my description"),
UrlFilteringProfile: securityProfile.ID(),
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 securityProfile = new Gcp.NetworkSecurity.SecurityProfile("security_profile", new()
{
Name = "sec-profile",
Location = "global",
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",
},
},
},
},
Parent = "organizations/123456789",
});
var @default = new Gcp.NetworkSecurity.SecurityProfileGroup("default", new()
{
Name = "sec-profile-group",
Parent = "organizations/123456789",
Description = "my description",
UrlFilteringProfile = securityProfile.Id,
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 com.pulumi.gcp.networksecurity.SecurityProfileGroup;
import com.pulumi.gcp.networksecurity.SecurityProfileGroupArgs;
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 securityProfile = new SecurityProfile("securityProfile", SecurityProfileArgs.builder()
.name("sec-profile")
.location("global")
.type("URL_FILTERING")
.urlFilteringProfile(SecurityProfileUrlFilteringProfileArgs.builder()
.urlFilters(SecurityProfileUrlFilteringProfileUrlFilterArgs.builder()
.priority(1)
.filteringAction("ALLOW")
.urls(
"*example.com",
"*about.example.com",
"*help.example.com")
.build())
.build())
.parent("organizations/123456789")
.build());
var default_ = new SecurityProfileGroup("default", SecurityProfileGroupArgs.builder()
.name("sec-profile-group")
.parent("organizations/123456789")
.description("my description")
.urlFilteringProfile(securityProfile.id())
.labels(Map.of("foo", "bar"))
.build());
}
}
resources:
default:
type: gcp:networksecurity:SecurityProfileGroup
properties:
name: sec-profile-group
parent: organizations/123456789
description: my description
urlFilteringProfile: ${securityProfile.id}
labels:
foo: bar
securityProfile:
type: gcp:networksecurity:SecurityProfile
name: security_profile
properties:
name: sec-profile
location: global
type: URL_FILTERING
urlFilteringProfile:
urlFilters:
- priority: 1
filteringAction: ALLOW
urls:
- '*example.com'
- '*about.example.com'
- '*help.example.com'
parent: organizations/123456789
The urlFilteringProfile property references a SecurityProfile that defines URL filtering rules. Each rule specifies a priority, filteringAction (ALLOW or BLOCK), and URL patterns using wildcards. Rules are evaluated in priority order; the first match determines the action. This example allows traffic to example.com and specific subdomains.
Beyond these examples
These snippets focus on specific security profile group features: threat prevention and URL filtering, and traffic mirroring and inline inspection. They’re intentionally minimal rather than full network security deployments.
The examples require pre-existing infrastructure such as a GCP organization with valid organization ID, and VPC networks (created in examples but could reference existing networks). They focus on configuring profile groups rather than provisioning complete security architectures.
To keep things focused, common profile group patterns are omitted, including:
- Attaching profile groups to firewall policies
- Regional vs global profile group placement
- Label-based organization and filtering
- Profile group lifecycle (updates, versioning)
These omissions are intentional: the goal is to illustrate how each security profile type is wired, not provide drop-in security modules. See the SecurityProfileGroup resource reference for all available configuration options.
Let's configure GCP Network Security Profile Groups
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Immutability
name, location, and parent properties are immutable. Changing any of these requires recreating the resource.organizations/{organization_id}, as shown in all examples (e.g., organizations/123456789).global if not specified.Security Profiles
You can attach four types of security profiles:
- Threat Prevention - Use
threatPreventionProfile - Custom Mirroring - Use
customMirroringProfile - Custom Intercept - Use
customInterceptProfile - URL Filtering - Use
urlFilteringProfile
Advanced Configurations
Create the following resources in order:
gcp.networksecurity.MirroringDeploymentGroupwith a networkgcp.networksecurity.MirroringEndpointGroupreferencing the deployment groupgcp.networksecurity.SecurityProfilewithcustomMirroringProfilereferencing the endpoint group- Reference the security profile in your profile group’s
customMirroringProfileproperty
Create the following resources in order:
gcp.networksecurity.InterceptDeploymentGroupwith a networkgcp.networksecurity.InterceptEndpointGroupreferencing the deployment groupgcp.networksecurity.SecurityProfilewithcustomInterceptProfilereferencing the endpoint group- Reference the security profile in your profile group’s
customInterceptProfileproperty
Labels & Metadata
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 the effectiveLabels output property.