The gcp:compute/targetInstance:TargetInstance resource, part of the Pulumi GCP provider, defines a target instance endpoint that terminates protocol-forwarded traffic at a single VM. This guide focuses on three capabilities: basic target instance creation, custom network selection, and Cloud Armor Network security policy attachment.
Target instances reference existing Compute Engine VMs and optionally specify networks or security policies. The examples are intentionally small. Combine them with forwarding rules and your own VM infrastructure.
Route traffic to a single VM instance
Protocol forwarding starts by creating a target instance that points to a VM, establishing an endpoint for forwarding rules.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const vmimage = gcp.compute.getImage({
family: "debian-11",
project: "debian-cloud",
});
const target_vm = new gcp.compute.Instance("target-vm", {
name: "target-vm",
machineType: "e2-medium",
zone: "us-central1-a",
bootDisk: {
initializeParams: {
image: vmimage.then(vmimage => vmimage.selfLink),
},
},
networkInterfaces: [{
network: "default",
}],
});
const _default = new gcp.compute.TargetInstance("default", {
name: "target",
instance: target_vm.id,
});
import pulumi
import pulumi_gcp as gcp
vmimage = gcp.compute.get_image(family="debian-11",
project="debian-cloud")
target_vm = gcp.compute.Instance("target-vm",
name="target-vm",
machine_type="e2-medium",
zone="us-central1-a",
boot_disk={
"initialize_params": {
"image": vmimage.self_link,
},
},
network_interfaces=[{
"network": "default",
}])
default = gcp.compute.TargetInstance("default",
name="target",
instance=target_vm.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 {
vmimage, err := compute.LookupImage(ctx, &compute.LookupImageArgs{
Family: pulumi.StringRef("debian-11"),
Project: pulumi.StringRef("debian-cloud"),
}, nil)
if err != nil {
return err
}
target_vm, err := compute.NewInstance(ctx, "target-vm", &compute.InstanceArgs{
Name: pulumi.String("target-vm"),
MachineType: pulumi.String("e2-medium"),
Zone: pulumi.String("us-central1-a"),
BootDisk: &compute.InstanceBootDiskArgs{
InitializeParams: &compute.InstanceBootDiskInitializeParamsArgs{
Image: pulumi.String(vmimage.SelfLink),
},
},
NetworkInterfaces: compute.InstanceNetworkInterfaceArray{
&compute.InstanceNetworkInterfaceArgs{
Network: pulumi.String("default"),
},
},
})
if err != nil {
return err
}
_, err = compute.NewTargetInstance(ctx, "default", &compute.TargetInstanceArgs{
Name: pulumi.String("target"),
Instance: target_vm.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 vmimage = Gcp.Compute.GetImage.Invoke(new()
{
Family = "debian-11",
Project = "debian-cloud",
});
var target_vm = new Gcp.Compute.Instance("target-vm", new()
{
Name = "target-vm",
MachineType = "e2-medium",
Zone = "us-central1-a",
BootDisk = new Gcp.Compute.Inputs.InstanceBootDiskArgs
{
InitializeParams = new Gcp.Compute.Inputs.InstanceBootDiskInitializeParamsArgs
{
Image = vmimage.Apply(getImageResult => getImageResult.SelfLink),
},
},
NetworkInterfaces = new[]
{
new Gcp.Compute.Inputs.InstanceNetworkInterfaceArgs
{
Network = "default",
},
},
});
var @default = new Gcp.Compute.TargetInstance("default", new()
{
Name = "target",
Instance = target_vm.Id,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.ComputeFunctions;
import com.pulumi.gcp.compute.inputs.GetImageArgs;
import com.pulumi.gcp.compute.Instance;
import com.pulumi.gcp.compute.InstanceArgs;
import com.pulumi.gcp.compute.inputs.InstanceBootDiskArgs;
import com.pulumi.gcp.compute.inputs.InstanceBootDiskInitializeParamsArgs;
import com.pulumi.gcp.compute.inputs.InstanceNetworkInterfaceArgs;
import com.pulumi.gcp.compute.TargetInstance;
import com.pulumi.gcp.compute.TargetInstanceArgs;
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) {
final var vmimage = ComputeFunctions.getImage(GetImageArgs.builder()
.family("debian-11")
.project("debian-cloud")
.build());
var target_vm = new Instance("target-vm", InstanceArgs.builder()
.name("target-vm")
.machineType("e2-medium")
.zone("us-central1-a")
.bootDisk(InstanceBootDiskArgs.builder()
.initializeParams(InstanceBootDiskInitializeParamsArgs.builder()
.image(vmimage.selfLink())
.build())
.build())
.networkInterfaces(InstanceNetworkInterfaceArgs.builder()
.network("default")
.build())
.build());
var default_ = new TargetInstance("default", TargetInstanceArgs.builder()
.name("target")
.instance(target_vm.id())
.build());
}
}
resources:
default:
type: gcp:compute:TargetInstance
properties:
name: target
instance: ${["target-vm"].id}
target-vm:
type: gcp:compute:Instance
properties:
name: target-vm
machineType: e2-medium
zone: us-central1-a
bootDisk:
initializeParams:
image: ${vmimage.selfLink}
networkInterfaces:
- network: default
variables:
vmimage:
fn::invoke:
function: gcp:compute:getImage
arguments:
family: debian-11
project: debian-cloud
The instance property references the VM that receives traffic. The target instance acts as a stable endpoint; forwarding rules send packets here, and the target instance routes them to the specified VM. Without an explicit network property, traffic uses the VM’s default network interface.
Specify a custom network for forwarding
When VMs have multiple network interfaces, you can control which network receives forwarded traffic.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const target_vm = gcp.compute.getNetwork({
name: "default",
});
const vmimage = gcp.compute.getImage({
family: "debian-12",
project: "debian-cloud",
});
const target_vmInstance = new gcp.compute.Instance("target-vm", {
name: "custom-network-target-vm",
machineType: "e2-medium",
zone: "us-central1-a",
bootDisk: {
initializeParams: {
image: vmimage.then(vmimage => vmimage.selfLink),
},
},
networkInterfaces: [{
network: "default",
}],
});
const customNetwork = new gcp.compute.TargetInstance("custom_network", {
name: "custom-network",
instance: target_vmInstance.id,
network: target_vm.then(target_vm => target_vm.selfLink),
});
import pulumi
import pulumi_gcp as gcp
target_vm = gcp.compute.get_network(name="default")
vmimage = gcp.compute.get_image(family="debian-12",
project="debian-cloud")
target_vm_instance = gcp.compute.Instance("target-vm",
name="custom-network-target-vm",
machine_type="e2-medium",
zone="us-central1-a",
boot_disk={
"initialize_params": {
"image": vmimage.self_link,
},
},
network_interfaces=[{
"network": "default",
}])
custom_network = gcp.compute.TargetInstance("custom_network",
name="custom-network",
instance=target_vm_instance.id,
network=target_vm.self_link)
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 {
target_vm, err := compute.LookupNetwork(ctx, &compute.LookupNetworkArgs{
Name: "default",
}, nil)
if err != nil {
return err
}
vmimage, err := compute.LookupImage(ctx, &compute.LookupImageArgs{
Family: pulumi.StringRef("debian-12"),
Project: pulumi.StringRef("debian-cloud"),
}, nil)
if err != nil {
return err
}
target_vmInstance, err := compute.NewInstance(ctx, "target-vm", &compute.InstanceArgs{
Name: pulumi.String("custom-network-target-vm"),
MachineType: pulumi.String("e2-medium"),
Zone: pulumi.String("us-central1-a"),
BootDisk: &compute.InstanceBootDiskArgs{
InitializeParams: &compute.InstanceBootDiskInitializeParamsArgs{
Image: pulumi.String(vmimage.SelfLink),
},
},
NetworkInterfaces: compute.InstanceNetworkInterfaceArray{
&compute.InstanceNetworkInterfaceArgs{
Network: pulumi.String("default"),
},
},
})
if err != nil {
return err
}
_, err = compute.NewTargetInstance(ctx, "custom_network", &compute.TargetInstanceArgs{
Name: pulumi.String("custom-network"),
Instance: target_vmInstance.ID(),
Network: pulumi.String(target_vm.SelfLink),
})
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 target_vm = Gcp.Compute.GetNetwork.Invoke(new()
{
Name = "default",
});
var vmimage = Gcp.Compute.GetImage.Invoke(new()
{
Family = "debian-12",
Project = "debian-cloud",
});
var target_vmInstance = new Gcp.Compute.Instance("target-vm", new()
{
Name = "custom-network-target-vm",
MachineType = "e2-medium",
Zone = "us-central1-a",
BootDisk = new Gcp.Compute.Inputs.InstanceBootDiskArgs
{
InitializeParams = new Gcp.Compute.Inputs.InstanceBootDiskInitializeParamsArgs
{
Image = vmimage.Apply(getImageResult => getImageResult.SelfLink),
},
},
NetworkInterfaces = new[]
{
new Gcp.Compute.Inputs.InstanceNetworkInterfaceArgs
{
Network = "default",
},
},
});
var customNetwork = new Gcp.Compute.TargetInstance("custom_network", new()
{
Name = "custom-network",
Instance = target_vmInstance.Id,
Network = target_vm.Apply(target_vm => target_vm.Apply(getNetworkResult => getNetworkResult.SelfLink)),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.ComputeFunctions;
import com.pulumi.gcp.compute.inputs.GetNetworkArgs;
import com.pulumi.gcp.compute.inputs.GetImageArgs;
import com.pulumi.gcp.compute.Instance;
import com.pulumi.gcp.compute.InstanceArgs;
import com.pulumi.gcp.compute.inputs.InstanceBootDiskArgs;
import com.pulumi.gcp.compute.inputs.InstanceBootDiskInitializeParamsArgs;
import com.pulumi.gcp.compute.inputs.InstanceNetworkInterfaceArgs;
import com.pulumi.gcp.compute.TargetInstance;
import com.pulumi.gcp.compute.TargetInstanceArgs;
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) {
final var target-vm = ComputeFunctions.getNetwork(GetNetworkArgs.builder()
.name("default")
.build());
final var vmimage = ComputeFunctions.getImage(GetImageArgs.builder()
.family("debian-12")
.project("debian-cloud")
.build());
var target_vmInstance = new Instance("target-vmInstance", InstanceArgs.builder()
.name("custom-network-target-vm")
.machineType("e2-medium")
.zone("us-central1-a")
.bootDisk(InstanceBootDiskArgs.builder()
.initializeParams(InstanceBootDiskInitializeParamsArgs.builder()
.image(vmimage.selfLink())
.build())
.build())
.networkInterfaces(InstanceNetworkInterfaceArgs.builder()
.network("default")
.build())
.build());
var customNetwork = new TargetInstance("customNetwork", TargetInstanceArgs.builder()
.name("custom-network")
.instance(target_vmInstance.id())
.network(target_vm.selfLink())
.build());
}
}
resources:
customNetwork:
type: gcp:compute:TargetInstance
name: custom_network
properties:
name: custom-network
instance: ${["target-vmInstance"].id}
network: ${["target-vm"].selfLink}
target-vmInstance:
type: gcp:compute:Instance
name: target-vm
properties:
name: custom-network-target-vm
machineType: e2-medium
zone: us-central1-a
bootDisk:
initializeParams:
image: ${vmimage.selfLink}
networkInterfaces:
- network: default
variables:
target-vm:
fn::invoke:
function: gcp:compute:getNetwork
arguments:
name: default
vmimage:
fn::invoke:
function: gcp:compute:getImage
arguments:
family: debian-12
project: debian-cloud
The network property overrides the default behavior, directing traffic through a specific VPC. This matters when your VM spans multiple networks and you need precise control over routing paths.
Attach DDoS protection with security policies
Production deployments often add Cloud Armor Network security policies to protect against DDoS attacks.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const _default = new gcp.compute.Network("default", {
name: "custom-default-network",
autoCreateSubnetworks: false,
routingMode: "REGIONAL",
});
const defaultSubnetwork = new gcp.compute.Subnetwork("default", {
name: "custom-default-subnet",
ipCidrRange: "10.1.2.0/24",
network: _default.id,
privateIpv6GoogleAccess: "DISABLE_GOOGLE_ACCESS",
purpose: "PRIVATE",
region: "southamerica-west1",
stackType: "IPV4_ONLY",
});
const vmimage = gcp.compute.getImage({
family: "debian-11",
project: "debian-cloud",
});
const target_vm = new gcp.compute.Instance("target-vm", {
networkInterfaces: [{
accessConfigs: [{}],
network: _default.selfLink,
subnetwork: defaultSubnetwork.selfLink,
}],
name: "target-vm",
machineType: "e2-medium",
zone: "southamerica-west1-a",
bootDisk: {
initializeParams: {
image: vmimage.then(vmimage => vmimage.selfLink),
},
},
});
const policyddosprotection = new gcp.compute.RegionSecurityPolicy("policyddosprotection", {
region: "southamerica-west1",
name: "tf-test-policyddos_34962",
description: "ddos protection security policy to set target instance",
type: "CLOUD_ARMOR_NETWORK",
ddosProtectionConfig: {
ddosProtection: "ADVANCED_PREVIEW",
},
});
const edgeSecService = new gcp.compute.NetworkEdgeSecurityService("edge_sec_service", {
region: "southamerica-west1",
name: "tf-test-edgesec_74000",
securityPolicy: policyddosprotection.selfLink,
});
const regionsecuritypolicy = new gcp.compute.RegionSecurityPolicy("regionsecuritypolicy", {
name: "region-secpolicy",
region: "southamerica-west1",
description: "basic security policy for target instance",
type: "CLOUD_ARMOR_NETWORK",
}, {
dependsOn: [edgeSecService],
});
const defaultTargetInstance = new gcp.compute.TargetInstance("default", {
name: "target-instance",
zone: "southamerica-west1-a",
instance: target_vm.id,
securityPolicy: regionsecuritypolicy.selfLink,
});
import pulumi
import pulumi_gcp as gcp
default = gcp.compute.Network("default",
name="custom-default-network",
auto_create_subnetworks=False,
routing_mode="REGIONAL")
default_subnetwork = gcp.compute.Subnetwork("default",
name="custom-default-subnet",
ip_cidr_range="10.1.2.0/24",
network=default.id,
private_ipv6_google_access="DISABLE_GOOGLE_ACCESS",
purpose="PRIVATE",
region="southamerica-west1",
stack_type="IPV4_ONLY")
vmimage = gcp.compute.get_image(family="debian-11",
project="debian-cloud")
target_vm = gcp.compute.Instance("target-vm",
network_interfaces=[{
"access_configs": [{}],
"network": default.self_link,
"subnetwork": default_subnetwork.self_link,
}],
name="target-vm",
machine_type="e2-medium",
zone="southamerica-west1-a",
boot_disk={
"initialize_params": {
"image": vmimage.self_link,
},
})
policyddosprotection = gcp.compute.RegionSecurityPolicy("policyddosprotection",
region="southamerica-west1",
name="tf-test-policyddos_34962",
description="ddos protection security policy to set target instance",
type="CLOUD_ARMOR_NETWORK",
ddos_protection_config={
"ddos_protection": "ADVANCED_PREVIEW",
})
edge_sec_service = gcp.compute.NetworkEdgeSecurityService("edge_sec_service",
region="southamerica-west1",
name="tf-test-edgesec_74000",
security_policy=policyddosprotection.self_link)
regionsecuritypolicy = gcp.compute.RegionSecurityPolicy("regionsecuritypolicy",
name="region-secpolicy",
region="southamerica-west1",
description="basic security policy for target instance",
type="CLOUD_ARMOR_NETWORK",
opts = pulumi.ResourceOptions(depends_on=[edge_sec_service]))
default_target_instance = gcp.compute.TargetInstance("default",
name="target-instance",
zone="southamerica-west1-a",
instance=target_vm.id,
security_policy=regionsecuritypolicy.self_link)
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.NewNetwork(ctx, "default", &compute.NetworkArgs{
Name: pulumi.String("custom-default-network"),
AutoCreateSubnetworks: pulumi.Bool(false),
RoutingMode: pulumi.String("REGIONAL"),
})
if err != nil {
return err
}
defaultSubnetwork, err := compute.NewSubnetwork(ctx, "default", &compute.SubnetworkArgs{
Name: pulumi.String("custom-default-subnet"),
IpCidrRange: pulumi.String("10.1.2.0/24"),
Network: _default.ID(),
PrivateIpv6GoogleAccess: pulumi.String("DISABLE_GOOGLE_ACCESS"),
Purpose: pulumi.String("PRIVATE"),
Region: pulumi.String("southamerica-west1"),
StackType: pulumi.String("IPV4_ONLY"),
})
if err != nil {
return err
}
vmimage, err := compute.LookupImage(ctx, &compute.LookupImageArgs{
Family: pulumi.StringRef("debian-11"),
Project: pulumi.StringRef("debian-cloud"),
}, nil)
if err != nil {
return err
}
target_vm, err := compute.NewInstance(ctx, "target-vm", &compute.InstanceArgs{
NetworkInterfaces: compute.InstanceNetworkInterfaceArray{
&compute.InstanceNetworkInterfaceArgs{
AccessConfigs: compute.InstanceNetworkInterfaceAccessConfigArray{
&compute.InstanceNetworkInterfaceAccessConfigArgs{},
},
Network: _default.SelfLink,
Subnetwork: defaultSubnetwork.SelfLink,
},
},
Name: pulumi.String("target-vm"),
MachineType: pulumi.String("e2-medium"),
Zone: pulumi.String("southamerica-west1-a"),
BootDisk: &compute.InstanceBootDiskArgs{
InitializeParams: &compute.InstanceBootDiskInitializeParamsArgs{
Image: pulumi.String(vmimage.SelfLink),
},
},
})
if err != nil {
return err
}
policyddosprotection, err := compute.NewRegionSecurityPolicy(ctx, "policyddosprotection", &compute.RegionSecurityPolicyArgs{
Region: pulumi.String("southamerica-west1"),
Name: pulumi.String("tf-test-policyddos_34962"),
Description: pulumi.String("ddos protection security policy to set target instance"),
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("southamerica-west1"),
Name: pulumi.String("tf-test-edgesec_74000"),
SecurityPolicy: policyddosprotection.SelfLink,
})
if err != nil {
return err
}
regionsecuritypolicy, err := compute.NewRegionSecurityPolicy(ctx, "regionsecuritypolicy", &compute.RegionSecurityPolicyArgs{
Name: pulumi.String("region-secpolicy"),
Region: pulumi.String("southamerica-west1"),
Description: pulumi.String("basic security policy for target instance"),
Type: pulumi.String("CLOUD_ARMOR_NETWORK"),
}, pulumi.DependsOn([]pulumi.Resource{
edgeSecService,
}))
if err != nil {
return err
}
_, err = compute.NewTargetInstance(ctx, "default", &compute.TargetInstanceArgs{
Name: pulumi.String("target-instance"),
Zone: pulumi.String("southamerica-west1-a"),
Instance: target_vm.ID(),
SecurityPolicy: regionsecuritypolicy.SelfLink,
})
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 = "custom-default-network",
AutoCreateSubnetworks = false,
RoutingMode = "REGIONAL",
});
var defaultSubnetwork = new Gcp.Compute.Subnetwork("default", new()
{
Name = "custom-default-subnet",
IpCidrRange = "10.1.2.0/24",
Network = @default.Id,
PrivateIpv6GoogleAccess = "DISABLE_GOOGLE_ACCESS",
Purpose = "PRIVATE",
Region = "southamerica-west1",
StackType = "IPV4_ONLY",
});
var vmimage = Gcp.Compute.GetImage.Invoke(new()
{
Family = "debian-11",
Project = "debian-cloud",
});
var target_vm = new Gcp.Compute.Instance("target-vm", new()
{
NetworkInterfaces = new[]
{
new Gcp.Compute.Inputs.InstanceNetworkInterfaceArgs
{
AccessConfigs = new[]
{
null,
},
Network = @default.SelfLink,
Subnetwork = defaultSubnetwork.SelfLink,
},
},
Name = "target-vm",
MachineType = "e2-medium",
Zone = "southamerica-west1-a",
BootDisk = new Gcp.Compute.Inputs.InstanceBootDiskArgs
{
InitializeParams = new Gcp.Compute.Inputs.InstanceBootDiskInitializeParamsArgs
{
Image = vmimage.Apply(getImageResult => getImageResult.SelfLink),
},
},
});
var policyddosprotection = new Gcp.Compute.RegionSecurityPolicy("policyddosprotection", new()
{
Region = "southamerica-west1",
Name = "tf-test-policyddos_34962",
Description = "ddos protection security policy to set target instance",
Type = "CLOUD_ARMOR_NETWORK",
DdosProtectionConfig = new Gcp.Compute.Inputs.RegionSecurityPolicyDdosProtectionConfigArgs
{
DdosProtection = "ADVANCED_PREVIEW",
},
});
var edgeSecService = new Gcp.Compute.NetworkEdgeSecurityService("edge_sec_service", new()
{
Region = "southamerica-west1",
Name = "tf-test-edgesec_74000",
SecurityPolicy = policyddosprotection.SelfLink,
});
var regionsecuritypolicy = new Gcp.Compute.RegionSecurityPolicy("regionsecuritypolicy", new()
{
Name = "region-secpolicy",
Region = "southamerica-west1",
Description = "basic security policy for target instance",
Type = "CLOUD_ARMOR_NETWORK",
}, new CustomResourceOptions
{
DependsOn =
{
edgeSecService,
},
});
var defaultTargetInstance = new Gcp.Compute.TargetInstance("default", new()
{
Name = "target-instance",
Zone = "southamerica-west1-a",
Instance = target_vm.Id,
SecurityPolicy = regionsecuritypolicy.SelfLink,
});
});
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.compute.Subnetwork;
import com.pulumi.gcp.compute.SubnetworkArgs;
import com.pulumi.gcp.compute.ComputeFunctions;
import com.pulumi.gcp.compute.inputs.GetImageArgs;
import com.pulumi.gcp.compute.Instance;
import com.pulumi.gcp.compute.InstanceArgs;
import com.pulumi.gcp.compute.inputs.InstanceNetworkInterfaceArgs;
import com.pulumi.gcp.compute.inputs.InstanceBootDiskArgs;
import com.pulumi.gcp.compute.inputs.InstanceBootDiskInitializeParamsArgs;
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.TargetInstance;
import com.pulumi.gcp.compute.TargetInstanceArgs;
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) {
var default_ = new Network("default", NetworkArgs.builder()
.name("custom-default-network")
.autoCreateSubnetworks(false)
.routingMode("REGIONAL")
.build());
var defaultSubnetwork = new Subnetwork("defaultSubnetwork", SubnetworkArgs.builder()
.name("custom-default-subnet")
.ipCidrRange("10.1.2.0/24")
.network(default_.id())
.privateIpv6GoogleAccess("DISABLE_GOOGLE_ACCESS")
.purpose("PRIVATE")
.region("southamerica-west1")
.stackType("IPV4_ONLY")
.build());
final var vmimage = ComputeFunctions.getImage(GetImageArgs.builder()
.family("debian-11")
.project("debian-cloud")
.build());
var target_vm = new Instance("target-vm", InstanceArgs.builder()
.networkInterfaces(InstanceNetworkInterfaceArgs.builder()
.accessConfigs(InstanceNetworkInterfaceAccessConfigArgs.builder()
.build())
.network(default_.selfLink())
.subnetwork(defaultSubnetwork.selfLink())
.build())
.name("target-vm")
.machineType("e2-medium")
.zone("southamerica-west1-a")
.bootDisk(InstanceBootDiskArgs.builder()
.initializeParams(InstanceBootDiskInitializeParamsArgs.builder()
.image(vmimage.selfLink())
.build())
.build())
.build());
var policyddosprotection = new RegionSecurityPolicy("policyddosprotection", RegionSecurityPolicyArgs.builder()
.region("southamerica-west1")
.name("tf-test-policyddos_34962")
.description("ddos protection security policy to set target instance")
.type("CLOUD_ARMOR_NETWORK")
.ddosProtectionConfig(RegionSecurityPolicyDdosProtectionConfigArgs.builder()
.ddosProtection("ADVANCED_PREVIEW")
.build())
.build());
var edgeSecService = new NetworkEdgeSecurityService("edgeSecService", NetworkEdgeSecurityServiceArgs.builder()
.region("southamerica-west1")
.name("tf-test-edgesec_74000")
.securityPolicy(policyddosprotection.selfLink())
.build());
var regionsecuritypolicy = new RegionSecurityPolicy("regionsecuritypolicy", RegionSecurityPolicyArgs.builder()
.name("region-secpolicy")
.region("southamerica-west1")
.description("basic security policy for target instance")
.type("CLOUD_ARMOR_NETWORK")
.build(), CustomResourceOptions.builder()
.dependsOn(edgeSecService)
.build());
var defaultTargetInstance = new TargetInstance("defaultTargetInstance", TargetInstanceArgs.builder()
.name("target-instance")
.zone("southamerica-west1-a")
.instance(target_vm.id())
.securityPolicy(regionsecuritypolicy.selfLink())
.build());
}
}
resources:
default:
type: gcp:compute:Network
properties:
name: custom-default-network
autoCreateSubnetworks: false
routingMode: REGIONAL
defaultSubnetwork:
type: gcp:compute:Subnetwork
name: default
properties:
name: custom-default-subnet
ipCidrRange: 10.1.2.0/24
network: ${default.id}
privateIpv6GoogleAccess: DISABLE_GOOGLE_ACCESS
purpose: PRIVATE
region: southamerica-west1
stackType: IPV4_ONLY
target-vm:
type: gcp:compute:Instance
properties:
networkInterfaces:
- accessConfigs:
- {}
network: ${default.selfLink}
subnetwork: ${defaultSubnetwork.selfLink}
name: target-vm
machineType: e2-medium
zone: southamerica-west1-a
bootDisk:
initializeParams:
image: ${vmimage.selfLink}
policyddosprotection:
type: gcp:compute:RegionSecurityPolicy
properties:
region: southamerica-west1
name: tf-test-policyddos_34962
description: ddos protection security policy to set target instance
type: CLOUD_ARMOR_NETWORK
ddosProtectionConfig:
ddosProtection: ADVANCED_PREVIEW
edgeSecService:
type: gcp:compute:NetworkEdgeSecurityService
name: edge_sec_service
properties:
region: southamerica-west1
name: tf-test-edgesec_74000
securityPolicy: ${policyddosprotection.selfLink}
regionsecuritypolicy:
type: gcp:compute:RegionSecurityPolicy
properties:
name: region-secpolicy
region: southamerica-west1
description: basic security policy for target instance
type: CLOUD_ARMOR_NETWORK
options:
dependsOn:
- ${edgeSecService}
defaultTargetInstance:
type: gcp:compute:TargetInstance
name: default
properties:
name: target-instance
zone: southamerica-west1-a
instance: ${["target-vm"].id}
securityPolicy: ${regionsecuritypolicy.selfLink}
variables:
vmimage:
fn::invoke:
function: gcp:compute:getImage
arguments:
family: debian-11
project: debian-cloud
The securityPolicy property attaches a RegionSecurityPolicy to the target instance. Cloud Armor Network policies (type CLOUD_ARMOR_NETWORK) provide DDoS protection and network-level access controls. The NetworkEdgeSecurityService links the policy to the network edge. All resources must be in the same region.
Beyond these examples
These snippets focus on specific target instance features: basic target instance creation, custom network selection, and Cloud Armor Network security policies. They’re intentionally minimal rather than complete protocol forwarding setups.
The examples reference pre-existing infrastructure such as Compute Engine VM instances to receive traffic. They focus on configuring the target instance rather than provisioning the complete forwarding path.
To keep things focused, common target instance patterns are omitted, including:
- Forwarding rules that send traffic to target instances
- NAT policy configuration (only NO_NAT is supported)
- Multi-region or global load balancing setups
- Health checks and failover configuration
These omissions are intentional: the goal is to illustrate how each target instance feature is wired, not provide drop-in load balancing modules. See the TargetInstance resource reference for all available configuration options.
Let's configure GCP Compute Target Instances
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Immutability
securityPolicy can be modified after creation. All other properties (instance, name, zone, project, description, natPolicy, and network) are immutable and require resource replacement to change.a-z?.Instance & Network Setup
projects/project/zones/zone/instances/instance, or just the instance name. If using the name alone, the zone and project default to the provider configuration.network when you need to forward traffic to a specific network. If not specified, traffic is forwarded to the network that the default network interface belongs to.Security & Advanced Features
securityPolicy is the only mutable property. You can add or update it by setting the property to the resource URL of a RegionSecurityPolicy.Using a different cloud?
Explore networking guides for other cloud providers: