The gcp:compute/publicDelegatedPrefix:PublicDelegatedPrefix resource, part of the Pulumi GCP provider, defines delegated IP prefixes that carve smaller subnets from your BYOIP (bring your own IP) ranges for regional use. This guide focuses on three capabilities: IPv4 prefix delegation, IPv6 hierarchical delegation with mode configuration, and subnet and forwarding rule allocation patterns.
Delegated prefixes depend on a parent PublicAdvertisedPrefix that represents your onboarded BYOIP range. The examples are intentionally small. Combine them with your own VPC subnets, forwarding rules, and network architecture.
Delegate an IPv4 prefix from an advertised range
Organizations bringing their own IPv4 addresses to GCP start by advertising a prefix, then delegating smaller regional subnets from it.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const advertised = new gcp.compute.PublicAdvertisedPrefix("advertised", {
name: "my-prefix",
description: "description",
dnsVerificationIp: "127.127.0.0",
ipCidrRange: "127.127.0.0/16",
});
const prefixes = new gcp.compute.PublicDelegatedPrefix("prefixes", {
name: "my-prefix",
region: "us-central1",
description: "my description",
ipCidrRange: "127.127.0.0/24",
parentPrefix: advertised.id,
});
import pulumi
import pulumi_gcp as gcp
advertised = gcp.compute.PublicAdvertisedPrefix("advertised",
name="my-prefix",
description="description",
dns_verification_ip="127.127.0.0",
ip_cidr_range="127.127.0.0/16")
prefixes = gcp.compute.PublicDelegatedPrefix("prefixes",
name="my-prefix",
region="us-central1",
description="my description",
ip_cidr_range="127.127.0.0/24",
parent_prefix=advertised.id)
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 {
advertised, err := compute.NewPublicAdvertisedPrefix(ctx, "advertised", &compute.PublicAdvertisedPrefixArgs{
Name: pulumi.String("my-prefix"),
Description: pulumi.String("description"),
DnsVerificationIp: pulumi.String("127.127.0.0"),
IpCidrRange: pulumi.String("127.127.0.0/16"),
})
if err != nil {
return err
}
_, err = compute.NewPublicDelegatedPrefix(ctx, "prefixes", &compute.PublicDelegatedPrefixArgs{
Name: pulumi.String("my-prefix"),
Region: pulumi.String("us-central1"),
Description: pulumi.String("my description"),
IpCidrRange: pulumi.String("127.127.0.0/24"),
ParentPrefix: advertised.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 advertised = new Gcp.Compute.PublicAdvertisedPrefix("advertised", new()
{
Name = "my-prefix",
Description = "description",
DnsVerificationIp = "127.127.0.0",
IpCidrRange = "127.127.0.0/16",
});
var prefixes = new Gcp.Compute.PublicDelegatedPrefix("prefixes", new()
{
Name = "my-prefix",
Region = "us-central1",
Description = "my description",
IpCidrRange = "127.127.0.0/24",
ParentPrefix = advertised.Id,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.PublicAdvertisedPrefix;
import com.pulumi.gcp.compute.PublicAdvertisedPrefixArgs;
import com.pulumi.gcp.compute.PublicDelegatedPrefix;
import com.pulumi.gcp.compute.PublicDelegatedPrefixArgs;
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 advertised = new PublicAdvertisedPrefix("advertised", PublicAdvertisedPrefixArgs.builder()
.name("my-prefix")
.description("description")
.dnsVerificationIp("127.127.0.0")
.ipCidrRange("127.127.0.0/16")
.build());
var prefixes = new PublicDelegatedPrefix("prefixes", PublicDelegatedPrefixArgs.builder()
.name("my-prefix")
.region("us-central1")
.description("my description")
.ipCidrRange("127.127.0.0/24")
.parentPrefix(advertised.id())
.build());
}
}
resources:
advertised:
type: gcp:compute:PublicAdvertisedPrefix
properties:
name: my-prefix
description: description
dnsVerificationIp: 127.127.0.0
ipCidrRange: 127.127.0.0/16
prefixes:
type: gcp:compute:PublicDelegatedPrefix
properties:
name: my-prefix
region: us-central1
description: my description
ipCidrRange: 127.127.0.0/24
parentPrefix: ${advertised.id}
The parentPrefix property links this delegated prefix to your advertised BYOIP range. The ipCidrRange carves out a smaller subnet (here /24 from a /16 parent) that can be used in the specified region. IPv4 prefixes don’t require a mode property; they default to basic delegation behavior.
Create a hierarchy for IPv6 forwarding rules
IPv6 BYOIP requires a two-level delegation hierarchy: a root prefix in DELEGATION mode, then sub-prefixes that allocate addresses for forwarding rules.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const advertised = new gcp.compute.PublicAdvertisedPrefix("advertised", {
name: "ipv6-pap",
description: "description",
dnsVerificationIp: "2001:db8::",
ipCidrRange: "2001:db8::/32",
pdpScope: "REGIONAL",
});
const prefix = new gcp.compute.PublicDelegatedPrefix("prefix", {
name: "ipv6-root-pdp",
description: "test-delegation-mode-pdp",
region: "us-west1",
ipCidrRange: "2001:db8::/40",
parentPrefix: advertised.id,
mode: "DELEGATION",
});
const subprefix = new gcp.compute.PublicDelegatedPrefix("subprefix", {
name: "ipv6-sub-pdp",
description: "test-forwarding-rule-mode-pdp",
region: "us-west1",
ipCidrRange: "2001:db8::/48",
parentPrefix: prefix.id,
allocatablePrefixLength: 64,
mode: "EXTERNAL_IPV6_FORWARDING_RULE_CREATION",
});
import pulumi
import pulumi_gcp as gcp
advertised = gcp.compute.PublicAdvertisedPrefix("advertised",
name="ipv6-pap",
description="description",
dns_verification_ip="2001:db8::",
ip_cidr_range="2001:db8::/32",
pdp_scope="REGIONAL")
prefix = gcp.compute.PublicDelegatedPrefix("prefix",
name="ipv6-root-pdp",
description="test-delegation-mode-pdp",
region="us-west1",
ip_cidr_range="2001:db8::/40",
parent_prefix=advertised.id,
mode="DELEGATION")
subprefix = gcp.compute.PublicDelegatedPrefix("subprefix",
name="ipv6-sub-pdp",
description="test-forwarding-rule-mode-pdp",
region="us-west1",
ip_cidr_range="2001:db8::/48",
parent_prefix=prefix.id,
allocatable_prefix_length=64,
mode="EXTERNAL_IPV6_FORWARDING_RULE_CREATION")
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 {
advertised, err := compute.NewPublicAdvertisedPrefix(ctx, "advertised", &compute.PublicAdvertisedPrefixArgs{
Name: pulumi.String("ipv6-pap"),
Description: pulumi.String("description"),
DnsVerificationIp: pulumi.String("2001:db8::"),
IpCidrRange: pulumi.String("2001:db8::/32"),
PdpScope: pulumi.String("REGIONAL"),
})
if err != nil {
return err
}
prefix, err := compute.NewPublicDelegatedPrefix(ctx, "prefix", &compute.PublicDelegatedPrefixArgs{
Name: pulumi.String("ipv6-root-pdp"),
Description: pulumi.String("test-delegation-mode-pdp"),
Region: pulumi.String("us-west1"),
IpCidrRange: pulumi.String("2001:db8::/40"),
ParentPrefix: advertised.ID(),
Mode: pulumi.String("DELEGATION"),
})
if err != nil {
return err
}
_, err = compute.NewPublicDelegatedPrefix(ctx, "subprefix", &compute.PublicDelegatedPrefixArgs{
Name: pulumi.String("ipv6-sub-pdp"),
Description: pulumi.String("test-forwarding-rule-mode-pdp"),
Region: pulumi.String("us-west1"),
IpCidrRange: pulumi.String("2001:db8::/48"),
ParentPrefix: prefix.ID(),
AllocatablePrefixLength: pulumi.Int(64),
Mode: pulumi.String("EXTERNAL_IPV6_FORWARDING_RULE_CREATION"),
})
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 advertised = new Gcp.Compute.PublicAdvertisedPrefix("advertised", new()
{
Name = "ipv6-pap",
Description = "description",
DnsVerificationIp = "2001:db8::",
IpCidrRange = "2001:db8::/32",
PdpScope = "REGIONAL",
});
var prefix = new Gcp.Compute.PublicDelegatedPrefix("prefix", new()
{
Name = "ipv6-root-pdp",
Description = "test-delegation-mode-pdp",
Region = "us-west1",
IpCidrRange = "2001:db8::/40",
ParentPrefix = advertised.Id,
Mode = "DELEGATION",
});
var subprefix = new Gcp.Compute.PublicDelegatedPrefix("subprefix", new()
{
Name = "ipv6-sub-pdp",
Description = "test-forwarding-rule-mode-pdp",
Region = "us-west1",
IpCidrRange = "2001:db8::/48",
ParentPrefix = prefix.Id,
AllocatablePrefixLength = 64,
Mode = "EXTERNAL_IPV6_FORWARDING_RULE_CREATION",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.PublicAdvertisedPrefix;
import com.pulumi.gcp.compute.PublicAdvertisedPrefixArgs;
import com.pulumi.gcp.compute.PublicDelegatedPrefix;
import com.pulumi.gcp.compute.PublicDelegatedPrefixArgs;
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 advertised = new PublicAdvertisedPrefix("advertised", PublicAdvertisedPrefixArgs.builder()
.name("ipv6-pap")
.description("description")
.dnsVerificationIp("2001:db8::")
.ipCidrRange("2001:db8::/32")
.pdpScope("REGIONAL")
.build());
var prefix = new PublicDelegatedPrefix("prefix", PublicDelegatedPrefixArgs.builder()
.name("ipv6-root-pdp")
.description("test-delegation-mode-pdp")
.region("us-west1")
.ipCidrRange("2001:db8::/40")
.parentPrefix(advertised.id())
.mode("DELEGATION")
.build());
var subprefix = new PublicDelegatedPrefix("subprefix", PublicDelegatedPrefixArgs.builder()
.name("ipv6-sub-pdp")
.description("test-forwarding-rule-mode-pdp")
.region("us-west1")
.ipCidrRange("2001:db8::/48")
.parentPrefix(prefix.id())
.allocatablePrefixLength(64)
.mode("EXTERNAL_IPV6_FORWARDING_RULE_CREATION")
.build());
}
}
resources:
advertised:
type: gcp:compute:PublicAdvertisedPrefix
properties:
name: ipv6-pap
description: description
dnsVerificationIp: '2001:db8::'
ipCidrRange: 2001:db8::/32
pdpScope: REGIONAL
prefix:
type: gcp:compute:PublicDelegatedPrefix
properties:
name: ipv6-root-pdp
description: test-delegation-mode-pdp
region: us-west1
ipCidrRange: 2001:db8::/40
parentPrefix: ${advertised.id}
mode: DELEGATION
subprefix:
type: gcp:compute:PublicDelegatedPrefix
properties:
name: ipv6-sub-pdp
description: test-forwarding-rule-mode-pdp
region: us-west1
ipCidrRange: 2001:db8::/48
parentPrefix: ${prefix.id}
allocatablePrefixLength: 64
mode: EXTERNAL_IPV6_FORWARDING_RULE_CREATION
The mode property controls how addresses are allocated. The root prefix uses DELEGATION mode to enable further subdivision. The sub-prefix uses EXTERNAL_IPV6_FORWARDING_RULE_CREATION mode, which allows load balancers and forwarding rules to claim addresses. The allocatablePrefixLength (64) sets the size of individual address allocations.
Allocate IPv6 ranges for VPC subnets
VPC subnets can use IPv6 addresses from your BYOIP range when you configure a sub-prefix in subnet creation mode.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const advertised = new gcp.compute.PublicAdvertisedPrefix("advertised", {
name: "ipv6-pap",
description: "description",
dnsVerificationIp: "2001:db8::",
ipCidrRange: "2001:db8::/32",
pdpScope: "REGIONAL",
});
const prefix = new gcp.compute.PublicDelegatedPrefix("prefix", {
name: "ipv6-root-pdp",
description: "test-delegation-mode-pdp",
region: "us-east1",
ipCidrRange: "2001:db8::/40",
parentPrefix: advertised.id,
mode: "DELEGATION",
});
const subprefix = new gcp.compute.PublicDelegatedPrefix("subprefix", {
name: "ipv6-sub-pdp",
description: "test-subnet-mode-pdp",
region: "us-east1",
ipCidrRange: "2001:db8::/48",
parentPrefix: prefix.id,
mode: "EXTERNAL_IPV6_SUBNETWORK_CREATION",
});
import pulumi
import pulumi_gcp as gcp
advertised = gcp.compute.PublicAdvertisedPrefix("advertised",
name="ipv6-pap",
description="description",
dns_verification_ip="2001:db8::",
ip_cidr_range="2001:db8::/32",
pdp_scope="REGIONAL")
prefix = gcp.compute.PublicDelegatedPrefix("prefix",
name="ipv6-root-pdp",
description="test-delegation-mode-pdp",
region="us-east1",
ip_cidr_range="2001:db8::/40",
parent_prefix=advertised.id,
mode="DELEGATION")
subprefix = gcp.compute.PublicDelegatedPrefix("subprefix",
name="ipv6-sub-pdp",
description="test-subnet-mode-pdp",
region="us-east1",
ip_cidr_range="2001:db8::/48",
parent_prefix=prefix.id,
mode="EXTERNAL_IPV6_SUBNETWORK_CREATION")
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 {
advertised, err := compute.NewPublicAdvertisedPrefix(ctx, "advertised", &compute.PublicAdvertisedPrefixArgs{
Name: pulumi.String("ipv6-pap"),
Description: pulumi.String("description"),
DnsVerificationIp: pulumi.String("2001:db8::"),
IpCidrRange: pulumi.String("2001:db8::/32"),
PdpScope: pulumi.String("REGIONAL"),
})
if err != nil {
return err
}
prefix, err := compute.NewPublicDelegatedPrefix(ctx, "prefix", &compute.PublicDelegatedPrefixArgs{
Name: pulumi.String("ipv6-root-pdp"),
Description: pulumi.String("test-delegation-mode-pdp"),
Region: pulumi.String("us-east1"),
IpCidrRange: pulumi.String("2001:db8::/40"),
ParentPrefix: advertised.ID(),
Mode: pulumi.String("DELEGATION"),
})
if err != nil {
return err
}
_, err = compute.NewPublicDelegatedPrefix(ctx, "subprefix", &compute.PublicDelegatedPrefixArgs{
Name: pulumi.String("ipv6-sub-pdp"),
Description: pulumi.String("test-subnet-mode-pdp"),
Region: pulumi.String("us-east1"),
IpCidrRange: pulumi.String("2001:db8::/48"),
ParentPrefix: prefix.ID(),
Mode: pulumi.String("EXTERNAL_IPV6_SUBNETWORK_CREATION"),
})
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 advertised = new Gcp.Compute.PublicAdvertisedPrefix("advertised", new()
{
Name = "ipv6-pap",
Description = "description",
DnsVerificationIp = "2001:db8::",
IpCidrRange = "2001:db8::/32",
PdpScope = "REGIONAL",
});
var prefix = new Gcp.Compute.PublicDelegatedPrefix("prefix", new()
{
Name = "ipv6-root-pdp",
Description = "test-delegation-mode-pdp",
Region = "us-east1",
IpCidrRange = "2001:db8::/40",
ParentPrefix = advertised.Id,
Mode = "DELEGATION",
});
var subprefix = new Gcp.Compute.PublicDelegatedPrefix("subprefix", new()
{
Name = "ipv6-sub-pdp",
Description = "test-subnet-mode-pdp",
Region = "us-east1",
IpCidrRange = "2001:db8::/48",
ParentPrefix = prefix.Id,
Mode = "EXTERNAL_IPV6_SUBNETWORK_CREATION",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.PublicAdvertisedPrefix;
import com.pulumi.gcp.compute.PublicAdvertisedPrefixArgs;
import com.pulumi.gcp.compute.PublicDelegatedPrefix;
import com.pulumi.gcp.compute.PublicDelegatedPrefixArgs;
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 advertised = new PublicAdvertisedPrefix("advertised", PublicAdvertisedPrefixArgs.builder()
.name("ipv6-pap")
.description("description")
.dnsVerificationIp("2001:db8::")
.ipCidrRange("2001:db8::/32")
.pdpScope("REGIONAL")
.build());
var prefix = new PublicDelegatedPrefix("prefix", PublicDelegatedPrefixArgs.builder()
.name("ipv6-root-pdp")
.description("test-delegation-mode-pdp")
.region("us-east1")
.ipCidrRange("2001:db8::/40")
.parentPrefix(advertised.id())
.mode("DELEGATION")
.build());
var subprefix = new PublicDelegatedPrefix("subprefix", PublicDelegatedPrefixArgs.builder()
.name("ipv6-sub-pdp")
.description("test-subnet-mode-pdp")
.region("us-east1")
.ipCidrRange("2001:db8::/48")
.parentPrefix(prefix.id())
.mode("EXTERNAL_IPV6_SUBNETWORK_CREATION")
.build());
}
}
resources:
advertised:
type: gcp:compute:PublicAdvertisedPrefix
properties:
name: ipv6-pap
description: description
dnsVerificationIp: '2001:db8::'
ipCidrRange: 2001:db8::/32
pdpScope: REGIONAL
prefix:
type: gcp:compute:PublicDelegatedPrefix
properties:
name: ipv6-root-pdp
description: test-delegation-mode-pdp
region: us-east1
ipCidrRange: 2001:db8::/40
parentPrefix: ${advertised.id}
mode: DELEGATION
subprefix:
type: gcp:compute:PublicDelegatedPrefix
properties:
name: ipv6-sub-pdp
description: test-subnet-mode-pdp
region: us-east1
ipCidrRange: 2001:db8::/48
parentPrefix: ${prefix.id}
mode: EXTERNAL_IPV6_SUBNETWORK_CREATION
This configuration mirrors the forwarding rule example but uses EXTERNAL_IPV6_SUBNETWORK_CREATION mode instead. This mode allows VPC subnets to claim IPv6 ranges from the delegated prefix. The two-level hierarchy (root in DELEGATION mode, sub-prefix in subnet mode) is required for IPv6.
Configure internal IPv6 ranges for private subnets
Some deployments need IPv6 addresses that remain internal to Google Cloud without internet announcement.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const advertised = new gcp.compute.PublicAdvertisedPrefix("advertised", {
name: "ipv6-pap",
description: "description",
ipCidrRange: "2001:db8::/32",
pdpScope: "REGIONAL",
ipv6AccessType: "INTERNAL",
});
const prefix = new gcp.compute.PublicDelegatedPrefix("prefix", {
name: "ipv6-root-pdp",
description: "test-delegation-mode-pdp",
region: "us-east1",
ipCidrRange: "2001:db8::/40",
parentPrefix: advertised.id,
mode: "DELEGATION",
});
const subprefix = new gcp.compute.PublicDelegatedPrefix("subprefix", {
name: "ipv6-sub-pdp",
description: "test-subnet-mode-pdp",
region: "us-east1",
ipCidrRange: "2001:db8::/48",
parentPrefix: prefix.id,
mode: "INTERNAL_IPV6_SUBNETWORK_CREATION",
});
import pulumi
import pulumi_gcp as gcp
advertised = gcp.compute.PublicAdvertisedPrefix("advertised",
name="ipv6-pap",
description="description",
ip_cidr_range="2001:db8::/32",
pdp_scope="REGIONAL",
ipv6_access_type="INTERNAL")
prefix = gcp.compute.PublicDelegatedPrefix("prefix",
name="ipv6-root-pdp",
description="test-delegation-mode-pdp",
region="us-east1",
ip_cidr_range="2001:db8::/40",
parent_prefix=advertised.id,
mode="DELEGATION")
subprefix = gcp.compute.PublicDelegatedPrefix("subprefix",
name="ipv6-sub-pdp",
description="test-subnet-mode-pdp",
region="us-east1",
ip_cidr_range="2001:db8::/48",
parent_prefix=prefix.id,
mode="INTERNAL_IPV6_SUBNETWORK_CREATION")
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 {
advertised, err := compute.NewPublicAdvertisedPrefix(ctx, "advertised", &compute.PublicAdvertisedPrefixArgs{
Name: pulumi.String("ipv6-pap"),
Description: pulumi.String("description"),
IpCidrRange: pulumi.String("2001:db8::/32"),
PdpScope: pulumi.String("REGIONAL"),
Ipv6AccessType: pulumi.String("INTERNAL"),
})
if err != nil {
return err
}
prefix, err := compute.NewPublicDelegatedPrefix(ctx, "prefix", &compute.PublicDelegatedPrefixArgs{
Name: pulumi.String("ipv6-root-pdp"),
Description: pulumi.String("test-delegation-mode-pdp"),
Region: pulumi.String("us-east1"),
IpCidrRange: pulumi.String("2001:db8::/40"),
ParentPrefix: advertised.ID(),
Mode: pulumi.String("DELEGATION"),
})
if err != nil {
return err
}
_, err = compute.NewPublicDelegatedPrefix(ctx, "subprefix", &compute.PublicDelegatedPrefixArgs{
Name: pulumi.String("ipv6-sub-pdp"),
Description: pulumi.String("test-subnet-mode-pdp"),
Region: pulumi.String("us-east1"),
IpCidrRange: pulumi.String("2001:db8::/48"),
ParentPrefix: prefix.ID(),
Mode: pulumi.String("INTERNAL_IPV6_SUBNETWORK_CREATION"),
})
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 advertised = new Gcp.Compute.PublicAdvertisedPrefix("advertised", new()
{
Name = "ipv6-pap",
Description = "description",
IpCidrRange = "2001:db8::/32",
PdpScope = "REGIONAL",
Ipv6AccessType = "INTERNAL",
});
var prefix = new Gcp.Compute.PublicDelegatedPrefix("prefix", new()
{
Name = "ipv6-root-pdp",
Description = "test-delegation-mode-pdp",
Region = "us-east1",
IpCidrRange = "2001:db8::/40",
ParentPrefix = advertised.Id,
Mode = "DELEGATION",
});
var subprefix = new Gcp.Compute.PublicDelegatedPrefix("subprefix", new()
{
Name = "ipv6-sub-pdp",
Description = "test-subnet-mode-pdp",
Region = "us-east1",
IpCidrRange = "2001:db8::/48",
ParentPrefix = prefix.Id,
Mode = "INTERNAL_IPV6_SUBNETWORK_CREATION",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.PublicAdvertisedPrefix;
import com.pulumi.gcp.compute.PublicAdvertisedPrefixArgs;
import com.pulumi.gcp.compute.PublicDelegatedPrefix;
import com.pulumi.gcp.compute.PublicDelegatedPrefixArgs;
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 advertised = new PublicAdvertisedPrefix("advertised", PublicAdvertisedPrefixArgs.builder()
.name("ipv6-pap")
.description("description")
.ipCidrRange("2001:db8::/32")
.pdpScope("REGIONAL")
.ipv6AccessType("INTERNAL")
.build());
var prefix = new PublicDelegatedPrefix("prefix", PublicDelegatedPrefixArgs.builder()
.name("ipv6-root-pdp")
.description("test-delegation-mode-pdp")
.region("us-east1")
.ipCidrRange("2001:db8::/40")
.parentPrefix(advertised.id())
.mode("DELEGATION")
.build());
var subprefix = new PublicDelegatedPrefix("subprefix", PublicDelegatedPrefixArgs.builder()
.name("ipv6-sub-pdp")
.description("test-subnet-mode-pdp")
.region("us-east1")
.ipCidrRange("2001:db8::/48")
.parentPrefix(prefix.id())
.mode("INTERNAL_IPV6_SUBNETWORK_CREATION")
.build());
}
}
resources:
advertised:
type: gcp:compute:PublicAdvertisedPrefix
properties:
name: ipv6-pap
description: description
ipCidrRange: 2001:db8::/32
pdpScope: REGIONAL
ipv6AccessType: INTERNAL
prefix:
type: gcp:compute:PublicDelegatedPrefix
properties:
name: ipv6-root-pdp
description: test-delegation-mode-pdp
region: us-east1
ipCidrRange: 2001:db8::/40
parentPrefix: ${advertised.id}
mode: DELEGATION
subprefix:
type: gcp:compute:PublicDelegatedPrefix
properties:
name: ipv6-sub-pdp
description: test-subnet-mode-pdp
region: us-east1
ipCidrRange: 2001:db8::/48
parentPrefix: ${prefix.id}
mode: INTERNAL_IPV6_SUBNETWORK_CREATION
The INTERNAL_IPV6_SUBNETWORK_CREATION mode creates prefixes for internal-only subnets. The parent PublicAdvertisedPrefix must have ipv6AccessType set to INTERNAL, which prevents the range from being announced to the internet. The ipv6AccessType output property is inherited from the parent and confirms the access level.
Beyond these examples
These snippets focus on specific prefix delegation features: IPv4 and IPv6 prefix delegation, mode configuration for different allocation patterns, and hierarchical prefix relationships. They’re intentionally minimal rather than full network deployments.
The examples require pre-existing infrastructure such as PublicAdvertisedPrefix resources (BYOIP onboarding), DNS verification for IPv4 ranges, and regional scope configuration for IPv6. They focus on prefix configuration rather than the complete BYOIP onboarding process.
To keep things focused, common prefix patterns are omitted, including:
- Live migration configuration (isLiveMigration)
- Actual subnet or forwarding rule creation using delegated prefixes
- Multi-region prefix distribution
- Prefix lifecycle management and deletion
These omissions are intentional: the goal is to illustrate how prefix delegation is wired, not provide drop-in BYOIP modules. See the PublicDelegatedPrefix resource reference for all available configuration options.
Let's configure GCP Public Delegated Prefixes
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Immutability
ipCidrRange, name, parentPrefix, region, mode, description, allocatablePrefixLength, and isLiveMigration. Changing any of these requires destroying and recreating the resource.Modes & Use Cases
There are four modes for IPv6 prefixes:
- DELEGATION - For creating sub-prefixes that can be further delegated
- EXTERNAL_IPV6_FORWARDING_RULE_CREATION - For creating forwarding rules
- EXTERNAL_IPV6_SUBNETWORK_CREATION - For creating external IPv6 subnets
- INTERNAL_IPV6_SUBNETWORK_CREATION - For creating internal IPv6 subnets
Prefix Hierarchy & Relationships
PublicAdvertisedPrefix first, then create a root PublicDelegatedPrefix with mode set to DELEGATION referencing the advertised prefix, then create sub-prefixes referencing the root prefix with appropriate modes.parentPrefix can be either a PublicAdvertisedPrefix or another PublicDelegatedPrefix, allowing you to create hierarchical prefix structures.IPv6-Specific Features
allocatablePrefixLength only for IPv6 prefixes in EXTERNAL_IPV6_FORWARDING_RULE_CREATION mode. It cannot be set for DELEGATION mode or IPv4 prefixes (IPv4 always defaults to 32).ipv6AccessType is an output-only field inherited from the parent prefix. EXTERNAL means the prefix is announced to the internet, while INTERNAL means it’s used privately within Google Cloud. Set this on the parent PublicAdvertisedPrefix.mode or allocatablePrefixLength properties (allocatablePrefixLength always defaults to 32 for IPv4).Using a different cloud?
Explore networking guides for other cloud providers: