The aws:vpclattice/listener:Listener resource, part of the Pulumi AWS provider, defines a VPC Lattice listener that accepts traffic on a service and routes it based on configured actions. This guide focuses on two capabilities: fixed response actions and target group forwarding with optional traffic weighting.
Listeners belong to VPC Lattice services and forward traffic to target groups containing instances, IPs, or Lambda functions. The examples are intentionally small. Combine them with your own services, target groups, and routing rules.
Return a fixed HTTP response without routing
Some services return static responses for health checks, maintenance pages, or default catch-all behavior.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.vpclattice.Service("example", {name: "example"});
const exampleListener = new aws.vpclattice.Listener("example", {
name: "example",
protocol: "HTTPS",
serviceIdentifier: example.id,
defaultAction: {
fixedResponse: {
statusCode: 404,
},
},
});
import pulumi
import pulumi_aws as aws
example = aws.vpclattice.Service("example", name="example")
example_listener = aws.vpclattice.Listener("example",
name="example",
protocol="HTTPS",
service_identifier=example.id,
default_action={
"fixed_response": {
"status_code": 404,
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/vpclattice"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
example, err := vpclattice.NewService(ctx, "example", &vpclattice.ServiceArgs{
Name: pulumi.String("example"),
})
if err != nil {
return err
}
_, err = vpclattice.NewListener(ctx, "example", &vpclattice.ListenerArgs{
Name: pulumi.String("example"),
Protocol: pulumi.String("HTTPS"),
ServiceIdentifier: example.ID(),
DefaultAction: &vpclattice.ListenerDefaultActionArgs{
FixedResponse: &vpclattice.ListenerDefaultActionFixedResponseArgs{
StatusCode: pulumi.Int(404),
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.VpcLattice.Service("example", new()
{
Name = "example",
});
var exampleListener = new Aws.VpcLattice.Listener("example", new()
{
Name = "example",
Protocol = "HTTPS",
ServiceIdentifier = example.Id,
DefaultAction = new Aws.VpcLattice.Inputs.ListenerDefaultActionArgs
{
FixedResponse = new Aws.VpcLattice.Inputs.ListenerDefaultActionFixedResponseArgs
{
StatusCode = 404,
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.vpclattice.Service;
import com.pulumi.aws.vpclattice.ServiceArgs;
import com.pulumi.aws.vpclattice.Listener;
import com.pulumi.aws.vpclattice.ListenerArgs;
import com.pulumi.aws.vpclattice.inputs.ListenerDefaultActionArgs;
import com.pulumi.aws.vpclattice.inputs.ListenerDefaultActionFixedResponseArgs;
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 example = new Service("example", ServiceArgs.builder()
.name("example")
.build());
var exampleListener = new Listener("exampleListener", ListenerArgs.builder()
.name("example")
.protocol("HTTPS")
.serviceIdentifier(example.id())
.defaultAction(ListenerDefaultActionArgs.builder()
.fixedResponse(ListenerDefaultActionFixedResponseArgs.builder()
.statusCode(404)
.build())
.build())
.build());
}
}
resources:
example:
type: aws:vpclattice:Service
properties:
name: example
exampleListener:
type: aws:vpclattice:Listener
name: example
properties:
name: example
protocol: HTTPS
serviceIdentifier: ${example.id}
defaultAction:
fixedResponse:
statusCode: 404
The defaultAction property defines what happens when a request arrives. A fixedResponse action returns the specified statusCode directly without forwarding to any backend. The protocol property determines the listener’s communication protocol; port defaults to 80 for HTTP and 443 for HTTPS if not specified.
Route traffic to a single target group
Most listeners forward incoming requests to a target group containing the actual workload handlers.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.vpclattice.Service("example", {name: "example"});
const exampleTargetGroup = new aws.vpclattice.TargetGroup("example", {
name: "example-target-group-1",
type: "INSTANCE",
config: {
port: 80,
protocol: "HTTP",
vpcIdentifier: exampleAwsVpc.id,
},
});
const exampleListener = new aws.vpclattice.Listener("example", {
name: "example",
protocol: "HTTP",
serviceIdentifier: example.id,
defaultAction: {
forwards: [{
targetGroups: [{
targetGroupIdentifier: exampleTargetGroup.id,
}],
}],
},
});
import pulumi
import pulumi_aws as aws
example = aws.vpclattice.Service("example", name="example")
example_target_group = aws.vpclattice.TargetGroup("example",
name="example-target-group-1",
type="INSTANCE",
config={
"port": 80,
"protocol": "HTTP",
"vpc_identifier": example_aws_vpc["id"],
})
example_listener = aws.vpclattice.Listener("example",
name="example",
protocol="HTTP",
service_identifier=example.id,
default_action={
"forwards": [{
"target_groups": [{
"target_group_identifier": example_target_group.id,
}],
}],
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/vpclattice"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
example, err := vpclattice.NewService(ctx, "example", &vpclattice.ServiceArgs{
Name: pulumi.String("example"),
})
if err != nil {
return err
}
exampleTargetGroup, err := vpclattice.NewTargetGroup(ctx, "example", &vpclattice.TargetGroupArgs{
Name: pulumi.String("example-target-group-1"),
Type: pulumi.String("INSTANCE"),
Config: &vpclattice.TargetGroupConfigArgs{
Port: pulumi.Int(80),
Protocol: pulumi.String("HTTP"),
VpcIdentifier: pulumi.Any(exampleAwsVpc.Id),
},
})
if err != nil {
return err
}
_, err = vpclattice.NewListener(ctx, "example", &vpclattice.ListenerArgs{
Name: pulumi.String("example"),
Protocol: pulumi.String("HTTP"),
ServiceIdentifier: example.ID(),
DefaultAction: &vpclattice.ListenerDefaultActionArgs{
Forwards: vpclattice.ListenerDefaultActionForwardArray{
&vpclattice.ListenerDefaultActionForwardArgs{
TargetGroups: vpclattice.ListenerDefaultActionForwardTargetGroupArray{
&vpclattice.ListenerDefaultActionForwardTargetGroupArgs{
TargetGroupIdentifier: exampleTargetGroup.ID(),
},
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.VpcLattice.Service("example", new()
{
Name = "example",
});
var exampleTargetGroup = new Aws.VpcLattice.TargetGroup("example", new()
{
Name = "example-target-group-1",
Type = "INSTANCE",
Config = new Aws.VpcLattice.Inputs.TargetGroupConfigArgs
{
Port = 80,
Protocol = "HTTP",
VpcIdentifier = exampleAwsVpc.Id,
},
});
var exampleListener = new Aws.VpcLattice.Listener("example", new()
{
Name = "example",
Protocol = "HTTP",
ServiceIdentifier = example.Id,
DefaultAction = new Aws.VpcLattice.Inputs.ListenerDefaultActionArgs
{
Forwards = new[]
{
new Aws.VpcLattice.Inputs.ListenerDefaultActionForwardArgs
{
TargetGroups = new[]
{
new Aws.VpcLattice.Inputs.ListenerDefaultActionForwardTargetGroupArgs
{
TargetGroupIdentifier = exampleTargetGroup.Id,
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.vpclattice.Service;
import com.pulumi.aws.vpclattice.ServiceArgs;
import com.pulumi.aws.vpclattice.TargetGroup;
import com.pulumi.aws.vpclattice.TargetGroupArgs;
import com.pulumi.aws.vpclattice.inputs.TargetGroupConfigArgs;
import com.pulumi.aws.vpclattice.Listener;
import com.pulumi.aws.vpclattice.ListenerArgs;
import com.pulumi.aws.vpclattice.inputs.ListenerDefaultActionArgs;
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 example = new Service("example", ServiceArgs.builder()
.name("example")
.build());
var exampleTargetGroup = new TargetGroup("exampleTargetGroup", TargetGroupArgs.builder()
.name("example-target-group-1")
.type("INSTANCE")
.config(TargetGroupConfigArgs.builder()
.port(80)
.protocol("HTTP")
.vpcIdentifier(exampleAwsVpc.id())
.build())
.build());
var exampleListener = new Listener("exampleListener", ListenerArgs.builder()
.name("example")
.protocol("HTTP")
.serviceIdentifier(example.id())
.defaultAction(ListenerDefaultActionArgs.builder()
.forwards(ListenerDefaultActionForwardArgs.builder()
.targetGroups(ListenerDefaultActionForwardTargetGroupArgs.builder()
.targetGroupIdentifier(exampleTargetGroup.id())
.build())
.build())
.build())
.build());
}
}
resources:
example:
type: aws:vpclattice:Service
properties:
name: example
exampleTargetGroup:
type: aws:vpclattice:TargetGroup
name: example
properties:
name: example-target-group-1
type: INSTANCE
config:
port: 80
protocol: HTTP
vpcIdentifier: ${exampleAwsVpc.id}
exampleListener:
type: aws:vpclattice:Listener
name: example
properties:
name: example
protocol: HTTP
serviceIdentifier: ${example.id}
defaultAction:
forwards:
- targetGroups:
- targetGroupIdentifier: ${exampleTargetGroup.id}
When defaultAction contains a forwards block, the listener routes traffic to the specified target groups. The targetGroupIdentifier points to an existing target group. This configuration sends all traffic to one backend without splitting or weighting.
Split traffic across multiple target groups
Applications running canary deployments or A/B tests distribute traffic across multiple backend versions with percentage control.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.vpclattice.Service("example", {name: "example"});
const example1 = new aws.vpclattice.TargetGroup("example1", {
name: "example-target-group-1",
type: "INSTANCE",
config: {
port: 80,
protocol: "HTTP",
vpcIdentifier: exampleAwsVpc.id,
},
});
const example2 = new aws.vpclattice.TargetGroup("example2", {
name: "example-target-group-2",
type: "INSTANCE",
config: {
port: 8080,
protocol: "HTTP",
vpcIdentifier: exampleAwsVpc.id,
},
});
const exampleListener = new aws.vpclattice.Listener("example", {
name: "example",
protocol: "HTTP",
serviceIdentifier: example.id,
defaultAction: {
forwards: [{
targetGroups: [
{
targetGroupIdentifier: example1.id,
weight: 80,
},
{
targetGroupIdentifier: example2.id,
weight: 20,
},
],
}],
},
});
import pulumi
import pulumi_aws as aws
example = aws.vpclattice.Service("example", name="example")
example1 = aws.vpclattice.TargetGroup("example1",
name="example-target-group-1",
type="INSTANCE",
config={
"port": 80,
"protocol": "HTTP",
"vpc_identifier": example_aws_vpc["id"],
})
example2 = aws.vpclattice.TargetGroup("example2",
name="example-target-group-2",
type="INSTANCE",
config={
"port": 8080,
"protocol": "HTTP",
"vpc_identifier": example_aws_vpc["id"],
})
example_listener = aws.vpclattice.Listener("example",
name="example",
protocol="HTTP",
service_identifier=example.id,
default_action={
"forwards": [{
"target_groups": [
{
"target_group_identifier": example1.id,
"weight": 80,
},
{
"target_group_identifier": example2.id,
"weight": 20,
},
],
}],
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/vpclattice"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
example, err := vpclattice.NewService(ctx, "example", &vpclattice.ServiceArgs{
Name: pulumi.String("example"),
})
if err != nil {
return err
}
example1, err := vpclattice.NewTargetGroup(ctx, "example1", &vpclattice.TargetGroupArgs{
Name: pulumi.String("example-target-group-1"),
Type: pulumi.String("INSTANCE"),
Config: &vpclattice.TargetGroupConfigArgs{
Port: pulumi.Int(80),
Protocol: pulumi.String("HTTP"),
VpcIdentifier: pulumi.Any(exampleAwsVpc.Id),
},
})
if err != nil {
return err
}
example2, err := vpclattice.NewTargetGroup(ctx, "example2", &vpclattice.TargetGroupArgs{
Name: pulumi.String("example-target-group-2"),
Type: pulumi.String("INSTANCE"),
Config: &vpclattice.TargetGroupConfigArgs{
Port: pulumi.Int(8080),
Protocol: pulumi.String("HTTP"),
VpcIdentifier: pulumi.Any(exampleAwsVpc.Id),
},
})
if err != nil {
return err
}
_, err = vpclattice.NewListener(ctx, "example", &vpclattice.ListenerArgs{
Name: pulumi.String("example"),
Protocol: pulumi.String("HTTP"),
ServiceIdentifier: example.ID(),
DefaultAction: &vpclattice.ListenerDefaultActionArgs{
Forwards: vpclattice.ListenerDefaultActionForwardArray{
&vpclattice.ListenerDefaultActionForwardArgs{
TargetGroups: vpclattice.ListenerDefaultActionForwardTargetGroupArray{
&vpclattice.ListenerDefaultActionForwardTargetGroupArgs{
TargetGroupIdentifier: example1.ID(),
Weight: pulumi.Int(80),
},
&vpclattice.ListenerDefaultActionForwardTargetGroupArgs{
TargetGroupIdentifier: example2.ID(),
Weight: pulumi.Int(20),
},
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.VpcLattice.Service("example", new()
{
Name = "example",
});
var example1 = new Aws.VpcLattice.TargetGroup("example1", new()
{
Name = "example-target-group-1",
Type = "INSTANCE",
Config = new Aws.VpcLattice.Inputs.TargetGroupConfigArgs
{
Port = 80,
Protocol = "HTTP",
VpcIdentifier = exampleAwsVpc.Id,
},
});
var example2 = new Aws.VpcLattice.TargetGroup("example2", new()
{
Name = "example-target-group-2",
Type = "INSTANCE",
Config = new Aws.VpcLattice.Inputs.TargetGroupConfigArgs
{
Port = 8080,
Protocol = "HTTP",
VpcIdentifier = exampleAwsVpc.Id,
},
});
var exampleListener = new Aws.VpcLattice.Listener("example", new()
{
Name = "example",
Protocol = "HTTP",
ServiceIdentifier = example.Id,
DefaultAction = new Aws.VpcLattice.Inputs.ListenerDefaultActionArgs
{
Forwards = new[]
{
new Aws.VpcLattice.Inputs.ListenerDefaultActionForwardArgs
{
TargetGroups = new[]
{
new Aws.VpcLattice.Inputs.ListenerDefaultActionForwardTargetGroupArgs
{
TargetGroupIdentifier = example1.Id,
Weight = 80,
},
new Aws.VpcLattice.Inputs.ListenerDefaultActionForwardTargetGroupArgs
{
TargetGroupIdentifier = example2.Id,
Weight = 20,
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.vpclattice.Service;
import com.pulumi.aws.vpclattice.ServiceArgs;
import com.pulumi.aws.vpclattice.TargetGroup;
import com.pulumi.aws.vpclattice.TargetGroupArgs;
import com.pulumi.aws.vpclattice.inputs.TargetGroupConfigArgs;
import com.pulumi.aws.vpclattice.Listener;
import com.pulumi.aws.vpclattice.ListenerArgs;
import com.pulumi.aws.vpclattice.inputs.ListenerDefaultActionArgs;
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 example = new Service("example", ServiceArgs.builder()
.name("example")
.build());
var example1 = new TargetGroup("example1", TargetGroupArgs.builder()
.name("example-target-group-1")
.type("INSTANCE")
.config(TargetGroupConfigArgs.builder()
.port(80)
.protocol("HTTP")
.vpcIdentifier(exampleAwsVpc.id())
.build())
.build());
var example2 = new TargetGroup("example2", TargetGroupArgs.builder()
.name("example-target-group-2")
.type("INSTANCE")
.config(TargetGroupConfigArgs.builder()
.port(8080)
.protocol("HTTP")
.vpcIdentifier(exampleAwsVpc.id())
.build())
.build());
var exampleListener = new Listener("exampleListener", ListenerArgs.builder()
.name("example")
.protocol("HTTP")
.serviceIdentifier(example.id())
.defaultAction(ListenerDefaultActionArgs.builder()
.forwards(ListenerDefaultActionForwardArgs.builder()
.targetGroups(
ListenerDefaultActionForwardTargetGroupArgs.builder()
.targetGroupIdentifier(example1.id())
.weight(80)
.build(),
ListenerDefaultActionForwardTargetGroupArgs.builder()
.targetGroupIdentifier(example2.id())
.weight(20)
.build())
.build())
.build())
.build());
}
}
resources:
example:
type: aws:vpclattice:Service
properties:
name: example
example1:
type: aws:vpclattice:TargetGroup
properties:
name: example-target-group-1
type: INSTANCE
config:
port: 80
protocol: HTTP
vpcIdentifier: ${exampleAwsVpc.id}
example2:
type: aws:vpclattice:TargetGroup
properties:
name: example-target-group-2
type: INSTANCE
config:
port: 8080
protocol: HTTP
vpcIdentifier: ${exampleAwsVpc.id}
exampleListener:
type: aws:vpclattice:Listener
name: example
properties:
name: example
protocol: HTTP
serviceIdentifier: ${example.id}
defaultAction:
forwards:
- targetGroups:
- targetGroupIdentifier: ${example1.id}
weight: 80
- targetGroupIdentifier: ${example2.id}
weight: 20
The weight property controls traffic distribution across target groups. Weights are relative: 80 and 20 result in an 80/20 split. VPC Lattice handles the distribution automatically based on these ratios, enabling gradual rollouts or testing scenarios.
Beyond these examples
These snippets focus on specific listener-level features: fixed responses and traffic forwarding, and weighted target group distribution. They’re intentionally minimal rather than full service mesh configurations.
The examples reference pre-existing infrastructure such as VPC Lattice services, target groups with configured backends, and VPC infrastructure. They focus on configuring the listener rather than provisioning the entire service mesh.
To keep things focused, common listener patterns are omitted, including:
- Port configuration (defaults to 80 for HTTP, 443 for HTTPS)
- TLS_PASSTHROUGH protocol support
- Listener rules for path-based or header-based routing
- Tags for resource organization
These omissions are intentional: the goal is to illustrate how each listener feature is wired, not provide drop-in service mesh modules. See the VPC Lattice Listener resource reference for all available configuration options.
Let's configure AWS VPC Lattice Listeners
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Setup
HTTP, HTTPS, or TLS_PASSTHROUGH protocols. Ports range from 1 to 65535, defaulting to 80 for HTTP and 443 for HTTPS if not specified.serviceArn or serviceIdentifier, but not both.fixedResponse (returns a status code like 404) or forwards (routes traffic to one or more target groups).defaultAction.forwards.targetGroups, each with a weight value. For example, you can route 80% of traffic to one group and 20% to another.Naming & Immutability
name, port, and protocol properties are immutable. Changing any of these will force replacement of the listener.Using a different cloud?
Explore networking guides for other cloud providers: