The aws:appmesh/route:Route resource, part of the Pulumi AWS provider, defines routing rules within an App Mesh virtual router: how traffic is matched, distributed across virtual nodes, and retried on failure. This guide focuses on three capabilities: HTTP and TCP traffic distribution, header-based request filtering, and automatic retry policies.
Routes belong to virtual routers and direct traffic to virtual nodes within a service mesh. The examples are intentionally small. Combine them with your own mesh, virtual routers, and virtual nodes.
Split HTTP traffic across virtual nodes
Service meshes often route traffic to multiple backend versions simultaneously, enabling canary deployments where most traffic goes to a stable version while a small percentage tests new code.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const serviceb = new aws.appmesh.Route("serviceb", {
name: "serviceB-route",
meshName: simple.id,
virtualRouterName: servicebAwsAppmeshVirtualRouter.name,
spec: {
httpRoute: {
match: {
prefix: "/",
},
action: {
weightedTargets: [
{
virtualNode: serviceb1.name,
weight: 90,
},
{
virtualNode: serviceb2.name,
weight: 10,
},
],
},
},
},
});
import pulumi
import pulumi_aws as aws
serviceb = aws.appmesh.Route("serviceb",
name="serviceB-route",
mesh_name=simple["id"],
virtual_router_name=serviceb_aws_appmesh_virtual_router["name"],
spec={
"http_route": {
"match": {
"prefix": "/",
},
"action": {
"weighted_targets": [
{
"virtual_node": serviceb1["name"],
"weight": 90,
},
{
"virtual_node": serviceb2["name"],
"weight": 10,
},
],
},
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/appmesh"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := appmesh.NewRoute(ctx, "serviceb", &appmesh.RouteArgs{
Name: pulumi.String("serviceB-route"),
MeshName: pulumi.Any(simple.Id),
VirtualRouterName: pulumi.Any(servicebAwsAppmeshVirtualRouter.Name),
Spec: &appmesh.RouteSpecArgs{
HttpRoute: &appmesh.RouteSpecHttpRouteArgs{
Match: &appmesh.RouteSpecHttpRouteMatchArgs{
Prefix: pulumi.String("/"),
},
Action: &appmesh.RouteSpecHttpRouteActionArgs{
WeightedTargets: appmesh.RouteSpecHttpRouteActionWeightedTargetArray{
&appmesh.RouteSpecHttpRouteActionWeightedTargetArgs{
VirtualNode: pulumi.Any(serviceb1.Name),
Weight: pulumi.Int(90),
},
&appmesh.RouteSpecHttpRouteActionWeightedTargetArgs{
VirtualNode: pulumi.Any(serviceb2.Name),
Weight: pulumi.Int(10),
},
},
},
},
},
})
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 serviceb = new Aws.AppMesh.Route("serviceb", new()
{
Name = "serviceB-route",
MeshName = simple.Id,
VirtualRouterName = servicebAwsAppmeshVirtualRouter.Name,
Spec = new Aws.AppMesh.Inputs.RouteSpecArgs
{
HttpRoute = new Aws.AppMesh.Inputs.RouteSpecHttpRouteArgs
{
Match = new Aws.AppMesh.Inputs.RouteSpecHttpRouteMatchArgs
{
Prefix = "/",
},
Action = new Aws.AppMesh.Inputs.RouteSpecHttpRouteActionArgs
{
WeightedTargets = new[]
{
new Aws.AppMesh.Inputs.RouteSpecHttpRouteActionWeightedTargetArgs
{
VirtualNode = serviceb1.Name,
Weight = 90,
},
new Aws.AppMesh.Inputs.RouteSpecHttpRouteActionWeightedTargetArgs
{
VirtualNode = serviceb2.Name,
Weight = 10,
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.appmesh.Route;
import com.pulumi.aws.appmesh.RouteArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecHttpRouteArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecHttpRouteMatchArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecHttpRouteActionArgs;
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 serviceb = new Route("serviceb", RouteArgs.builder()
.name("serviceB-route")
.meshName(simple.id())
.virtualRouterName(servicebAwsAppmeshVirtualRouter.name())
.spec(RouteSpecArgs.builder()
.httpRoute(RouteSpecHttpRouteArgs.builder()
.match(RouteSpecHttpRouteMatchArgs.builder()
.prefix("/")
.build())
.action(RouteSpecHttpRouteActionArgs.builder()
.weightedTargets(
RouteSpecHttpRouteActionWeightedTargetArgs.builder()
.virtualNode(serviceb1.name())
.weight(90)
.build(),
RouteSpecHttpRouteActionWeightedTargetArgs.builder()
.virtualNode(serviceb2.name())
.weight(10)
.build())
.build())
.build())
.build())
.build());
}
}
resources:
serviceb:
type: aws:appmesh:Route
properties:
name: serviceB-route
meshName: ${simple.id}
virtualRouterName: ${servicebAwsAppmeshVirtualRouter.name}
spec:
httpRoute:
match:
prefix: /
action:
weightedTargets:
- virtualNode: ${serviceb1.name}
weight: 90
- virtualNode: ${serviceb2.name}
weight: 10
When a request matches the prefix, App Mesh distributes it across the weighted targets. Here, 90% of requests go to serviceb1 and 10% to serviceb2. The match block defines which requests this route handles; the action block specifies where they go and in what proportion.
Route requests based on HTTP headers and method
Applications sometimes need to route requests differently based on headers, HTTP methods, or URL schemes, directing specific client types or request patterns to dedicated backends.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const serviceb = new aws.appmesh.Route("serviceb", {
name: "serviceB-route",
meshName: simple.id,
virtualRouterName: servicebAwsAppmeshVirtualRouter.name,
spec: {
httpRoute: {
match: {
method: "POST",
prefix: "/",
scheme: "https",
headers: [{
name: "clientRequestId",
match: {
prefix: "123",
},
}],
},
action: {
weightedTargets: [{
virtualNode: servicebAwsAppmeshVirtualNode.name,
weight: 100,
}],
},
},
},
});
import pulumi
import pulumi_aws as aws
serviceb = aws.appmesh.Route("serviceb",
name="serviceB-route",
mesh_name=simple["id"],
virtual_router_name=serviceb_aws_appmesh_virtual_router["name"],
spec={
"http_route": {
"match": {
"method": "POST",
"prefix": "/",
"scheme": "https",
"headers": [{
"name": "clientRequestId",
"match": {
"prefix": "123",
},
}],
},
"action": {
"weighted_targets": [{
"virtual_node": serviceb_aws_appmesh_virtual_node["name"],
"weight": 100,
}],
},
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/appmesh"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := appmesh.NewRoute(ctx, "serviceb", &appmesh.RouteArgs{
Name: pulumi.String("serviceB-route"),
MeshName: pulumi.Any(simple.Id),
VirtualRouterName: pulumi.Any(servicebAwsAppmeshVirtualRouter.Name),
Spec: &appmesh.RouteSpecArgs{
HttpRoute: &appmesh.RouteSpecHttpRouteArgs{
Match: &appmesh.RouteSpecHttpRouteMatchArgs{
Method: pulumi.String("POST"),
Prefix: pulumi.String("/"),
Scheme: pulumi.String("https"),
Headers: appmesh.RouteSpecHttpRouteMatchHeaderArray{
&appmesh.RouteSpecHttpRouteMatchHeaderArgs{
Name: pulumi.String("clientRequestId"),
Match: &appmesh.RouteSpecHttpRouteMatchHeaderMatchArgs{
Prefix: pulumi.String("123"),
},
},
},
},
Action: &appmesh.RouteSpecHttpRouteActionArgs{
WeightedTargets: appmesh.RouteSpecHttpRouteActionWeightedTargetArray{
&appmesh.RouteSpecHttpRouteActionWeightedTargetArgs{
VirtualNode: pulumi.Any(servicebAwsAppmeshVirtualNode.Name),
Weight: pulumi.Int(100),
},
},
},
},
},
})
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 serviceb = new Aws.AppMesh.Route("serviceb", new()
{
Name = "serviceB-route",
MeshName = simple.Id,
VirtualRouterName = servicebAwsAppmeshVirtualRouter.Name,
Spec = new Aws.AppMesh.Inputs.RouteSpecArgs
{
HttpRoute = new Aws.AppMesh.Inputs.RouteSpecHttpRouteArgs
{
Match = new Aws.AppMesh.Inputs.RouteSpecHttpRouteMatchArgs
{
Method = "POST",
Prefix = "/",
Scheme = "https",
Headers = new[]
{
new Aws.AppMesh.Inputs.RouteSpecHttpRouteMatchHeaderArgs
{
Name = "clientRequestId",
Match = new Aws.AppMesh.Inputs.RouteSpecHttpRouteMatchHeaderMatchArgs
{
Prefix = "123",
},
},
},
},
Action = new Aws.AppMesh.Inputs.RouteSpecHttpRouteActionArgs
{
WeightedTargets = new[]
{
new Aws.AppMesh.Inputs.RouteSpecHttpRouteActionWeightedTargetArgs
{
VirtualNode = servicebAwsAppmeshVirtualNode.Name,
Weight = 100,
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.appmesh.Route;
import com.pulumi.aws.appmesh.RouteArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecHttpRouteArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecHttpRouteMatchArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecHttpRouteActionArgs;
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 serviceb = new Route("serviceb", RouteArgs.builder()
.name("serviceB-route")
.meshName(simple.id())
.virtualRouterName(servicebAwsAppmeshVirtualRouter.name())
.spec(RouteSpecArgs.builder()
.httpRoute(RouteSpecHttpRouteArgs.builder()
.match(RouteSpecHttpRouteMatchArgs.builder()
.method("POST")
.prefix("/")
.scheme("https")
.headers(RouteSpecHttpRouteMatchHeaderArgs.builder()
.name("clientRequestId")
.match(RouteSpecHttpRouteMatchHeaderMatchArgs.builder()
.prefix("123")
.build())
.build())
.build())
.action(RouteSpecHttpRouteActionArgs.builder()
.weightedTargets(RouteSpecHttpRouteActionWeightedTargetArgs.builder()
.virtualNode(servicebAwsAppmeshVirtualNode.name())
.weight(100)
.build())
.build())
.build())
.build())
.build());
}
}
resources:
serviceb:
type: aws:appmesh:Route
properties:
name: serviceB-route
meshName: ${simple.id}
virtualRouterName: ${servicebAwsAppmeshVirtualRouter.name}
spec:
httpRoute:
match:
method: POST
prefix: /
scheme: https
headers:
- name: clientRequestId
match:
prefix: '123'
action:
weightedTargets:
- virtualNode: ${servicebAwsAppmeshVirtualNode.name}
weight: 100
The match block filters incoming requests by method (POST), scheme (https), and header values. Only requests with a clientRequestId header starting with “123” reach this route. The headers array supports prefix, exact, range, and regex matching for flexible filtering.
Add automatic retries for transient failures
Distributed systems encounter transient failures like network timeouts or temporary service unavailability. Retry policies automatically reattempt failed requests without requiring application-level retry logic.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const serviceb = new aws.appmesh.Route("serviceb", {
name: "serviceB-route",
meshName: simple.id,
virtualRouterName: servicebAwsAppmeshVirtualRouter.name,
spec: {
httpRoute: {
match: {
prefix: "/",
},
retryPolicy: {
httpRetryEvents: ["server-error"],
maxRetries: 1,
perRetryTimeout: {
unit: "s",
value: 15,
},
},
action: {
weightedTargets: [{
virtualNode: servicebAwsAppmeshVirtualNode.name,
weight: 100,
}],
},
},
},
});
import pulumi
import pulumi_aws as aws
serviceb = aws.appmesh.Route("serviceb",
name="serviceB-route",
mesh_name=simple["id"],
virtual_router_name=serviceb_aws_appmesh_virtual_router["name"],
spec={
"http_route": {
"match": {
"prefix": "/",
},
"retry_policy": {
"http_retry_events": ["server-error"],
"max_retries": 1,
"per_retry_timeout": {
"unit": "s",
"value": 15,
},
},
"action": {
"weighted_targets": [{
"virtual_node": serviceb_aws_appmesh_virtual_node["name"],
"weight": 100,
}],
},
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/appmesh"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := appmesh.NewRoute(ctx, "serviceb", &appmesh.RouteArgs{
Name: pulumi.String("serviceB-route"),
MeshName: pulumi.Any(simple.Id),
VirtualRouterName: pulumi.Any(servicebAwsAppmeshVirtualRouter.Name),
Spec: &appmesh.RouteSpecArgs{
HttpRoute: &appmesh.RouteSpecHttpRouteArgs{
Match: &appmesh.RouteSpecHttpRouteMatchArgs{
Prefix: pulumi.String("/"),
},
RetryPolicy: &appmesh.RouteSpecHttpRouteRetryPolicyArgs{
HttpRetryEvents: pulumi.StringArray{
pulumi.String("server-error"),
},
MaxRetries: pulumi.Int(1),
PerRetryTimeout: &appmesh.RouteSpecHttpRouteRetryPolicyPerRetryTimeoutArgs{
Unit: pulumi.String("s"),
Value: pulumi.Int(15),
},
},
Action: &appmesh.RouteSpecHttpRouteActionArgs{
WeightedTargets: appmesh.RouteSpecHttpRouteActionWeightedTargetArray{
&appmesh.RouteSpecHttpRouteActionWeightedTargetArgs{
VirtualNode: pulumi.Any(servicebAwsAppmeshVirtualNode.Name),
Weight: pulumi.Int(100),
},
},
},
},
},
})
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 serviceb = new Aws.AppMesh.Route("serviceb", new()
{
Name = "serviceB-route",
MeshName = simple.Id,
VirtualRouterName = servicebAwsAppmeshVirtualRouter.Name,
Spec = new Aws.AppMesh.Inputs.RouteSpecArgs
{
HttpRoute = new Aws.AppMesh.Inputs.RouteSpecHttpRouteArgs
{
Match = new Aws.AppMesh.Inputs.RouteSpecHttpRouteMatchArgs
{
Prefix = "/",
},
RetryPolicy = new Aws.AppMesh.Inputs.RouteSpecHttpRouteRetryPolicyArgs
{
HttpRetryEvents = new[]
{
"server-error",
},
MaxRetries = 1,
PerRetryTimeout = new Aws.AppMesh.Inputs.RouteSpecHttpRouteRetryPolicyPerRetryTimeoutArgs
{
Unit = "s",
Value = 15,
},
},
Action = new Aws.AppMesh.Inputs.RouteSpecHttpRouteActionArgs
{
WeightedTargets = new[]
{
new Aws.AppMesh.Inputs.RouteSpecHttpRouteActionWeightedTargetArgs
{
VirtualNode = servicebAwsAppmeshVirtualNode.Name,
Weight = 100,
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.appmesh.Route;
import com.pulumi.aws.appmesh.RouteArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecHttpRouteArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecHttpRouteMatchArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecHttpRouteRetryPolicyArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecHttpRouteRetryPolicyPerRetryTimeoutArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecHttpRouteActionArgs;
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 serviceb = new Route("serviceb", RouteArgs.builder()
.name("serviceB-route")
.meshName(simple.id())
.virtualRouterName(servicebAwsAppmeshVirtualRouter.name())
.spec(RouteSpecArgs.builder()
.httpRoute(RouteSpecHttpRouteArgs.builder()
.match(RouteSpecHttpRouteMatchArgs.builder()
.prefix("/")
.build())
.retryPolicy(RouteSpecHttpRouteRetryPolicyArgs.builder()
.httpRetryEvents("server-error")
.maxRetries(1)
.perRetryTimeout(RouteSpecHttpRouteRetryPolicyPerRetryTimeoutArgs.builder()
.unit("s")
.value(15)
.build())
.build())
.action(RouteSpecHttpRouteActionArgs.builder()
.weightedTargets(RouteSpecHttpRouteActionWeightedTargetArgs.builder()
.virtualNode(servicebAwsAppmeshVirtualNode.name())
.weight(100)
.build())
.build())
.build())
.build())
.build());
}
}
resources:
serviceb:
type: aws:appmesh:Route
properties:
name: serviceB-route
meshName: ${simple.id}
virtualRouterName: ${servicebAwsAppmeshVirtualRouter.name}
spec:
httpRoute:
match:
prefix: /
retryPolicy:
httpRetryEvents:
- server-error
maxRetries: 1
perRetryTimeout:
unit: s
value: 15
action:
weightedTargets:
- virtualNode: ${servicebAwsAppmeshVirtualNode.name}
weight: 100
The retryPolicy block configures automatic retries when App Mesh detects server errors. The httpRetryEvents property lists which error types trigger retries; maxRetries caps the number of attempts; perRetryTimeout sets how long to wait for each attempt. This moves retry logic from application code into the mesh infrastructure.
Route TCP traffic to virtual nodes
Non-HTTP protocols like databases or custom TCP services need routing rules that operate at the transport layer without inspecting application-level headers.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const serviceb = new aws.appmesh.Route("serviceb", {
name: "serviceB-route",
meshName: simple.id,
virtualRouterName: servicebAwsAppmeshVirtualRouter.name,
spec: {
tcpRoute: {
action: {
weightedTargets: [{
virtualNode: serviceb1.name,
weight: 100,
}],
},
},
},
});
import pulumi
import pulumi_aws as aws
serviceb = aws.appmesh.Route("serviceb",
name="serviceB-route",
mesh_name=simple["id"],
virtual_router_name=serviceb_aws_appmesh_virtual_router["name"],
spec={
"tcp_route": {
"action": {
"weighted_targets": [{
"virtual_node": serviceb1["name"],
"weight": 100,
}],
},
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/appmesh"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := appmesh.NewRoute(ctx, "serviceb", &appmesh.RouteArgs{
Name: pulumi.String("serviceB-route"),
MeshName: pulumi.Any(simple.Id),
VirtualRouterName: pulumi.Any(servicebAwsAppmeshVirtualRouter.Name),
Spec: &appmesh.RouteSpecArgs{
TcpRoute: &appmesh.RouteSpecTcpRouteArgs{
Action: &appmesh.RouteSpecTcpRouteActionArgs{
WeightedTargets: appmesh.RouteSpecTcpRouteActionWeightedTargetArray{
&appmesh.RouteSpecTcpRouteActionWeightedTargetArgs{
VirtualNode: pulumi.Any(serviceb1.Name),
Weight: pulumi.Int(100),
},
},
},
},
},
})
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 serviceb = new Aws.AppMesh.Route("serviceb", new()
{
Name = "serviceB-route",
MeshName = simple.Id,
VirtualRouterName = servicebAwsAppmeshVirtualRouter.Name,
Spec = new Aws.AppMesh.Inputs.RouteSpecArgs
{
TcpRoute = new Aws.AppMesh.Inputs.RouteSpecTcpRouteArgs
{
Action = new Aws.AppMesh.Inputs.RouteSpecTcpRouteActionArgs
{
WeightedTargets = new[]
{
new Aws.AppMesh.Inputs.RouteSpecTcpRouteActionWeightedTargetArgs
{
VirtualNode = serviceb1.Name,
Weight = 100,
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.appmesh.Route;
import com.pulumi.aws.appmesh.RouteArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecTcpRouteArgs;
import com.pulumi.aws.appmesh.inputs.RouteSpecTcpRouteActionArgs;
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 serviceb = new Route("serviceb", RouteArgs.builder()
.name("serviceB-route")
.meshName(simple.id())
.virtualRouterName(servicebAwsAppmeshVirtualRouter.name())
.spec(RouteSpecArgs.builder()
.tcpRoute(RouteSpecTcpRouteArgs.builder()
.action(RouteSpecTcpRouteActionArgs.builder()
.weightedTargets(RouteSpecTcpRouteActionWeightedTargetArgs.builder()
.virtualNode(serviceb1.name())
.weight(100)
.build())
.build())
.build())
.build())
.build());
}
}
resources:
serviceb:
type: aws:appmesh:Route
properties:
name: serviceB-route
meshName: ${simple.id}
virtualRouterName: ${servicebAwsAppmeshVirtualRouter.name}
spec:
tcpRoute:
action:
weightedTargets:
- virtualNode: ${serviceb1.name}
weight: 100
TCP routes use tcpRoute instead of httpRoute and omit the match block since TCP routing doesn’t inspect request content. The action block still supports weighted targets for distributing connections across backends.
Beyond these examples
These snippets focus on specific route-level features: HTTP and TCP routing, weighted traffic distribution, and header-based filtering and retry policies. They’re intentionally minimal rather than full service mesh configurations.
The examples reference pre-existing infrastructure such as App Mesh service meshes, virtual routers, and virtual nodes. They focus on configuring the route rather than provisioning the surrounding mesh components.
To keep things focused, common route patterns are omitted, including:
- gRPC routing (grpcRoute)
- Timeout configuration (timeout blocks)
- Priority-based routing
- Connection pool settings
These omissions are intentional: the goal is to illustrate how each route feature is wired, not provide drop-in mesh modules. See the App Mesh Route resource reference for all available configuration options.
Let's configure AWS App Mesh Routes
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Route Configuration & Types
meshName, name, and virtualRouterName properties are immutable and will force resource replacement if changed.Traffic Management
weightedTargets in the route action with weight values for each virtual node. For example, weights of 90 and 10 create a 90/10 traffic split for canary deployments.Advanced HTTP Routing
match block with headers, method, scheme, and prefix properties. For example, you can route POST requests with specific header values to designated virtual nodes.retryPolicy to your HTTP route specifying httpRetryEvents (like “server-error”), maxRetries, and perRetryTimeout with unit and value.httpRetryEvents value. Configure maxRetries and perRetryTimeout to control retry behavior.Resource Management
mesh_name/virtual_router_name/route_name, for example: pulumi import aws:appmesh/route:Route serviceb simpleapp/serviceB/serviceB-routeUsing a different cloud?
Explore networking guides for other cloud providers: