Configure GCP URL Maps for Load Balancing

The gcp:compute/uRLMap:URLMap resource, part of the Pulumi GCP provider, defines routing rules that direct incoming requests to backend services or backend buckets based on hostname, path, headers, and query parameters. This guide focuses on four capabilities: host and path-based routing, header and query parameter matching, Traffic Director route actions, and custom error responses.

URL maps depend on backend services (with health checks) and backend buckets that must exist before you configure routing. The examples are intentionally small. Combine them with your own backend infrastructure and load balancing configuration.

Route requests across backend services and storage buckets

Most load balancers route traffic to different backends based on hostname and path, directing requests to backend services for dynamic content or backend buckets for static assets.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.compute.HttpHealthCheck("default", {
    name: "health-check",
    requestPath: "/",
    checkIntervalSec: 1,
    timeoutSec: 1,
});
const login = new gcp.compute.BackendService("login", {
    name: "login",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    healthChecks: _default.id,
});
const staticBucket = new gcp.storage.Bucket("static", {
    name: "static-asset-bucket",
    location: "US",
});
const static = new gcp.compute.BackendBucket("static", {
    name: "static-asset-backend-bucket",
    bucketName: staticBucket.name,
    enableCdn: true,
});
const urlmap = new gcp.compute.URLMap("urlmap", {
    name: "urlmap",
    description: "a description",
    defaultService: static.id,
    hostRules: [
        {
            hosts: ["mysite.com"],
            pathMatcher: "mysite",
        },
        {
            hosts: ["myothersite.com"],
            pathMatcher: "otherpaths",
        },
    ],
    pathMatchers: [
        {
            name: "mysite",
            defaultService: static.id,
            pathRules: [
                {
                    paths: ["/home"],
                    service: static.id,
                },
                {
                    paths: ["/login"],
                    service: login.id,
                },
                {
                    paths: ["/static"],
                    service: static.id,
                },
            ],
        },
        {
            name: "otherpaths",
            defaultService: static.id,
        },
    ],
    tests: [{
        service: static.id,
        host: "example.com",
        path: "/home",
    }],
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.HttpHealthCheck("default",
    name="health-check",
    request_path="/",
    check_interval_sec=1,
    timeout_sec=1)
login = gcp.compute.BackendService("login",
    name="login",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    health_checks=default.id)
static_bucket = gcp.storage.Bucket("static",
    name="static-asset-bucket",
    location="US")
static = gcp.compute.BackendBucket("static",
    name="static-asset-backend-bucket",
    bucket_name=static_bucket.name,
    enable_cdn=True)
urlmap = gcp.compute.URLMap("urlmap",
    name="urlmap",
    description="a description",
    default_service=static.id,
    host_rules=[
        {
            "hosts": ["mysite.com"],
            "path_matcher": "mysite",
        },
        {
            "hosts": ["myothersite.com"],
            "path_matcher": "otherpaths",
        },
    ],
    path_matchers=[
        {
            "name": "mysite",
            "default_service": static.id,
            "path_rules": [
                {
                    "paths": ["/home"],
                    "service": static.id,
                },
                {
                    "paths": ["/login"],
                    "service": login.id,
                },
                {
                    "paths": ["/static"],
                    "service": static.id,
                },
            ],
        },
        {
            "name": "otherpaths",
            "default_service": static.id,
        },
    ],
    tests=[{
        "service": static.id,
        "host": "example.com",
        "path": "/home",
    }])
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/storage"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
			Name:             pulumi.String("health-check"),
			RequestPath:      pulumi.String("/"),
			CheckIntervalSec: pulumi.Int(1),
			TimeoutSec:       pulumi.Int(1),
		})
		if err != nil {
			return err
		}
		login, err := compute.NewBackendService(ctx, "login", &compute.BackendServiceArgs{
			Name:         pulumi.String("login"),
			PortName:     pulumi.String("http"),
			Protocol:     pulumi.String("HTTP"),
			TimeoutSec:   pulumi.Int(10),
			HealthChecks: _default.ID(),
		})
		if err != nil {
			return err
		}
		staticBucket, err := storage.NewBucket(ctx, "static", &storage.BucketArgs{
			Name:     pulumi.String("static-asset-bucket"),
			Location: pulumi.String("US"),
		})
		if err != nil {
			return err
		}
		static, err := compute.NewBackendBucket(ctx, "static", &compute.BackendBucketArgs{
			Name:       pulumi.String("static-asset-backend-bucket"),
			BucketName: staticBucket.Name,
			EnableCdn:  pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewURLMap(ctx, "urlmap", &compute.URLMapArgs{
			Name:           pulumi.String("urlmap"),
			Description:    pulumi.String("a description"),
			DefaultService: static.ID(),
			HostRules: compute.URLMapHostRuleArray{
				&compute.URLMapHostRuleArgs{
					Hosts: pulumi.StringArray{
						pulumi.String("mysite.com"),
					},
					PathMatcher: pulumi.String("mysite"),
				},
				&compute.URLMapHostRuleArgs{
					Hosts: pulumi.StringArray{
						pulumi.String("myothersite.com"),
					},
					PathMatcher: pulumi.String("otherpaths"),
				},
			},
			PathMatchers: compute.URLMapPathMatcherArray{
				&compute.URLMapPathMatcherArgs{
					Name:           pulumi.String("mysite"),
					DefaultService: static.ID(),
					PathRules: compute.URLMapPathMatcherPathRuleArray{
						&compute.URLMapPathMatcherPathRuleArgs{
							Paths: pulumi.StringArray{
								pulumi.String("/home"),
							},
							Service: static.ID(),
						},
						&compute.URLMapPathMatcherPathRuleArgs{
							Paths: pulumi.StringArray{
								pulumi.String("/login"),
							},
							Service: login.ID(),
						},
						&compute.URLMapPathMatcherPathRuleArgs{
							Paths: pulumi.StringArray{
								pulumi.String("/static"),
							},
							Service: static.ID(),
						},
					},
				},
				&compute.URLMapPathMatcherArgs{
					Name:           pulumi.String("otherpaths"),
					DefaultService: static.ID(),
				},
			},
			Tests: compute.URLMapTestArray{
				&compute.URLMapTestArgs{
					Service: static.ID(),
					Host:    pulumi.String("example.com"),
					Path:    pulumi.String("/home"),
				},
			},
		})
		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.HttpHealthCheck("default", new()
    {
        Name = "health-check",
        RequestPath = "/",
        CheckIntervalSec = 1,
        TimeoutSec = 1,
    });

    var login = new Gcp.Compute.BackendService("login", new()
    {
        Name = "login",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        HealthChecks = @default.Id,
    });

    var staticBucket = new Gcp.Storage.Bucket("static", new()
    {
        Name = "static-asset-bucket",
        Location = "US",
    });

    var @static = new Gcp.Compute.BackendBucket("static", new()
    {
        Name = "static-asset-backend-bucket",
        BucketName = staticBucket.Name,
        EnableCdn = true,
    });

    var urlmap = new Gcp.Compute.URLMap("urlmap", new()
    {
        Name = "urlmap",
        Description = "a description",
        DefaultService = @static.Id,
        HostRules = new[]
        {
            new Gcp.Compute.Inputs.URLMapHostRuleArgs
            {
                Hosts = new[]
                {
                    "mysite.com",
                },
                PathMatcher = "mysite",
            },
            new Gcp.Compute.Inputs.URLMapHostRuleArgs
            {
                Hosts = new[]
                {
                    "myothersite.com",
                },
                PathMatcher = "otherpaths",
            },
        },
        PathMatchers = new[]
        {
            new Gcp.Compute.Inputs.URLMapPathMatcherArgs
            {
                Name = "mysite",
                DefaultService = @static.Id,
                PathRules = new[]
                {
                    new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleArgs
                    {
                        Paths = new[]
                        {
                            "/home",
                        },
                        Service = @static.Id,
                    },
                    new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleArgs
                    {
                        Paths = new[]
                        {
                            "/login",
                        },
                        Service = login.Id,
                    },
                    new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleArgs
                    {
                        Paths = new[]
                        {
                            "/static",
                        },
                        Service = @static.Id,
                    },
                },
            },
            new Gcp.Compute.Inputs.URLMapPathMatcherArgs
            {
                Name = "otherpaths",
                DefaultService = @static.Id,
            },
        },
        Tests = new[]
        {
            new Gcp.Compute.Inputs.URLMapTestArgs
            {
                Service = @static.Id,
                Host = "example.com",
                Path = "/home",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HttpHealthCheck;
import com.pulumi.gcp.compute.HttpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.storage.Bucket;
import com.pulumi.gcp.storage.BucketArgs;
import com.pulumi.gcp.compute.BackendBucket;
import com.pulumi.gcp.compute.BackendBucketArgs;
import com.pulumi.gcp.compute.URLMap;
import com.pulumi.gcp.compute.URLMapArgs;
import com.pulumi.gcp.compute.inputs.URLMapHostRuleArgs;
import com.pulumi.gcp.compute.inputs.URLMapPathMatcherArgs;
import com.pulumi.gcp.compute.inputs.URLMapTestArgs;
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 HttpHealthCheck("default", HttpHealthCheckArgs.builder()
            .name("health-check")
            .requestPath("/")
            .checkIntervalSec(1)
            .timeoutSec(1)
            .build());

        var login = new BackendService("login", BackendServiceArgs.builder()
            .name("login")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .healthChecks(default_.id())
            .build());

        var staticBucket = new Bucket("staticBucket", BucketArgs.builder()
            .name("static-asset-bucket")
            .location("US")
            .build());

        var static_ = new BackendBucket("static", BackendBucketArgs.builder()
            .name("static-asset-backend-bucket")
            .bucketName(staticBucket.name())
            .enableCdn(true)
            .build());

        var urlmap = new URLMap("urlmap", URLMapArgs.builder()
            .name("urlmap")
            .description("a description")
            .defaultService(static_.id())
            .hostRules(            
                URLMapHostRuleArgs.builder()
                    .hosts("mysite.com")
                    .pathMatcher("mysite")
                    .build(),
                URLMapHostRuleArgs.builder()
                    .hosts("myothersite.com")
                    .pathMatcher("otherpaths")
                    .build())
            .pathMatchers(            
                URLMapPathMatcherArgs.builder()
                    .name("mysite")
                    .defaultService(static_.id())
                    .pathRules(                    
                        URLMapPathMatcherPathRuleArgs.builder()
                            .paths("/home")
                            .service(static_.id())
                            .build(),
                        URLMapPathMatcherPathRuleArgs.builder()
                            .paths("/login")
                            .service(login.id())
                            .build(),
                        URLMapPathMatcherPathRuleArgs.builder()
                            .paths("/static")
                            .service(static_.id())
                            .build())
                    .build(),
                URLMapPathMatcherArgs.builder()
                    .name("otherpaths")
                    .defaultService(static_.id())
                    .build())
            .tests(URLMapTestArgs.builder()
                .service(static_.id())
                .host("example.com")
                .path("/home")
                .build())
            .build());

    }
}
resources:
  urlmap:
    type: gcp:compute:URLMap
    properties:
      name: urlmap
      description: a description
      defaultService: ${static.id}
      hostRules:
        - hosts:
            - mysite.com
          pathMatcher: mysite
        - hosts:
            - myothersite.com
          pathMatcher: otherpaths
      pathMatchers:
        - name: mysite
          defaultService: ${static.id}
          pathRules:
            - paths:
                - /home
              service: ${static.id}
            - paths:
                - /login
              service: ${login.id}
            - paths:
                - /static
              service: ${static.id}
        - name: otherpaths
          defaultService: ${static.id}
      tests:
        - service: ${static.id}
          host: example.com
          path: /home
  login:
    type: gcp:compute:BackendService
    properties:
      name: login
      portName: http
      protocol: HTTP
      timeoutSec: 10
      healthChecks: ${default.id}
  default:
    type: gcp:compute:HttpHealthCheck
    properties:
      name: health-check
      requestPath: /
      checkIntervalSec: 1
      timeoutSec: 1
  static:
    type: gcp:compute:BackendBucket
    properties:
      name: static-asset-backend-bucket
      bucketName: ${staticBucket.name}
      enableCdn: true
  staticBucket:
    type: gcp:storage:Bucket
    name: static
    properties:
      name: static-asset-bucket
      location: US

The hostRules array maps hostnames to path matchers. Each pathMatcher defines a defaultService and optional pathRules that route specific paths to different backends. The defaultService handles requests that don’t match any pathRule. This configuration sends requests for /home and /static to a Cloud Storage bucket, while /login goes to a backend service.

Route traffic based on request headers

A/B testing and canary deployments route users to different backend services based on request headers.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const defaultHttpHealthCheck = new gcp.compute.HttpHealthCheck("default", {
    name: "health-check",
    requestPath: "/",
    checkIntervalSec: 1,
    timeoutSec: 1,
});
const _default = new gcp.compute.BackendService("default", {
    name: "default",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    healthChecks: defaultHttpHealthCheck.id,
});
const service_a = new gcp.compute.BackendService("service-a", {
    name: "service-a",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    healthChecks: defaultHttpHealthCheck.id,
});
const service_b = new gcp.compute.BackendService("service-b", {
    name: "service-b",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    healthChecks: defaultHttpHealthCheck.id,
});
const urlmap = new gcp.compute.URLMap("urlmap", {
    name: "urlmap",
    description: "header-based routing example",
    defaultService: _default.id,
    hostRules: [{
        hosts: ["*"],
        pathMatcher: "allpaths",
    }],
    pathMatchers: [{
        name: "allpaths",
        defaultService: _default.id,
        routeRules: [
            {
                priority: 1,
                service: service_a.id,
                matchRules: [{
                    prefixMatch: "/",
                    ignoreCase: true,
                    headerMatches: [{
                        headerName: "abtest",
                        exactMatch: "a",
                    }],
                }],
            },
            {
                priority: 2,
                service: service_b.id,
                matchRules: [{
                    ignoreCase: true,
                    prefixMatch: "/",
                    headerMatches: [{
                        headerName: "abtest",
                        exactMatch: "b",
                    }],
                }],
            },
        ],
    }],
});
import pulumi
import pulumi_gcp as gcp

default_http_health_check = gcp.compute.HttpHealthCheck("default",
    name="health-check",
    request_path="/",
    check_interval_sec=1,
    timeout_sec=1)
default = gcp.compute.BackendService("default",
    name="default",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    health_checks=default_http_health_check.id)
service_a = gcp.compute.BackendService("service-a",
    name="service-a",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    health_checks=default_http_health_check.id)
service_b = gcp.compute.BackendService("service-b",
    name="service-b",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    health_checks=default_http_health_check.id)
urlmap = gcp.compute.URLMap("urlmap",
    name="urlmap",
    description="header-based routing example",
    default_service=default.id,
    host_rules=[{
        "hosts": ["*"],
        "path_matcher": "allpaths",
    }],
    path_matchers=[{
        "name": "allpaths",
        "default_service": default.id,
        "route_rules": [
            {
                "priority": 1,
                "service": service_a.id,
                "match_rules": [{
                    "prefix_match": "/",
                    "ignore_case": True,
                    "header_matches": [{
                        "header_name": "abtest",
                        "exact_match": "a",
                    }],
                }],
            },
            {
                "priority": 2,
                "service": service_b.id,
                "match_rules": [{
                    "ignore_case": True,
                    "prefix_match": "/",
                    "header_matches": [{
                        "header_name": "abtest",
                        "exact_match": "b",
                    }],
                }],
            },
        ],
    }])
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 {
		defaultHttpHealthCheck, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
			Name:             pulumi.String("health-check"),
			RequestPath:      pulumi.String("/"),
			CheckIntervalSec: pulumi.Int(1),
			TimeoutSec:       pulumi.Int(1),
		})
		if err != nil {
			return err
		}
		_default, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
			Name:         pulumi.String("default"),
			PortName:     pulumi.String("http"),
			Protocol:     pulumi.String("HTTP"),
			TimeoutSec:   pulumi.Int(10),
			HealthChecks: defaultHttpHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		service_a, err := compute.NewBackendService(ctx, "service-a", &compute.BackendServiceArgs{
			Name:         pulumi.String("service-a"),
			PortName:     pulumi.String("http"),
			Protocol:     pulumi.String("HTTP"),
			TimeoutSec:   pulumi.Int(10),
			HealthChecks: defaultHttpHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		service_b, err := compute.NewBackendService(ctx, "service-b", &compute.BackendServiceArgs{
			Name:         pulumi.String("service-b"),
			PortName:     pulumi.String("http"),
			Protocol:     pulumi.String("HTTP"),
			TimeoutSec:   pulumi.Int(10),
			HealthChecks: defaultHttpHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewURLMap(ctx, "urlmap", &compute.URLMapArgs{
			Name:           pulumi.String("urlmap"),
			Description:    pulumi.String("header-based routing example"),
			DefaultService: _default.ID(),
			HostRules: compute.URLMapHostRuleArray{
				&compute.URLMapHostRuleArgs{
					Hosts: pulumi.StringArray{
						pulumi.String("*"),
					},
					PathMatcher: pulumi.String("allpaths"),
				},
			},
			PathMatchers: compute.URLMapPathMatcherArray{
				&compute.URLMapPathMatcherArgs{
					Name:           pulumi.String("allpaths"),
					DefaultService: _default.ID(),
					RouteRules: compute.URLMapPathMatcherRouteRuleArray{
						&compute.URLMapPathMatcherRouteRuleArgs{
							Priority: pulumi.Int(1),
							Service:  service_a.ID(),
							MatchRules: compute.URLMapPathMatcherRouteRuleMatchRuleArray{
								&compute.URLMapPathMatcherRouteRuleMatchRuleArgs{
									PrefixMatch: pulumi.String("/"),
									IgnoreCase:  pulumi.Bool(true),
									HeaderMatches: compute.URLMapPathMatcherRouteRuleMatchRuleHeaderMatchArray{
										&compute.URLMapPathMatcherRouteRuleMatchRuleHeaderMatchArgs{
											HeaderName: pulumi.String("abtest"),
											ExactMatch: pulumi.String("a"),
										},
									},
								},
							},
						},
						&compute.URLMapPathMatcherRouteRuleArgs{
							Priority: pulumi.Int(2),
							Service:  service_b.ID(),
							MatchRules: compute.URLMapPathMatcherRouteRuleMatchRuleArray{
								&compute.URLMapPathMatcherRouteRuleMatchRuleArgs{
									IgnoreCase:  pulumi.Bool(true),
									PrefixMatch: pulumi.String("/"),
									HeaderMatches: compute.URLMapPathMatcherRouteRuleMatchRuleHeaderMatchArray{
										&compute.URLMapPathMatcherRouteRuleMatchRuleHeaderMatchArgs{
											HeaderName: pulumi.String("abtest"),
											ExactMatch: pulumi.String("b"),
										},
									},
								},
							},
						},
					},
				},
			},
		})
		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 defaultHttpHealthCheck = new Gcp.Compute.HttpHealthCheck("default", new()
    {
        Name = "health-check",
        RequestPath = "/",
        CheckIntervalSec = 1,
        TimeoutSec = 1,
    });

    var @default = new Gcp.Compute.BackendService("default", new()
    {
        Name = "default",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        HealthChecks = defaultHttpHealthCheck.Id,
    });

    var service_a = new Gcp.Compute.BackendService("service-a", new()
    {
        Name = "service-a",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        HealthChecks = defaultHttpHealthCheck.Id,
    });

    var service_b = new Gcp.Compute.BackendService("service-b", new()
    {
        Name = "service-b",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        HealthChecks = defaultHttpHealthCheck.Id,
    });

    var urlmap = new Gcp.Compute.URLMap("urlmap", new()
    {
        Name = "urlmap",
        Description = "header-based routing example",
        DefaultService = @default.Id,
        HostRules = new[]
        {
            new Gcp.Compute.Inputs.URLMapHostRuleArgs
            {
                Hosts = new[]
                {
                    "*",
                },
                PathMatcher = "allpaths",
            },
        },
        PathMatchers = new[]
        {
            new Gcp.Compute.Inputs.URLMapPathMatcherArgs
            {
                Name = "allpaths",
                DefaultService = @default.Id,
                RouteRules = new[]
                {
                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleArgs
                    {
                        Priority = 1,
                        Service = service_a.Id,
                        MatchRules = new[]
                        {
                            new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleArgs
                            {
                                PrefixMatch = "/",
                                IgnoreCase = true,
                                HeaderMatches = new[]
                                {
                                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleHeaderMatchArgs
                                    {
                                        HeaderName = "abtest",
                                        ExactMatch = "a",
                                    },
                                },
                            },
                        },
                    },
                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleArgs
                    {
                        Priority = 2,
                        Service = service_b.Id,
                        MatchRules = new[]
                        {
                            new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleArgs
                            {
                                IgnoreCase = true,
                                PrefixMatch = "/",
                                HeaderMatches = new[]
                                {
                                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleHeaderMatchArgs
                                    {
                                        HeaderName = "abtest",
                                        ExactMatch = "b",
                                    },
                                },
                            },
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HttpHealthCheck;
import com.pulumi.gcp.compute.HttpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.compute.URLMap;
import com.pulumi.gcp.compute.URLMapArgs;
import com.pulumi.gcp.compute.inputs.URLMapHostRuleArgs;
import com.pulumi.gcp.compute.inputs.URLMapPathMatcherArgs;
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 defaultHttpHealthCheck = new HttpHealthCheck("defaultHttpHealthCheck", HttpHealthCheckArgs.builder()
            .name("health-check")
            .requestPath("/")
            .checkIntervalSec(1)
            .timeoutSec(1)
            .build());

        var default_ = new BackendService("default", BackendServiceArgs.builder()
            .name("default")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .healthChecks(defaultHttpHealthCheck.id())
            .build());

        var service_a = new BackendService("service-a", BackendServiceArgs.builder()
            .name("service-a")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .healthChecks(defaultHttpHealthCheck.id())
            .build());

        var service_b = new BackendService("service-b", BackendServiceArgs.builder()
            .name("service-b")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .healthChecks(defaultHttpHealthCheck.id())
            .build());

        var urlmap = new URLMap("urlmap", URLMapArgs.builder()
            .name("urlmap")
            .description("header-based routing example")
            .defaultService(default_.id())
            .hostRules(URLMapHostRuleArgs.builder()
                .hosts("*")
                .pathMatcher("allpaths")
                .build())
            .pathMatchers(URLMapPathMatcherArgs.builder()
                .name("allpaths")
                .defaultService(default_.id())
                .routeRules(                
                    URLMapPathMatcherRouteRuleArgs.builder()
                        .priority(1)
                        .service(service_a.id())
                        .matchRules(URLMapPathMatcherRouteRuleMatchRuleArgs.builder()
                            .prefixMatch("/")
                            .ignoreCase(true)
                            .headerMatches(URLMapPathMatcherRouteRuleMatchRuleHeaderMatchArgs.builder()
                                .headerName("abtest")
                                .exactMatch("a")
                                .build())
                            .build())
                        .build(),
                    URLMapPathMatcherRouteRuleArgs.builder()
                        .priority(2)
                        .service(service_b.id())
                        .matchRules(URLMapPathMatcherRouteRuleMatchRuleArgs.builder()
                            .ignoreCase(true)
                            .prefixMatch("/")
                            .headerMatches(URLMapPathMatcherRouteRuleMatchRuleHeaderMatchArgs.builder()
                                .headerName("abtest")
                                .exactMatch("b")
                                .build())
                            .build())
                        .build())
                .build())
            .build());

    }
}
resources:
  urlmap:
    type: gcp:compute:URLMap
    properties:
      name: urlmap
      description: header-based routing example
      defaultService: ${default.id}
      hostRules:
        - hosts:
            - '*'
          pathMatcher: allpaths
      pathMatchers:
        - name: allpaths
          defaultService: ${default.id}
          routeRules:
            - priority: 1
              service: ${["service-a"].id}
              matchRules:
                - prefixMatch: /
                  ignoreCase: true
                  headerMatches:
                    - headerName: abtest
                      exactMatch: a
            - priority: 2
              service: ${["service-b"].id}
              matchRules:
                - ignoreCase: true
                  prefixMatch: /
                  headerMatches:
                    - headerName: abtest
                      exactMatch: b
  default:
    type: gcp:compute:BackendService
    properties:
      name: default
      portName: http
      protocol: HTTP
      timeoutSec: 10
      healthChecks: ${defaultHttpHealthCheck.id}
  service-a:
    type: gcp:compute:BackendService
    properties:
      name: service-a
      portName: http
      protocol: HTTP
      timeoutSec: 10
      healthChecks: ${defaultHttpHealthCheck.id}
  service-b:
    type: gcp:compute:BackendService
    properties:
      name: service-b
      portName: http
      protocol: HTTP
      timeoutSec: 10
      healthChecks: ${defaultHttpHealthCheck.id}
  defaultHttpHealthCheck:
    type: gcp:compute:HttpHealthCheck
    name: default
    properties:
      name: health-check
      requestPath: /
      checkIntervalSec: 1
      timeoutSec: 1

Route rules use matchRules to inspect request properties. The headerMatches array checks header values; here, requests with abtest: a go to service-a, while abtest: b goes to service-b. The priority field determines evaluation order (lower numbers first). Route rules provide more flexibility than path rules, enabling header-based, parameter-based, and metadata-based routing.

Route traffic based on query parameters

Query parameter routing enables feature flags and experimentation by inspecting URL parameters.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const defaultHttpHealthCheck = new gcp.compute.HttpHealthCheck("default", {
    name: "health-check",
    requestPath: "/",
    checkIntervalSec: 1,
    timeoutSec: 1,
});
const _default = new gcp.compute.BackendService("default", {
    name: "default",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    healthChecks: defaultHttpHealthCheck.id,
});
const service_a = new gcp.compute.BackendService("service-a", {
    name: "service-a",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    healthChecks: defaultHttpHealthCheck.id,
});
const service_b = new gcp.compute.BackendService("service-b", {
    name: "service-b",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    healthChecks: defaultHttpHealthCheck.id,
});
const urlmap = new gcp.compute.URLMap("urlmap", {
    name: "urlmap",
    description: "parameter-based routing example",
    defaultService: _default.id,
    hostRules: [{
        hosts: ["*"],
        pathMatcher: "allpaths",
    }],
    pathMatchers: [{
        name: "allpaths",
        defaultService: _default.id,
        routeRules: [
            {
                priority: 1,
                service: service_a.id,
                matchRules: [{
                    prefixMatch: "/",
                    ignoreCase: true,
                    queryParameterMatches: [{
                        name: "abtest",
                        exactMatch: "a",
                    }],
                }],
            },
            {
                priority: 2,
                service: service_b.id,
                matchRules: [{
                    ignoreCase: true,
                    prefixMatch: "/",
                    queryParameterMatches: [{
                        name: "abtest",
                        exactMatch: "b",
                    }],
                }],
            },
        ],
    }],
});
import pulumi
import pulumi_gcp as gcp

default_http_health_check = gcp.compute.HttpHealthCheck("default",
    name="health-check",
    request_path="/",
    check_interval_sec=1,
    timeout_sec=1)
default = gcp.compute.BackendService("default",
    name="default",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    health_checks=default_http_health_check.id)
service_a = gcp.compute.BackendService("service-a",
    name="service-a",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    health_checks=default_http_health_check.id)
service_b = gcp.compute.BackendService("service-b",
    name="service-b",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    health_checks=default_http_health_check.id)
urlmap = gcp.compute.URLMap("urlmap",
    name="urlmap",
    description="parameter-based routing example",
    default_service=default.id,
    host_rules=[{
        "hosts": ["*"],
        "path_matcher": "allpaths",
    }],
    path_matchers=[{
        "name": "allpaths",
        "default_service": default.id,
        "route_rules": [
            {
                "priority": 1,
                "service": service_a.id,
                "match_rules": [{
                    "prefix_match": "/",
                    "ignore_case": True,
                    "query_parameter_matches": [{
                        "name": "abtest",
                        "exact_match": "a",
                    }],
                }],
            },
            {
                "priority": 2,
                "service": service_b.id,
                "match_rules": [{
                    "ignore_case": True,
                    "prefix_match": "/",
                    "query_parameter_matches": [{
                        "name": "abtest",
                        "exact_match": "b",
                    }],
                }],
            },
        ],
    }])
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 {
		defaultHttpHealthCheck, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
			Name:             pulumi.String("health-check"),
			RequestPath:      pulumi.String("/"),
			CheckIntervalSec: pulumi.Int(1),
			TimeoutSec:       pulumi.Int(1),
		})
		if err != nil {
			return err
		}
		_default, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
			Name:         pulumi.String("default"),
			PortName:     pulumi.String("http"),
			Protocol:     pulumi.String("HTTP"),
			TimeoutSec:   pulumi.Int(10),
			HealthChecks: defaultHttpHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		service_a, err := compute.NewBackendService(ctx, "service-a", &compute.BackendServiceArgs{
			Name:         pulumi.String("service-a"),
			PortName:     pulumi.String("http"),
			Protocol:     pulumi.String("HTTP"),
			TimeoutSec:   pulumi.Int(10),
			HealthChecks: defaultHttpHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		service_b, err := compute.NewBackendService(ctx, "service-b", &compute.BackendServiceArgs{
			Name:         pulumi.String("service-b"),
			PortName:     pulumi.String("http"),
			Protocol:     pulumi.String("HTTP"),
			TimeoutSec:   pulumi.Int(10),
			HealthChecks: defaultHttpHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewURLMap(ctx, "urlmap", &compute.URLMapArgs{
			Name:           pulumi.String("urlmap"),
			Description:    pulumi.String("parameter-based routing example"),
			DefaultService: _default.ID(),
			HostRules: compute.URLMapHostRuleArray{
				&compute.URLMapHostRuleArgs{
					Hosts: pulumi.StringArray{
						pulumi.String("*"),
					},
					PathMatcher: pulumi.String("allpaths"),
				},
			},
			PathMatchers: compute.URLMapPathMatcherArray{
				&compute.URLMapPathMatcherArgs{
					Name:           pulumi.String("allpaths"),
					DefaultService: _default.ID(),
					RouteRules: compute.URLMapPathMatcherRouteRuleArray{
						&compute.URLMapPathMatcherRouteRuleArgs{
							Priority: pulumi.Int(1),
							Service:  service_a.ID(),
							MatchRules: compute.URLMapPathMatcherRouteRuleMatchRuleArray{
								&compute.URLMapPathMatcherRouteRuleMatchRuleArgs{
									PrefixMatch: pulumi.String("/"),
									IgnoreCase:  pulumi.Bool(true),
									QueryParameterMatches: compute.URLMapPathMatcherRouteRuleMatchRuleQueryParameterMatchArray{
										&compute.URLMapPathMatcherRouteRuleMatchRuleQueryParameterMatchArgs{
											Name:       pulumi.String("abtest"),
											ExactMatch: pulumi.String("a"),
										},
									},
								},
							},
						},
						&compute.URLMapPathMatcherRouteRuleArgs{
							Priority: pulumi.Int(2),
							Service:  service_b.ID(),
							MatchRules: compute.URLMapPathMatcherRouteRuleMatchRuleArray{
								&compute.URLMapPathMatcherRouteRuleMatchRuleArgs{
									IgnoreCase:  pulumi.Bool(true),
									PrefixMatch: pulumi.String("/"),
									QueryParameterMatches: compute.URLMapPathMatcherRouteRuleMatchRuleQueryParameterMatchArray{
										&compute.URLMapPathMatcherRouteRuleMatchRuleQueryParameterMatchArgs{
											Name:       pulumi.String("abtest"),
											ExactMatch: pulumi.String("b"),
										},
									},
								},
							},
						},
					},
				},
			},
		})
		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 defaultHttpHealthCheck = new Gcp.Compute.HttpHealthCheck("default", new()
    {
        Name = "health-check",
        RequestPath = "/",
        CheckIntervalSec = 1,
        TimeoutSec = 1,
    });

    var @default = new Gcp.Compute.BackendService("default", new()
    {
        Name = "default",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        HealthChecks = defaultHttpHealthCheck.Id,
    });

    var service_a = new Gcp.Compute.BackendService("service-a", new()
    {
        Name = "service-a",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        HealthChecks = defaultHttpHealthCheck.Id,
    });

    var service_b = new Gcp.Compute.BackendService("service-b", new()
    {
        Name = "service-b",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        HealthChecks = defaultHttpHealthCheck.Id,
    });

    var urlmap = new Gcp.Compute.URLMap("urlmap", new()
    {
        Name = "urlmap",
        Description = "parameter-based routing example",
        DefaultService = @default.Id,
        HostRules = new[]
        {
            new Gcp.Compute.Inputs.URLMapHostRuleArgs
            {
                Hosts = new[]
                {
                    "*",
                },
                PathMatcher = "allpaths",
            },
        },
        PathMatchers = new[]
        {
            new Gcp.Compute.Inputs.URLMapPathMatcherArgs
            {
                Name = "allpaths",
                DefaultService = @default.Id,
                RouteRules = new[]
                {
                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleArgs
                    {
                        Priority = 1,
                        Service = service_a.Id,
                        MatchRules = new[]
                        {
                            new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleArgs
                            {
                                PrefixMatch = "/",
                                IgnoreCase = true,
                                QueryParameterMatches = new[]
                                {
                                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleQueryParameterMatchArgs
                                    {
                                        Name = "abtest",
                                        ExactMatch = "a",
                                    },
                                },
                            },
                        },
                    },
                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleArgs
                    {
                        Priority = 2,
                        Service = service_b.Id,
                        MatchRules = new[]
                        {
                            new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleArgs
                            {
                                IgnoreCase = true,
                                PrefixMatch = "/",
                                QueryParameterMatches = new[]
                                {
                                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleQueryParameterMatchArgs
                                    {
                                        Name = "abtest",
                                        ExactMatch = "b",
                                    },
                                },
                            },
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HttpHealthCheck;
import com.pulumi.gcp.compute.HttpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.compute.URLMap;
import com.pulumi.gcp.compute.URLMapArgs;
import com.pulumi.gcp.compute.inputs.URLMapHostRuleArgs;
import com.pulumi.gcp.compute.inputs.URLMapPathMatcherArgs;
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 defaultHttpHealthCheck = new HttpHealthCheck("defaultHttpHealthCheck", HttpHealthCheckArgs.builder()
            .name("health-check")
            .requestPath("/")
            .checkIntervalSec(1)
            .timeoutSec(1)
            .build());

        var default_ = new BackendService("default", BackendServiceArgs.builder()
            .name("default")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .healthChecks(defaultHttpHealthCheck.id())
            .build());

        var service_a = new BackendService("service-a", BackendServiceArgs.builder()
            .name("service-a")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .healthChecks(defaultHttpHealthCheck.id())
            .build());

        var service_b = new BackendService("service-b", BackendServiceArgs.builder()
            .name("service-b")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .healthChecks(defaultHttpHealthCheck.id())
            .build());

        var urlmap = new URLMap("urlmap", URLMapArgs.builder()
            .name("urlmap")
            .description("parameter-based routing example")
            .defaultService(default_.id())
            .hostRules(URLMapHostRuleArgs.builder()
                .hosts("*")
                .pathMatcher("allpaths")
                .build())
            .pathMatchers(URLMapPathMatcherArgs.builder()
                .name("allpaths")
                .defaultService(default_.id())
                .routeRules(                
                    URLMapPathMatcherRouteRuleArgs.builder()
                        .priority(1)
                        .service(service_a.id())
                        .matchRules(URLMapPathMatcherRouteRuleMatchRuleArgs.builder()
                            .prefixMatch("/")
                            .ignoreCase(true)
                            .queryParameterMatches(URLMapPathMatcherRouteRuleMatchRuleQueryParameterMatchArgs.builder()
                                .name("abtest")
                                .exactMatch("a")
                                .build())
                            .build())
                        .build(),
                    URLMapPathMatcherRouteRuleArgs.builder()
                        .priority(2)
                        .service(service_b.id())
                        .matchRules(URLMapPathMatcherRouteRuleMatchRuleArgs.builder()
                            .ignoreCase(true)
                            .prefixMatch("/")
                            .queryParameterMatches(URLMapPathMatcherRouteRuleMatchRuleQueryParameterMatchArgs.builder()
                                .name("abtest")
                                .exactMatch("b")
                                .build())
                            .build())
                        .build())
                .build())
            .build());

    }
}
resources:
  urlmap:
    type: gcp:compute:URLMap
    properties:
      name: urlmap
      description: parameter-based routing example
      defaultService: ${default.id}
      hostRules:
        - hosts:
            - '*'
          pathMatcher: allpaths
      pathMatchers:
        - name: allpaths
          defaultService: ${default.id}
          routeRules:
            - priority: 1
              service: ${["service-a"].id}
              matchRules:
                - prefixMatch: /
                  ignoreCase: true
                  queryParameterMatches:
                    - name: abtest
                      exactMatch: a
            - priority: 2
              service: ${["service-b"].id}
              matchRules:
                - ignoreCase: true
                  prefixMatch: /
                  queryParameterMatches:
                    - name: abtest
                      exactMatch: b
  default:
    type: gcp:compute:BackendService
    properties:
      name: default
      portName: http
      protocol: HTTP
      timeoutSec: 10
      healthChecks: ${defaultHttpHealthCheck.id}
  service-a:
    type: gcp:compute:BackendService
    properties:
      name: service-a
      portName: http
      protocol: HTTP
      timeoutSec: 10
      healthChecks: ${defaultHttpHealthCheck.id}
  service-b:
    type: gcp:compute:BackendService
    properties:
      name: service-b
      portName: http
      protocol: HTTP
      timeoutSec: 10
      healthChecks: ${defaultHttpHealthCheck.id}
  defaultHttpHealthCheck:
    type: gcp:compute:HttpHealthCheck
    name: default
    properties:
      name: health-check
      requestPath: /
      checkIntervalSec: 1
      timeoutSec: 1

The queryParameterMatches array works like headerMatches but inspects query strings. Requests with ?abtest=a route to service-a, while ?abtest=b routes to service-b. This enables feature toggling without requiring custom headers or cookies.

Configure advanced routing with Traffic Director

Traffic Director enables service mesh capabilities including header manipulation, redirects, and metadata filtering for internal load balancing.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.compute.HealthCheck("default", {
    name: "health-check",
    httpHealthCheck: {
        port: 80,
    },
});
const home = new gcp.compute.BackendService("home", {
    name: "home",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    healthChecks: _default.id,
    loadBalancingScheme: "INTERNAL_SELF_MANAGED",
});
const urlmap = new gcp.compute.URLMap("urlmap", {
    name: "urlmap",
    description: "a description",
    defaultService: home.id,
    hostRules: [{
        hosts: ["mysite.com"],
        pathMatcher: "allpaths",
    }],
    pathMatchers: [{
        name: "allpaths",
        defaultService: home.id,
        routeRules: [{
            priority: 1,
            headerAction: {
                requestHeadersToRemoves: ["RemoveMe2"],
                requestHeadersToAdds: [{
                    headerName: "AddSomethingElse",
                    headerValue: "MyOtherValue",
                    replace: true,
                }],
                responseHeadersToRemoves: ["RemoveMe3"],
                responseHeadersToAdds: [{
                    headerName: "AddMe",
                    headerValue: "MyValue",
                    replace: false,
                }],
            },
            matchRules: [{
                fullPathMatch: "a full path",
                headerMatches: [{
                    headerName: "someheader",
                    exactMatch: "match this exactly",
                    invertMatch: true,
                }],
                ignoreCase: true,
                metadataFilters: [{
                    filterMatchCriteria: "MATCH_ANY",
                    filterLabels: [{
                        name: "PLANET",
                        value: "MARS",
                    }],
                }],
                queryParameterMatches: [{
                    name: "a query parameter",
                    presentMatch: true,
                }],
            }],
            urlRedirect: {
                hostRedirect: "A host",
                httpsRedirect: false,
                pathRedirect: "some/path",
                redirectResponseCode: "TEMPORARY_REDIRECT",
                stripQuery: true,
            },
        }],
    }],
    tests: [{
        service: home.id,
        host: "hi.com",
        path: "/home",
    }],
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.HealthCheck("default",
    name="health-check",
    http_health_check={
        "port": 80,
    })
home = gcp.compute.BackendService("home",
    name="home",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    health_checks=default.id,
    load_balancing_scheme="INTERNAL_SELF_MANAGED")
urlmap = gcp.compute.URLMap("urlmap",
    name="urlmap",
    description="a description",
    default_service=home.id,
    host_rules=[{
        "hosts": ["mysite.com"],
        "path_matcher": "allpaths",
    }],
    path_matchers=[{
        "name": "allpaths",
        "default_service": home.id,
        "route_rules": [{
            "priority": 1,
            "header_action": {
                "request_headers_to_removes": ["RemoveMe2"],
                "request_headers_to_adds": [{
                    "header_name": "AddSomethingElse",
                    "header_value": "MyOtherValue",
                    "replace": True,
                }],
                "response_headers_to_removes": ["RemoveMe3"],
                "response_headers_to_adds": [{
                    "header_name": "AddMe",
                    "header_value": "MyValue",
                    "replace": False,
                }],
            },
            "match_rules": [{
                "full_path_match": "a full path",
                "header_matches": [{
                    "header_name": "someheader",
                    "exact_match": "match this exactly",
                    "invert_match": True,
                }],
                "ignore_case": True,
                "metadata_filters": [{
                    "filter_match_criteria": "MATCH_ANY",
                    "filter_labels": [{
                        "name": "PLANET",
                        "value": "MARS",
                    }],
                }],
                "query_parameter_matches": [{
                    "name": "a query parameter",
                    "present_match": True,
                }],
            }],
            "url_redirect": {
                "host_redirect": "A host",
                "https_redirect": False,
                "path_redirect": "some/path",
                "redirect_response_code": "TEMPORARY_REDIRECT",
                "strip_query": True,
            },
        }],
    }],
    tests=[{
        "service": home.id,
        "host": "hi.com",
        "path": "/home",
    }])
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.NewHealthCheck(ctx, "default", &compute.HealthCheckArgs{
			Name: pulumi.String("health-check"),
			HttpHealthCheck: &compute.HealthCheckHttpHealthCheckArgs{
				Port: pulumi.Int(80),
			},
		})
		if err != nil {
			return err
		}
		home, err := compute.NewBackendService(ctx, "home", &compute.BackendServiceArgs{
			Name:                pulumi.String("home"),
			PortName:            pulumi.String("http"),
			Protocol:            pulumi.String("HTTP"),
			TimeoutSec:          pulumi.Int(10),
			HealthChecks:        _default.ID(),
			LoadBalancingScheme: pulumi.String("INTERNAL_SELF_MANAGED"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewURLMap(ctx, "urlmap", &compute.URLMapArgs{
			Name:           pulumi.String("urlmap"),
			Description:    pulumi.String("a description"),
			DefaultService: home.ID(),
			HostRules: compute.URLMapHostRuleArray{
				&compute.URLMapHostRuleArgs{
					Hosts: pulumi.StringArray{
						pulumi.String("mysite.com"),
					},
					PathMatcher: pulumi.String("allpaths"),
				},
			},
			PathMatchers: compute.URLMapPathMatcherArray{
				&compute.URLMapPathMatcherArgs{
					Name:           pulumi.String("allpaths"),
					DefaultService: home.ID(),
					RouteRules: compute.URLMapPathMatcherRouteRuleArray{
						&compute.URLMapPathMatcherRouteRuleArgs{
							Priority: pulumi.Int(1),
							HeaderAction: &compute.URLMapPathMatcherRouteRuleHeaderActionArgs{
								RequestHeadersToRemoves: pulumi.StringArray{
									pulumi.String("RemoveMe2"),
								},
								RequestHeadersToAdds: compute.URLMapPathMatcherRouteRuleHeaderActionRequestHeadersToAddArray{
									&compute.URLMapPathMatcherRouteRuleHeaderActionRequestHeadersToAddArgs{
										HeaderName:  pulumi.String("AddSomethingElse"),
										HeaderValue: pulumi.String("MyOtherValue"),
										Replace:     pulumi.Bool(true),
									},
								},
								ResponseHeadersToRemoves: pulumi.StringArray{
									pulumi.String("RemoveMe3"),
								},
								ResponseHeadersToAdds: compute.URLMapPathMatcherRouteRuleHeaderActionResponseHeadersToAddArray{
									&compute.URLMapPathMatcherRouteRuleHeaderActionResponseHeadersToAddArgs{
										HeaderName:  pulumi.String("AddMe"),
										HeaderValue: pulumi.String("MyValue"),
										Replace:     pulumi.Bool(false),
									},
								},
							},
							MatchRules: compute.URLMapPathMatcherRouteRuleMatchRuleArray{
								&compute.URLMapPathMatcherRouteRuleMatchRuleArgs{
									FullPathMatch: pulumi.String("a full path"),
									HeaderMatches: compute.URLMapPathMatcherRouteRuleMatchRuleHeaderMatchArray{
										&compute.URLMapPathMatcherRouteRuleMatchRuleHeaderMatchArgs{
											HeaderName:  pulumi.String("someheader"),
											ExactMatch:  pulumi.String("match this exactly"),
											InvertMatch: pulumi.Bool(true),
										},
									},
									IgnoreCase: pulumi.Bool(true),
									MetadataFilters: compute.URLMapPathMatcherRouteRuleMatchRuleMetadataFilterArray{
										&compute.URLMapPathMatcherRouteRuleMatchRuleMetadataFilterArgs{
											FilterMatchCriteria: pulumi.String("MATCH_ANY"),
											FilterLabels: compute.URLMapPathMatcherRouteRuleMatchRuleMetadataFilterFilterLabelArray{
												&compute.URLMapPathMatcherRouteRuleMatchRuleMetadataFilterFilterLabelArgs{
													Name:  pulumi.String("PLANET"),
													Value: pulumi.String("MARS"),
												},
											},
										},
									},
									QueryParameterMatches: compute.URLMapPathMatcherRouteRuleMatchRuleQueryParameterMatchArray{
										&compute.URLMapPathMatcherRouteRuleMatchRuleQueryParameterMatchArgs{
											Name:         pulumi.String("a query parameter"),
											PresentMatch: pulumi.Bool(true),
										},
									},
								},
							},
							UrlRedirect: &compute.URLMapPathMatcherRouteRuleUrlRedirectArgs{
								HostRedirect:         pulumi.String("A host"),
								HttpsRedirect:        pulumi.Bool(false),
								PathRedirect:         pulumi.String("some/path"),
								RedirectResponseCode: pulumi.String("TEMPORARY_REDIRECT"),
								StripQuery:           pulumi.Bool(true),
							},
						},
					},
				},
			},
			Tests: compute.URLMapTestArray{
				&compute.URLMapTestArgs{
					Service: home.ID(),
					Host:    pulumi.String("hi.com"),
					Path:    pulumi.String("/home"),
				},
			},
		})
		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.HealthCheck("default", new()
    {
        Name = "health-check",
        HttpHealthCheck = new Gcp.Compute.Inputs.HealthCheckHttpHealthCheckArgs
        {
            Port = 80,
        },
    });

    var home = new Gcp.Compute.BackendService("home", new()
    {
        Name = "home",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        HealthChecks = @default.Id,
        LoadBalancingScheme = "INTERNAL_SELF_MANAGED",
    });

    var urlmap = new Gcp.Compute.URLMap("urlmap", new()
    {
        Name = "urlmap",
        Description = "a description",
        DefaultService = home.Id,
        HostRules = new[]
        {
            new Gcp.Compute.Inputs.URLMapHostRuleArgs
            {
                Hosts = new[]
                {
                    "mysite.com",
                },
                PathMatcher = "allpaths",
            },
        },
        PathMatchers = new[]
        {
            new Gcp.Compute.Inputs.URLMapPathMatcherArgs
            {
                Name = "allpaths",
                DefaultService = home.Id,
                RouteRules = new[]
                {
                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleArgs
                    {
                        Priority = 1,
                        HeaderAction = new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleHeaderActionArgs
                        {
                            RequestHeadersToRemoves = new[]
                            {
                                "RemoveMe2",
                            },
                            RequestHeadersToAdds = new[]
                            {
                                new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleHeaderActionRequestHeadersToAddArgs
                                {
                                    HeaderName = "AddSomethingElse",
                                    HeaderValue = "MyOtherValue",
                                    Replace = true,
                                },
                            },
                            ResponseHeadersToRemoves = new[]
                            {
                                "RemoveMe3",
                            },
                            ResponseHeadersToAdds = new[]
                            {
                                new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleHeaderActionResponseHeadersToAddArgs
                                {
                                    HeaderName = "AddMe",
                                    HeaderValue = "MyValue",
                                    Replace = false,
                                },
                            },
                        },
                        MatchRules = new[]
                        {
                            new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleArgs
                            {
                                FullPathMatch = "a full path",
                                HeaderMatches = new[]
                                {
                                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleHeaderMatchArgs
                                    {
                                        HeaderName = "someheader",
                                        ExactMatch = "match this exactly",
                                        InvertMatch = true,
                                    },
                                },
                                IgnoreCase = true,
                                MetadataFilters = new[]
                                {
                                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleMetadataFilterArgs
                                    {
                                        FilterMatchCriteria = "MATCH_ANY",
                                        FilterLabels = new[]
                                        {
                                            new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleMetadataFilterFilterLabelArgs
                                            {
                                                Name = "PLANET",
                                                Value = "MARS",
                                            },
                                        },
                                    },
                                },
                                QueryParameterMatches = new[]
                                {
                                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleQueryParameterMatchArgs
                                    {
                                        Name = "a query parameter",
                                        PresentMatch = true,
                                    },
                                },
                            },
                        },
                        UrlRedirect = new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleUrlRedirectArgs
                        {
                            HostRedirect = "A host",
                            HttpsRedirect = false,
                            PathRedirect = "some/path",
                            RedirectResponseCode = "TEMPORARY_REDIRECT",
                            StripQuery = true,
                        },
                    },
                },
            },
        },
        Tests = new[]
        {
            new Gcp.Compute.Inputs.URLMapTestArgs
            {
                Service = home.Id,
                Host = "hi.com",
                Path = "/home",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HealthCheck;
import com.pulumi.gcp.compute.HealthCheckArgs;
import com.pulumi.gcp.compute.inputs.HealthCheckHttpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.compute.URLMap;
import com.pulumi.gcp.compute.URLMapArgs;
import com.pulumi.gcp.compute.inputs.URLMapHostRuleArgs;
import com.pulumi.gcp.compute.inputs.URLMapPathMatcherArgs;
import com.pulumi.gcp.compute.inputs.URLMapTestArgs;
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 HealthCheck("default", HealthCheckArgs.builder()
            .name("health-check")
            .httpHealthCheck(HealthCheckHttpHealthCheckArgs.builder()
                .port(80)
                .build())
            .build());

        var home = new BackendService("home", BackendServiceArgs.builder()
            .name("home")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .healthChecks(default_.id())
            .loadBalancingScheme("INTERNAL_SELF_MANAGED")
            .build());

        var urlmap = new URLMap("urlmap", URLMapArgs.builder()
            .name("urlmap")
            .description("a description")
            .defaultService(home.id())
            .hostRules(URLMapHostRuleArgs.builder()
                .hosts("mysite.com")
                .pathMatcher("allpaths")
                .build())
            .pathMatchers(URLMapPathMatcherArgs.builder()
                .name("allpaths")
                .defaultService(home.id())
                .routeRules(URLMapPathMatcherRouteRuleArgs.builder()
                    .priority(1)
                    .headerAction(URLMapPathMatcherRouteRuleHeaderActionArgs.builder()
                        .requestHeadersToRemoves("RemoveMe2")
                        .requestHeadersToAdds(URLMapPathMatcherRouteRuleHeaderActionRequestHeadersToAddArgs.builder()
                            .headerName("AddSomethingElse")
                            .headerValue("MyOtherValue")
                            .replace(true)
                            .build())
                        .responseHeadersToRemoves("RemoveMe3")
                        .responseHeadersToAdds(URLMapPathMatcherRouteRuleHeaderActionResponseHeadersToAddArgs.builder()
                            .headerName("AddMe")
                            .headerValue("MyValue")
                            .replace(false)
                            .build())
                        .build())
                    .matchRules(URLMapPathMatcherRouteRuleMatchRuleArgs.builder()
                        .fullPathMatch("a full path")
                        .headerMatches(URLMapPathMatcherRouteRuleMatchRuleHeaderMatchArgs.builder()
                            .headerName("someheader")
                            .exactMatch("match this exactly")
                            .invertMatch(true)
                            .build())
                        .ignoreCase(true)
                        .metadataFilters(URLMapPathMatcherRouteRuleMatchRuleMetadataFilterArgs.builder()
                            .filterMatchCriteria("MATCH_ANY")
                            .filterLabels(URLMapPathMatcherRouteRuleMatchRuleMetadataFilterFilterLabelArgs.builder()
                                .name("PLANET")
                                .value("MARS")
                                .build())
                            .build())
                        .queryParameterMatches(URLMapPathMatcherRouteRuleMatchRuleQueryParameterMatchArgs.builder()
                            .name("a query parameter")
                            .presentMatch(true)
                            .build())
                        .build())
                    .urlRedirect(URLMapPathMatcherRouteRuleUrlRedirectArgs.builder()
                        .hostRedirect("A host")
                        .httpsRedirect(false)
                        .pathRedirect("some/path")
                        .redirectResponseCode("TEMPORARY_REDIRECT")
                        .stripQuery(true)
                        .build())
                    .build())
                .build())
            .tests(URLMapTestArgs.builder()
                .service(home.id())
                .host("hi.com")
                .path("/home")
                .build())
            .build());

    }
}
resources:
  urlmap:
    type: gcp:compute:URLMap
    properties:
      name: urlmap
      description: a description
      defaultService: ${home.id}
      hostRules:
        - hosts:
            - mysite.com
          pathMatcher: allpaths
      pathMatchers:
        - name: allpaths
          defaultService: ${home.id}
          routeRules:
            - priority: 1
              headerAction:
                requestHeadersToRemoves:
                  - RemoveMe2
                requestHeadersToAdds:
                  - headerName: AddSomethingElse
                    headerValue: MyOtherValue
                    replace: true
                responseHeadersToRemoves:
                  - RemoveMe3
                responseHeadersToAdds:
                  - headerName: AddMe
                    headerValue: MyValue
                    replace: false
              matchRules:
                - fullPathMatch: a full path
                  headerMatches:
                    - headerName: someheader
                      exactMatch: match this exactly
                      invertMatch: true
                  ignoreCase: true
                  metadataFilters:
                    - filterMatchCriteria: MATCH_ANY
                      filterLabels:
                        - name: PLANET
                          value: MARS
                  queryParameterMatches:
                    - name: a query parameter
                      presentMatch: true
              urlRedirect:
                hostRedirect: A host
                httpsRedirect: false
                pathRedirect: some/path
                redirectResponseCode: TEMPORARY_REDIRECT
                stripQuery: true
      tests:
        - service: ${home.id}
          host: hi.com
          path: /home
  home:
    type: gcp:compute:BackendService
    properties:
      name: home
      portName: http
      protocol: HTTP
      timeoutSec: 10
      healthChecks: ${default.id}
      loadBalancingScheme: INTERNAL_SELF_MANAGED
  default:
    type: gcp:compute:HealthCheck
    properties:
      name: health-check
      httpHealthCheck:
        port: 80

Route rules can include headerAction to modify request and response headers, urlRedirect to redirect requests, and metadataFilters to match on service mesh metadata. The headerAction adds or removes headers; urlRedirect specifies the redirect target and response code. This example removes headers, adds new ones, and redirects matching requests to a different host and path.

Apply traffic policies with route actions

Route actions enable sophisticated traffic management including CORS policies, fault injection, request mirroring, retries, and URL rewriting.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.compute.HealthCheck("default", {
    name: "health-check",
    httpHealthCheck: {
        port: 80,
    },
});
const home = new gcp.compute.BackendService("home", {
    name: "home",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    healthChecks: _default.id,
    loadBalancingScheme: "INTERNAL_SELF_MANAGED",
});
const urlmap = new gcp.compute.URLMap("urlmap", {
    name: "urlmap",
    description: "a description",
    defaultService: home.id,
    hostRules: [{
        hosts: ["mysite.com"],
        pathMatcher: "allpaths",
    }],
    pathMatchers: [{
        name: "allpaths",
        defaultService: home.id,
        pathRules: [{
            paths: ["/home"],
            routeAction: {
                corsPolicy: {
                    allowCredentials: true,
                    allowHeaders: ["Allowed content"],
                    allowMethods: ["GET"],
                    allowOriginRegexes: ["abc.*"],
                    allowOrigins: ["Allowed origin"],
                    exposeHeaders: ["Exposed header"],
                    maxAge: 30,
                    disabled: false,
                },
                faultInjectionPolicy: {
                    abort: {
                        httpStatus: 234,
                        percentage: 5.6,
                    },
                    delay: {
                        fixedDelay: {
                            seconds: "0",
                            nanos: 50000,
                        },
                        percentage: 7.8,
                    },
                },
                requestMirrorPolicy: {
                    backendService: home.id,
                },
                retryPolicy: {
                    numRetries: 4,
                    perTryTimeout: {
                        seconds: "30",
                    },
                    retryConditions: [
                        "5xx",
                        "deadline-exceeded",
                    ],
                },
                timeout: {
                    seconds: "20",
                    nanos: 750000000,
                },
                urlRewrite: {
                    hostRewrite: "dev.example.com",
                    pathPrefixRewrite: "/v1/api/",
                },
                weightedBackendServices: [{
                    backendService: home.id,
                    weight: 400,
                    headerAction: {
                        requestHeadersToRemoves: ["RemoveMe"],
                        requestHeadersToAdds: [{
                            headerName: "AddMe",
                            headerValue: "MyValue",
                            replace: true,
                        }],
                        responseHeadersToRemoves: ["RemoveMe"],
                        responseHeadersToAdds: [{
                            headerName: "AddMe",
                            headerValue: "MyValue",
                            replace: false,
                        }],
                    },
                }],
            },
        }],
    }],
    tests: [{
        service: home.id,
        host: "hi.com",
        path: "/home",
    }],
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.HealthCheck("default",
    name="health-check",
    http_health_check={
        "port": 80,
    })
home = gcp.compute.BackendService("home",
    name="home",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    health_checks=default.id,
    load_balancing_scheme="INTERNAL_SELF_MANAGED")
urlmap = gcp.compute.URLMap("urlmap",
    name="urlmap",
    description="a description",
    default_service=home.id,
    host_rules=[{
        "hosts": ["mysite.com"],
        "path_matcher": "allpaths",
    }],
    path_matchers=[{
        "name": "allpaths",
        "default_service": home.id,
        "path_rules": [{
            "paths": ["/home"],
            "route_action": {
                "cors_policy": {
                    "allow_credentials": True,
                    "allow_headers": ["Allowed content"],
                    "allow_methods": ["GET"],
                    "allow_origin_regexes": ["abc.*"],
                    "allow_origins": ["Allowed origin"],
                    "expose_headers": ["Exposed header"],
                    "max_age": 30,
                    "disabled": False,
                },
                "fault_injection_policy": {
                    "abort": {
                        "http_status": 234,
                        "percentage": 5.6,
                    },
                    "delay": {
                        "fixed_delay": {
                            "seconds": "0",
                            "nanos": 50000,
                        },
                        "percentage": 7.8,
                    },
                },
                "request_mirror_policy": {
                    "backend_service": home.id,
                },
                "retry_policy": {
                    "num_retries": 4,
                    "per_try_timeout": {
                        "seconds": "30",
                    },
                    "retry_conditions": [
                        "5xx",
                        "deadline-exceeded",
                    ],
                },
                "timeout": {
                    "seconds": "20",
                    "nanos": 750000000,
                },
                "url_rewrite": {
                    "host_rewrite": "dev.example.com",
                    "path_prefix_rewrite": "/v1/api/",
                },
                "weighted_backend_services": [{
                    "backend_service": home.id,
                    "weight": 400,
                    "header_action": {
                        "request_headers_to_removes": ["RemoveMe"],
                        "request_headers_to_adds": [{
                            "header_name": "AddMe",
                            "header_value": "MyValue",
                            "replace": True,
                        }],
                        "response_headers_to_removes": ["RemoveMe"],
                        "response_headers_to_adds": [{
                            "header_name": "AddMe",
                            "header_value": "MyValue",
                            "replace": False,
                        }],
                    },
                }],
            },
        }],
    }],
    tests=[{
        "service": home.id,
        "host": "hi.com",
        "path": "/home",
    }])
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.NewHealthCheck(ctx, "default", &compute.HealthCheckArgs{
			Name: pulumi.String("health-check"),
			HttpHealthCheck: &compute.HealthCheckHttpHealthCheckArgs{
				Port: pulumi.Int(80),
			},
		})
		if err != nil {
			return err
		}
		home, err := compute.NewBackendService(ctx, "home", &compute.BackendServiceArgs{
			Name:                pulumi.String("home"),
			PortName:            pulumi.String("http"),
			Protocol:            pulumi.String("HTTP"),
			TimeoutSec:          pulumi.Int(10),
			HealthChecks:        _default.ID(),
			LoadBalancingScheme: pulumi.String("INTERNAL_SELF_MANAGED"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewURLMap(ctx, "urlmap", &compute.URLMapArgs{
			Name:           pulumi.String("urlmap"),
			Description:    pulumi.String("a description"),
			DefaultService: home.ID(),
			HostRules: compute.URLMapHostRuleArray{
				&compute.URLMapHostRuleArgs{
					Hosts: pulumi.StringArray{
						pulumi.String("mysite.com"),
					},
					PathMatcher: pulumi.String("allpaths"),
				},
			},
			PathMatchers: compute.URLMapPathMatcherArray{
				&compute.URLMapPathMatcherArgs{
					Name:           pulumi.String("allpaths"),
					DefaultService: home.ID(),
					PathRules: compute.URLMapPathMatcherPathRuleArray{
						&compute.URLMapPathMatcherPathRuleArgs{
							Paths: pulumi.StringArray{
								pulumi.String("/home"),
							},
							RouteAction: &compute.URLMapPathMatcherPathRuleRouteActionArgs{
								CorsPolicy: &compute.URLMapPathMatcherPathRuleRouteActionCorsPolicyArgs{
									AllowCredentials: pulumi.Bool(true),
									AllowHeaders: pulumi.StringArray{
										pulumi.String("Allowed content"),
									},
									AllowMethods: pulumi.StringArray{
										pulumi.String("GET"),
									},
									AllowOriginRegexes: pulumi.StringArray{
										pulumi.String("abc.*"),
									},
									AllowOrigins: pulumi.StringArray{
										pulumi.String("Allowed origin"),
									},
									ExposeHeaders: pulumi.StringArray{
										pulumi.String("Exposed header"),
									},
									MaxAge:   pulumi.Int(30),
									Disabled: pulumi.Bool(false),
								},
								FaultInjectionPolicy: &compute.URLMapPathMatcherPathRuleRouteActionFaultInjectionPolicyArgs{
									Abort: &compute.URLMapPathMatcherPathRuleRouteActionFaultInjectionPolicyAbortArgs{
										HttpStatus: pulumi.Int(234),
										Percentage: pulumi.Float64(5.6),
									},
									Delay: &compute.URLMapPathMatcherPathRuleRouteActionFaultInjectionPolicyDelayArgs{
										FixedDelay: &compute.URLMapPathMatcherPathRuleRouteActionFaultInjectionPolicyDelayFixedDelayArgs{
											Seconds: pulumi.String("0"),
											Nanos:   pulumi.Int(50000),
										},
										Percentage: pulumi.Float64(7.8),
									},
								},
								RequestMirrorPolicy: &compute.URLMapPathMatcherPathRuleRouteActionRequestMirrorPolicyArgs{
									BackendService: home.ID(),
								},
								RetryPolicy: &compute.URLMapPathMatcherPathRuleRouteActionRetryPolicyArgs{
									NumRetries: pulumi.Int(4),
									PerTryTimeout: &compute.URLMapPathMatcherPathRuleRouteActionRetryPolicyPerTryTimeoutArgs{
										Seconds: pulumi.String("30"),
									},
									RetryConditions: pulumi.StringArray{
										pulumi.String("5xx"),
										pulumi.String("deadline-exceeded"),
									},
								},
								Timeout: &compute.URLMapPathMatcherPathRuleRouteActionTimeoutArgs{
									Seconds: pulumi.String("20"),
									Nanos:   pulumi.Int(750000000),
								},
								UrlRewrite: &compute.URLMapPathMatcherPathRuleRouteActionUrlRewriteArgs{
									HostRewrite:       pulumi.String("dev.example.com"),
									PathPrefixRewrite: pulumi.String("/v1/api/"),
								},
								WeightedBackendServices: compute.URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceArray{
									&compute.URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceArgs{
										BackendService: home.ID(),
										Weight:         pulumi.Int(400),
										HeaderAction: &compute.URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceHeaderActionArgs{
											RequestHeadersToRemoves: pulumi.StringArray{
												pulumi.String("RemoveMe"),
											},
											RequestHeadersToAdds: compute.URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceHeaderActionRequestHeadersToAddArray{
												&compute.URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceHeaderActionRequestHeadersToAddArgs{
													HeaderName:  pulumi.String("AddMe"),
													HeaderValue: pulumi.String("MyValue"),
													Replace:     pulumi.Bool(true),
												},
											},
											ResponseHeadersToRemoves: pulumi.StringArray{
												pulumi.String("RemoveMe"),
											},
											ResponseHeadersToAdds: compute.URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceHeaderActionResponseHeadersToAddArray{
												&compute.URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceHeaderActionResponseHeadersToAddArgs{
													HeaderName:  pulumi.String("AddMe"),
													HeaderValue: pulumi.String("MyValue"),
													Replace:     pulumi.Bool(false),
												},
											},
										},
									},
								},
							},
						},
					},
				},
			},
			Tests: compute.URLMapTestArray{
				&compute.URLMapTestArgs{
					Service: home.ID(),
					Host:    pulumi.String("hi.com"),
					Path:    pulumi.String("/home"),
				},
			},
		})
		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.HealthCheck("default", new()
    {
        Name = "health-check",
        HttpHealthCheck = new Gcp.Compute.Inputs.HealthCheckHttpHealthCheckArgs
        {
            Port = 80,
        },
    });

    var home = new Gcp.Compute.BackendService("home", new()
    {
        Name = "home",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        HealthChecks = @default.Id,
        LoadBalancingScheme = "INTERNAL_SELF_MANAGED",
    });

    var urlmap = new Gcp.Compute.URLMap("urlmap", new()
    {
        Name = "urlmap",
        Description = "a description",
        DefaultService = home.Id,
        HostRules = new[]
        {
            new Gcp.Compute.Inputs.URLMapHostRuleArgs
            {
                Hosts = new[]
                {
                    "mysite.com",
                },
                PathMatcher = "allpaths",
            },
        },
        PathMatchers = new[]
        {
            new Gcp.Compute.Inputs.URLMapPathMatcherArgs
            {
                Name = "allpaths",
                DefaultService = home.Id,
                PathRules = new[]
                {
                    new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleArgs
                    {
                        Paths = new[]
                        {
                            "/home",
                        },
                        RouteAction = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionArgs
                        {
                            CorsPolicy = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionCorsPolicyArgs
                            {
                                AllowCredentials = true,
                                AllowHeaders = new[]
                                {
                                    "Allowed content",
                                },
                                AllowMethods = new[]
                                {
                                    "GET",
                                },
                                AllowOriginRegexes = new[]
                                {
                                    "abc.*",
                                },
                                AllowOrigins = new[]
                                {
                                    "Allowed origin",
                                },
                                ExposeHeaders = new[]
                                {
                                    "Exposed header",
                                },
                                MaxAge = 30,
                                Disabled = false,
                            },
                            FaultInjectionPolicy = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionFaultInjectionPolicyArgs
                            {
                                Abort = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionFaultInjectionPolicyAbortArgs
                                {
                                    HttpStatus = 234,
                                    Percentage = 5.6,
                                },
                                Delay = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionFaultInjectionPolicyDelayArgs
                                {
                                    FixedDelay = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionFaultInjectionPolicyDelayFixedDelayArgs
                                    {
                                        Seconds = "0",
                                        Nanos = 50000,
                                    },
                                    Percentage = 7.8,
                                },
                            },
                            RequestMirrorPolicy = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionRequestMirrorPolicyArgs
                            {
                                BackendService = home.Id,
                            },
                            RetryPolicy = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionRetryPolicyArgs
                            {
                                NumRetries = 4,
                                PerTryTimeout = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionRetryPolicyPerTryTimeoutArgs
                                {
                                    Seconds = "30",
                                },
                                RetryConditions = new[]
                                {
                                    "5xx",
                                    "deadline-exceeded",
                                },
                            },
                            Timeout = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionTimeoutArgs
                            {
                                Seconds = "20",
                                Nanos = 750000000,
                            },
                            UrlRewrite = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionUrlRewriteArgs
                            {
                                HostRewrite = "dev.example.com",
                                PathPrefixRewrite = "/v1/api/",
                            },
                            WeightedBackendServices = new[]
                            {
                                new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceArgs
                                {
                                    BackendService = home.Id,
                                    Weight = 400,
                                    HeaderAction = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceHeaderActionArgs
                                    {
                                        RequestHeadersToRemoves = new[]
                                        {
                                            "RemoveMe",
                                        },
                                        RequestHeadersToAdds = new[]
                                        {
                                            new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceHeaderActionRequestHeadersToAddArgs
                                            {
                                                HeaderName = "AddMe",
                                                HeaderValue = "MyValue",
                                                Replace = true,
                                            },
                                        },
                                        ResponseHeadersToRemoves = new[]
                                        {
                                            "RemoveMe",
                                        },
                                        ResponseHeadersToAdds = new[]
                                        {
                                            new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceHeaderActionResponseHeadersToAddArgs
                                            {
                                                HeaderName = "AddMe",
                                                HeaderValue = "MyValue",
                                                Replace = false,
                                            },
                                        },
                                    },
                                },
                            },
                        },
                    },
                },
            },
        },
        Tests = new[]
        {
            new Gcp.Compute.Inputs.URLMapTestArgs
            {
                Service = home.Id,
                Host = "hi.com",
                Path = "/home",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HealthCheck;
import com.pulumi.gcp.compute.HealthCheckArgs;
import com.pulumi.gcp.compute.inputs.HealthCheckHttpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.compute.URLMap;
import com.pulumi.gcp.compute.URLMapArgs;
import com.pulumi.gcp.compute.inputs.URLMapHostRuleArgs;
import com.pulumi.gcp.compute.inputs.URLMapPathMatcherArgs;
import com.pulumi.gcp.compute.inputs.URLMapTestArgs;
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 HealthCheck("default", HealthCheckArgs.builder()
            .name("health-check")
            .httpHealthCheck(HealthCheckHttpHealthCheckArgs.builder()
                .port(80)
                .build())
            .build());

        var home = new BackendService("home", BackendServiceArgs.builder()
            .name("home")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .healthChecks(default_.id())
            .loadBalancingScheme("INTERNAL_SELF_MANAGED")
            .build());

        var urlmap = new URLMap("urlmap", URLMapArgs.builder()
            .name("urlmap")
            .description("a description")
            .defaultService(home.id())
            .hostRules(URLMapHostRuleArgs.builder()
                .hosts("mysite.com")
                .pathMatcher("allpaths")
                .build())
            .pathMatchers(URLMapPathMatcherArgs.builder()
                .name("allpaths")
                .defaultService(home.id())
                .pathRules(URLMapPathMatcherPathRuleArgs.builder()
                    .paths("/home")
                    .routeAction(URLMapPathMatcherPathRuleRouteActionArgs.builder()
                        .corsPolicy(URLMapPathMatcherPathRuleRouteActionCorsPolicyArgs.builder()
                            .allowCredentials(true)
                            .allowHeaders("Allowed content")
                            .allowMethods("GET")
                            .allowOriginRegexes("abc.*")
                            .allowOrigins("Allowed origin")
                            .exposeHeaders("Exposed header")
                            .maxAge(30)
                            .disabled(false)
                            .build())
                        .faultInjectionPolicy(URLMapPathMatcherPathRuleRouteActionFaultInjectionPolicyArgs.builder()
                            .abort(URLMapPathMatcherPathRuleRouteActionFaultInjectionPolicyAbortArgs.builder()
                                .httpStatus(234)
                                .percentage(5.6)
                                .build())
                            .delay(URLMapPathMatcherPathRuleRouteActionFaultInjectionPolicyDelayArgs.builder()
                                .fixedDelay(URLMapPathMatcherPathRuleRouteActionFaultInjectionPolicyDelayFixedDelayArgs.builder()
                                    .seconds("0")
                                    .nanos(50000)
                                    .build())
                                .percentage(7.8)
                                .build())
                            .build())
                        .requestMirrorPolicy(URLMapPathMatcherPathRuleRouteActionRequestMirrorPolicyArgs.builder()
                            .backendService(home.id())
                            .build())
                        .retryPolicy(URLMapPathMatcherPathRuleRouteActionRetryPolicyArgs.builder()
                            .numRetries(4)
                            .perTryTimeout(URLMapPathMatcherPathRuleRouteActionRetryPolicyPerTryTimeoutArgs.builder()
                                .seconds("30")
                                .build())
                            .retryConditions(                            
                                "5xx",
                                "deadline-exceeded")
                            .build())
                        .timeout(URLMapPathMatcherPathRuleRouteActionTimeoutArgs.builder()
                            .seconds("20")
                            .nanos(750000000)
                            .build())
                        .urlRewrite(URLMapPathMatcherPathRuleRouteActionUrlRewriteArgs.builder()
                            .hostRewrite("dev.example.com")
                            .pathPrefixRewrite("/v1/api/")
                            .build())
                        .weightedBackendServices(URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceArgs.builder()
                            .backendService(home.id())
                            .weight(400)
                            .headerAction(URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceHeaderActionArgs.builder()
                                .requestHeadersToRemoves("RemoveMe")
                                .requestHeadersToAdds(URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceHeaderActionRequestHeadersToAddArgs.builder()
                                    .headerName("AddMe")
                                    .headerValue("MyValue")
                                    .replace(true)
                                    .build())
                                .responseHeadersToRemoves("RemoveMe")
                                .responseHeadersToAdds(URLMapPathMatcherPathRuleRouteActionWeightedBackendServiceHeaderActionResponseHeadersToAddArgs.builder()
                                    .headerName("AddMe")
                                    .headerValue("MyValue")
                                    .replace(false)
                                    .build())
                                .build())
                            .build())
                        .build())
                    .build())
                .build())
            .tests(URLMapTestArgs.builder()
                .service(home.id())
                .host("hi.com")
                .path("/home")
                .build())
            .build());

    }
}
resources:
  urlmap:
    type: gcp:compute:URLMap
    properties:
      name: urlmap
      description: a description
      defaultService: ${home.id}
      hostRules:
        - hosts:
            - mysite.com
          pathMatcher: allpaths
      pathMatchers:
        - name: allpaths
          defaultService: ${home.id}
          pathRules:
            - paths:
                - /home
              routeAction:
                corsPolicy:
                  allowCredentials: true
                  allowHeaders:
                    - Allowed content
                  allowMethods:
                    - GET
                  allowOriginRegexes:
                    - abc.*
                  allowOrigins:
                    - Allowed origin
                  exposeHeaders:
                    - Exposed header
                  maxAge: 30
                  disabled: false
                faultInjectionPolicy:
                  abort:
                    httpStatus: 234
                    percentage: 5.6
                  delay:
                    fixedDelay:
                      seconds: 0
                      nanos: 50000
                    percentage: 7.8
                requestMirrorPolicy:
                  backendService: ${home.id}
                retryPolicy:
                  numRetries: 4
                  perTryTimeout:
                    seconds: 30
                  retryConditions:
                    - 5xx
                    - deadline-exceeded
                timeout:
                  seconds: 20
                  nanos: 7.5e+08
                urlRewrite:
                  hostRewrite: dev.example.com
                  pathPrefixRewrite: /v1/api/
                weightedBackendServices:
                  - backendService: ${home.id}
                    weight: 400
                    headerAction:
                      requestHeadersToRemoves:
                        - RemoveMe
                      requestHeadersToAdds:
                        - headerName: AddMe
                          headerValue: MyValue
                          replace: true
                      responseHeadersToRemoves:
                        - RemoveMe
                      responseHeadersToAdds:
                        - headerName: AddMe
                          headerValue: MyValue
                          replace: false
      tests:
        - service: ${home.id}
          host: hi.com
          path: /home
  home:
    type: gcp:compute:BackendService
    properties:
      name: home
      portName: http
      protocol: HTTP
      timeoutSec: 10
      healthChecks: ${default.id}
      loadBalancingScheme: INTERNAL_SELF_MANAGED
  default:
    type: gcp:compute:HealthCheck
    properties:
      name: health-check
      httpHealthCheck:
        port: 80

The routeAction property configures advanced behaviors. The corsPolicy enables cross-origin requests with specific headers and methods. The faultInjectionPolicy simulates failures for testing. The retryPolicy configures automatic retries with backoff. The urlRewrite modifies the request before forwarding. The weightedBackendServices array distributes traffic across backends with weights.

Match and rewrite paths using templates

Path templates enable pattern matching with variable extraction, allowing you to capture URL segments and rewrite them for backend services.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.compute.HttpHealthCheck("default", {
    name: "health-check",
    requestPath: "/",
    checkIntervalSec: 1,
    timeoutSec: 1,
});
const cart_backend = new gcp.compute.BackendService("cart-backend", {
    name: "cart-service",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    loadBalancingScheme: "EXTERNAL_MANAGED",
    healthChecks: _default.id,
});
const user_backend = new gcp.compute.BackendService("user-backend", {
    name: "user-service",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    loadBalancingScheme: "EXTERNAL_MANAGED",
    healthChecks: _default.id,
});
const staticBucket = new gcp.storage.Bucket("static", {
    name: "static-asset-bucket",
    location: "US",
});
const static = new gcp.compute.BackendBucket("static", {
    name: "static-asset-backend-bucket",
    bucketName: staticBucket.name,
    enableCdn: true,
});
const urlmap = new gcp.compute.URLMap("urlmap", {
    name: "urlmap",
    description: "a description",
    defaultService: static.id,
    hostRules: [{
        hosts: ["mysite.com"],
        pathMatcher: "mysite",
    }],
    pathMatchers: [{
        name: "mysite",
        defaultService: static.id,
        routeRules: [
            {
                matchRules: [{
                    pathTemplateMatch: "/xyzwebservices/v2/xyz/users/{username=*}/carts/{cartid=**}",
                }],
                service: cart_backend.id,
                priority: 1,
                routeAction: {
                    urlRewrite: {
                        pathTemplateRewrite: "/{username}-{cartid}/",
                    },
                },
            },
            {
                matchRules: [{
                    pathTemplateMatch: "/xyzwebservices/v2/xyz/users/*/accountinfo/*",
                }],
                service: user_backend.id,
                priority: 2,
            },
        ],
    }],
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.HttpHealthCheck("default",
    name="health-check",
    request_path="/",
    check_interval_sec=1,
    timeout_sec=1)
cart_backend = gcp.compute.BackendService("cart-backend",
    name="cart-service",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    load_balancing_scheme="EXTERNAL_MANAGED",
    health_checks=default.id)
user_backend = gcp.compute.BackendService("user-backend",
    name="user-service",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    load_balancing_scheme="EXTERNAL_MANAGED",
    health_checks=default.id)
static_bucket = gcp.storage.Bucket("static",
    name="static-asset-bucket",
    location="US")
static = gcp.compute.BackendBucket("static",
    name="static-asset-backend-bucket",
    bucket_name=static_bucket.name,
    enable_cdn=True)
urlmap = gcp.compute.URLMap("urlmap",
    name="urlmap",
    description="a description",
    default_service=static.id,
    host_rules=[{
        "hosts": ["mysite.com"],
        "path_matcher": "mysite",
    }],
    path_matchers=[{
        "name": "mysite",
        "default_service": static.id,
        "route_rules": [
            {
                "match_rules": [{
                    "path_template_match": "/xyzwebservices/v2/xyz/users/{username=*}/carts/{cartid=**}",
                }],
                "service": cart_backend.id,
                "priority": 1,
                "route_action": {
                    "url_rewrite": {
                        "path_template_rewrite": "/{username}-{cartid}/",
                    },
                },
            },
            {
                "match_rules": [{
                    "path_template_match": "/xyzwebservices/v2/xyz/users/*/accountinfo/*",
                }],
                "service": user_backend.id,
                "priority": 2,
            },
        ],
    }])
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/storage"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
			Name:             pulumi.String("health-check"),
			RequestPath:      pulumi.String("/"),
			CheckIntervalSec: pulumi.Int(1),
			TimeoutSec:       pulumi.Int(1),
		})
		if err != nil {
			return err
		}
		cart_backend, err := compute.NewBackendService(ctx, "cart-backend", &compute.BackendServiceArgs{
			Name:                pulumi.String("cart-service"),
			PortName:            pulumi.String("http"),
			Protocol:            pulumi.String("HTTP"),
			TimeoutSec:          pulumi.Int(10),
			LoadBalancingScheme: pulumi.String("EXTERNAL_MANAGED"),
			HealthChecks:        _default.ID(),
		})
		if err != nil {
			return err
		}
		user_backend, err := compute.NewBackendService(ctx, "user-backend", &compute.BackendServiceArgs{
			Name:                pulumi.String("user-service"),
			PortName:            pulumi.String("http"),
			Protocol:            pulumi.String("HTTP"),
			TimeoutSec:          pulumi.Int(10),
			LoadBalancingScheme: pulumi.String("EXTERNAL_MANAGED"),
			HealthChecks:        _default.ID(),
		})
		if err != nil {
			return err
		}
		staticBucket, err := storage.NewBucket(ctx, "static", &storage.BucketArgs{
			Name:     pulumi.String("static-asset-bucket"),
			Location: pulumi.String("US"),
		})
		if err != nil {
			return err
		}
		static, err := compute.NewBackendBucket(ctx, "static", &compute.BackendBucketArgs{
			Name:       pulumi.String("static-asset-backend-bucket"),
			BucketName: staticBucket.Name,
			EnableCdn:  pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewURLMap(ctx, "urlmap", &compute.URLMapArgs{
			Name:           pulumi.String("urlmap"),
			Description:    pulumi.String("a description"),
			DefaultService: static.ID(),
			HostRules: compute.URLMapHostRuleArray{
				&compute.URLMapHostRuleArgs{
					Hosts: pulumi.StringArray{
						pulumi.String("mysite.com"),
					},
					PathMatcher: pulumi.String("mysite"),
				},
			},
			PathMatchers: compute.URLMapPathMatcherArray{
				&compute.URLMapPathMatcherArgs{
					Name:           pulumi.String("mysite"),
					DefaultService: static.ID(),
					RouteRules: compute.URLMapPathMatcherRouteRuleArray{
						&compute.URLMapPathMatcherRouteRuleArgs{
							MatchRules: compute.URLMapPathMatcherRouteRuleMatchRuleArray{
								&compute.URLMapPathMatcherRouteRuleMatchRuleArgs{
									PathTemplateMatch: pulumi.String("/xyzwebservices/v2/xyz/users/{username=*}/carts/{cartid=**}"),
								},
							},
							Service:  cart_backend.ID(),
							Priority: pulumi.Int(1),
							RouteAction: &compute.URLMapPathMatcherRouteRuleRouteActionArgs{
								UrlRewrite: &compute.URLMapPathMatcherRouteRuleRouteActionUrlRewriteArgs{
									PathTemplateRewrite: pulumi.String("/{username}-{cartid}/"),
								},
							},
						},
						&compute.URLMapPathMatcherRouteRuleArgs{
							MatchRules: compute.URLMapPathMatcherRouteRuleMatchRuleArray{
								&compute.URLMapPathMatcherRouteRuleMatchRuleArgs{
									PathTemplateMatch: pulumi.String("/xyzwebservices/v2/xyz/users/*/accountinfo/*"),
								},
							},
							Service:  user_backend.ID(),
							Priority: pulumi.Int(2),
						},
					},
				},
			},
		})
		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.HttpHealthCheck("default", new()
    {
        Name = "health-check",
        RequestPath = "/",
        CheckIntervalSec = 1,
        TimeoutSec = 1,
    });

    var cart_backend = new Gcp.Compute.BackendService("cart-backend", new()
    {
        Name = "cart-service",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        LoadBalancingScheme = "EXTERNAL_MANAGED",
        HealthChecks = @default.Id,
    });

    var user_backend = new Gcp.Compute.BackendService("user-backend", new()
    {
        Name = "user-service",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        LoadBalancingScheme = "EXTERNAL_MANAGED",
        HealthChecks = @default.Id,
    });

    var staticBucket = new Gcp.Storage.Bucket("static", new()
    {
        Name = "static-asset-bucket",
        Location = "US",
    });

    var @static = new Gcp.Compute.BackendBucket("static", new()
    {
        Name = "static-asset-backend-bucket",
        BucketName = staticBucket.Name,
        EnableCdn = true,
    });

    var urlmap = new Gcp.Compute.URLMap("urlmap", new()
    {
        Name = "urlmap",
        Description = "a description",
        DefaultService = @static.Id,
        HostRules = new[]
        {
            new Gcp.Compute.Inputs.URLMapHostRuleArgs
            {
                Hosts = new[]
                {
                    "mysite.com",
                },
                PathMatcher = "mysite",
            },
        },
        PathMatchers = new[]
        {
            new Gcp.Compute.Inputs.URLMapPathMatcherArgs
            {
                Name = "mysite",
                DefaultService = @static.Id,
                RouteRules = new[]
                {
                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleArgs
                    {
                        MatchRules = new[]
                        {
                            new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleArgs
                            {
                                PathTemplateMatch = "/xyzwebservices/v2/xyz/users/{username=*}/carts/{cartid=**}",
                            },
                        },
                        Service = cart_backend.Id,
                        Priority = 1,
                        RouteAction = new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleRouteActionArgs
                        {
                            UrlRewrite = new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleRouteActionUrlRewriteArgs
                            {
                                PathTemplateRewrite = "/{username}-{cartid}/",
                            },
                        },
                    },
                    new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleArgs
                    {
                        MatchRules = new[]
                        {
                            new Gcp.Compute.Inputs.URLMapPathMatcherRouteRuleMatchRuleArgs
                            {
                                PathTemplateMatch = "/xyzwebservices/v2/xyz/users/*/accountinfo/*",
                            },
                        },
                        Service = user_backend.Id,
                        Priority = 2,
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HttpHealthCheck;
import com.pulumi.gcp.compute.HttpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.storage.Bucket;
import com.pulumi.gcp.storage.BucketArgs;
import com.pulumi.gcp.compute.BackendBucket;
import com.pulumi.gcp.compute.BackendBucketArgs;
import com.pulumi.gcp.compute.URLMap;
import com.pulumi.gcp.compute.URLMapArgs;
import com.pulumi.gcp.compute.inputs.URLMapHostRuleArgs;
import com.pulumi.gcp.compute.inputs.URLMapPathMatcherArgs;
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 HttpHealthCheck("default", HttpHealthCheckArgs.builder()
            .name("health-check")
            .requestPath("/")
            .checkIntervalSec(1)
            .timeoutSec(1)
            .build());

        var cart_backend = new BackendService("cart-backend", BackendServiceArgs.builder()
            .name("cart-service")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .loadBalancingScheme("EXTERNAL_MANAGED")
            .healthChecks(default_.id())
            .build());

        var user_backend = new BackendService("user-backend", BackendServiceArgs.builder()
            .name("user-service")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .loadBalancingScheme("EXTERNAL_MANAGED")
            .healthChecks(default_.id())
            .build());

        var staticBucket = new Bucket("staticBucket", BucketArgs.builder()
            .name("static-asset-bucket")
            .location("US")
            .build());

        var static_ = new BackendBucket("static", BackendBucketArgs.builder()
            .name("static-asset-backend-bucket")
            .bucketName(staticBucket.name())
            .enableCdn(true)
            .build());

        var urlmap = new URLMap("urlmap", URLMapArgs.builder()
            .name("urlmap")
            .description("a description")
            .defaultService(static_.id())
            .hostRules(URLMapHostRuleArgs.builder()
                .hosts("mysite.com")
                .pathMatcher("mysite")
                .build())
            .pathMatchers(URLMapPathMatcherArgs.builder()
                .name("mysite")
                .defaultService(static_.id())
                .routeRules(                
                    URLMapPathMatcherRouteRuleArgs.builder()
                        .matchRules(URLMapPathMatcherRouteRuleMatchRuleArgs.builder()
                            .pathTemplateMatch("/xyzwebservices/v2/xyz/users/{username=*}/carts/{cartid=**}")
                            .build())
                        .service(cart_backend.id())
                        .priority(1)
                        .routeAction(URLMapPathMatcherRouteRuleRouteActionArgs.builder()
                            .urlRewrite(URLMapPathMatcherRouteRuleRouteActionUrlRewriteArgs.builder()
                                .pathTemplateRewrite("/{username}-{cartid}/")
                                .build())
                            .build())
                        .build(),
                    URLMapPathMatcherRouteRuleArgs.builder()
                        .matchRules(URLMapPathMatcherRouteRuleMatchRuleArgs.builder()
                            .pathTemplateMatch("/xyzwebservices/v2/xyz/users/*/accountinfo/*")
                            .build())
                        .service(user_backend.id())
                        .priority(2)
                        .build())
                .build())
            .build());

    }
}
resources:
  urlmap:
    type: gcp:compute:URLMap
    properties:
      name: urlmap
      description: a description
      defaultService: ${static.id}
      hostRules:
        - hosts:
            - mysite.com
          pathMatcher: mysite
      pathMatchers:
        - name: mysite
          defaultService: ${static.id}
          routeRules:
            - matchRules:
                - pathTemplateMatch: /xyzwebservices/v2/xyz/users/{username=*}/carts/{cartid=**}
              service: ${["cart-backend"].id}
              priority: 1
              routeAction:
                urlRewrite:
                  pathTemplateRewrite: /{username}-{cartid}/
            - matchRules:
                - pathTemplateMatch: /xyzwebservices/v2/xyz/users/*/accountinfo/*
              service: ${["user-backend"].id}
              priority: 2
  cart-backend:
    type: gcp:compute:BackendService
    properties:
      name: cart-service
      portName: http
      protocol: HTTP
      timeoutSec: 10
      loadBalancingScheme: EXTERNAL_MANAGED
      healthChecks: ${default.id}
  user-backend:
    type: gcp:compute:BackendService
    properties:
      name: user-service
      portName: http
      protocol: HTTP
      timeoutSec: 10
      loadBalancingScheme: EXTERNAL_MANAGED
      healthChecks: ${default.id}
  default:
    type: gcp:compute:HttpHealthCheck
    properties:
      name: health-check
      requestPath: /
      checkIntervalSec: 1
      timeoutSec: 1
  static:
    type: gcp:compute:BackendBucket
    properties:
      name: static-asset-backend-bucket
      bucketName: ${staticBucket.name}
      enableCdn: true
  staticBucket:
    type: gcp:storage:Bucket
    name: static
    properties:
      name: static-asset-bucket
      location: US

The pathTemplateMatch property uses a template syntax with wildcards (* for single segment, ** for multiple segments) and named variables ({username=*}). The pathTemplateRewrite property references these variables to construct new paths. This example captures username and cart ID from the URL and rewrites the path to /{username}-{cartid}/ before forwarding to the backend.

Customize error responses at multiple levels

When backend services return errors, you can serve custom error pages from Cloud Storage instead of default error responses.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const _default = new gcp.compute.HttpHealthCheck("default", {
    name: "health-check",
    requestPath: "/",
    checkIntervalSec: 1,
    timeoutSec: 1,
});
const example = new gcp.compute.BackendService("example", {
    name: "login",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    loadBalancingScheme: "EXTERNAL_MANAGED",
    healthChecks: _default.id,
});
const errorBucket = new gcp.storage.Bucket("error", {
    name: "static-asset-bucket",
    location: "US",
});
const error = new gcp.compute.BackendBucket("error", {
    name: "error-backend-bucket",
    bucketName: errorBucket.name,
    enableCdn: true,
});
const urlmap = new gcp.compute.URLMap("urlmap", {
    name: "urlmap",
    description: "a description",
    defaultService: example.id,
    defaultCustomErrorResponsePolicy: {
        errorResponseRules: [{
            matchResponseCodes: ["5xx"],
            path: "/internal_error.html",
            overrideResponseCode: 502,
        }],
        errorService: error.id,
    },
    hostRules: [{
        hosts: ["mysite.com"],
        pathMatcher: "mysite",
    }],
    pathMatchers: [{
        name: "mysite",
        defaultService: example.id,
        defaultCustomErrorResponsePolicy: {
            errorResponseRules: [
                {
                    matchResponseCodes: [
                        "4xx",
                        "5xx",
                    ],
                    path: "/login_error.html",
                    overrideResponseCode: 404,
                },
                {
                    matchResponseCodes: ["503"],
                    path: "/bad_gateway.html",
                    overrideResponseCode: 502,
                },
            ],
            errorService: error.id,
        },
        pathRules: [{
            paths: ["/private/*"],
            service: example.id,
            customErrorResponsePolicy: {
                errorResponseRules: [{
                    matchResponseCodes: ["4xx"],
                    path: "/login.html",
                    overrideResponseCode: 401,
                }],
                errorService: error.id,
            },
        }],
    }],
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.HttpHealthCheck("default",
    name="health-check",
    request_path="/",
    check_interval_sec=1,
    timeout_sec=1)
example = gcp.compute.BackendService("example",
    name="login",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    load_balancing_scheme="EXTERNAL_MANAGED",
    health_checks=default.id)
error_bucket = gcp.storage.Bucket("error",
    name="static-asset-bucket",
    location="US")
error = gcp.compute.BackendBucket("error",
    name="error-backend-bucket",
    bucket_name=error_bucket.name,
    enable_cdn=True)
urlmap = gcp.compute.URLMap("urlmap",
    name="urlmap",
    description="a description",
    default_service=example.id,
    default_custom_error_response_policy={
        "error_response_rules": [{
            "match_response_codes": ["5xx"],
            "path": "/internal_error.html",
            "override_response_code": 502,
        }],
        "error_service": error.id,
    },
    host_rules=[{
        "hosts": ["mysite.com"],
        "path_matcher": "mysite",
    }],
    path_matchers=[{
        "name": "mysite",
        "default_service": example.id,
        "default_custom_error_response_policy": {
            "error_response_rules": [
                {
                    "match_response_codes": [
                        "4xx",
                        "5xx",
                    ],
                    "path": "/login_error.html",
                    "override_response_code": 404,
                },
                {
                    "match_response_codes": ["503"],
                    "path": "/bad_gateway.html",
                    "override_response_code": 502,
                },
            ],
            "error_service": error.id,
        },
        "path_rules": [{
            "paths": ["/private/*"],
            "service": example.id,
            "custom_error_response_policy": {
                "error_response_rules": [{
                    "match_response_codes": ["4xx"],
                    "path": "/login.html",
                    "override_response_code": 401,
                }],
                "error_service": error.id,
            },
        }],
    }])
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/storage"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
			Name:             pulumi.String("health-check"),
			RequestPath:      pulumi.String("/"),
			CheckIntervalSec: pulumi.Int(1),
			TimeoutSec:       pulumi.Int(1),
		})
		if err != nil {
			return err
		}
		example, err := compute.NewBackendService(ctx, "example", &compute.BackendServiceArgs{
			Name:                pulumi.String("login"),
			PortName:            pulumi.String("http"),
			Protocol:            pulumi.String("HTTP"),
			TimeoutSec:          pulumi.Int(10),
			LoadBalancingScheme: pulumi.String("EXTERNAL_MANAGED"),
			HealthChecks:        _default.ID(),
		})
		if err != nil {
			return err
		}
		errorBucket, err := storage.NewBucket(ctx, "error", &storage.BucketArgs{
			Name:     pulumi.String("static-asset-bucket"),
			Location: pulumi.String("US"),
		})
		if err != nil {
			return err
		}
		error, err := compute.NewBackendBucket(ctx, "error", &compute.BackendBucketArgs{
			Name:       pulumi.String("error-backend-bucket"),
			BucketName: errorBucket.Name,
			EnableCdn:  pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewURLMap(ctx, "urlmap", &compute.URLMapArgs{
			Name:           pulumi.String("urlmap"),
			Description:    pulumi.String("a description"),
			DefaultService: example.ID(),
			DefaultCustomErrorResponsePolicy: &compute.URLMapDefaultCustomErrorResponsePolicyArgs{
				ErrorResponseRules: compute.URLMapDefaultCustomErrorResponsePolicyErrorResponseRuleArray{
					&compute.URLMapDefaultCustomErrorResponsePolicyErrorResponseRuleArgs{
						MatchResponseCodes: pulumi.StringArray{
							pulumi.String("5xx"),
						},
						Path:                 pulumi.String("/internal_error.html"),
						OverrideResponseCode: pulumi.Int(502),
					},
				},
				ErrorService: error.ID(),
			},
			HostRules: compute.URLMapHostRuleArray{
				&compute.URLMapHostRuleArgs{
					Hosts: pulumi.StringArray{
						pulumi.String("mysite.com"),
					},
					PathMatcher: pulumi.String("mysite"),
				},
			},
			PathMatchers: compute.URLMapPathMatcherArray{
				&compute.URLMapPathMatcherArgs{
					Name:           pulumi.String("mysite"),
					DefaultService: example.ID(),
					DefaultCustomErrorResponsePolicy: &compute.URLMapPathMatcherDefaultCustomErrorResponsePolicyArgs{
						ErrorResponseRules: compute.URLMapPathMatcherDefaultCustomErrorResponsePolicyErrorResponseRuleArray{
							&compute.URLMapPathMatcherDefaultCustomErrorResponsePolicyErrorResponseRuleArgs{
								MatchResponseCodes: pulumi.StringArray{
									pulumi.String("4xx"),
									pulumi.String("5xx"),
								},
								Path:                 pulumi.String("/login_error.html"),
								OverrideResponseCode: pulumi.Int(404),
							},
							&compute.URLMapPathMatcherDefaultCustomErrorResponsePolicyErrorResponseRuleArgs{
								MatchResponseCodes: pulumi.StringArray{
									pulumi.String("503"),
								},
								Path:                 pulumi.String("/bad_gateway.html"),
								OverrideResponseCode: pulumi.Int(502),
							},
						},
						ErrorService: error.ID(),
					},
					PathRules: compute.URLMapPathMatcherPathRuleArray{
						&compute.URLMapPathMatcherPathRuleArgs{
							Paths: pulumi.StringArray{
								pulumi.String("/private/*"),
							},
							Service: example.ID(),
							CustomErrorResponsePolicy: &compute.URLMapPathMatcherPathRuleCustomErrorResponsePolicyArgs{
								ErrorResponseRules: compute.URLMapPathMatcherPathRuleCustomErrorResponsePolicyErrorResponseRuleArray{
									&compute.URLMapPathMatcherPathRuleCustomErrorResponsePolicyErrorResponseRuleArgs{
										MatchResponseCodes: pulumi.StringArray{
											pulumi.String("4xx"),
										},
										Path:                 pulumi.String("/login.html"),
										OverrideResponseCode: pulumi.Int(401),
									},
								},
								ErrorService: error.ID(),
							},
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.Compute.HttpHealthCheck("default", new()
    {
        Name = "health-check",
        RequestPath = "/",
        CheckIntervalSec = 1,
        TimeoutSec = 1,
    });

    var example = new Gcp.Compute.BackendService("example", new()
    {
        Name = "login",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        LoadBalancingScheme = "EXTERNAL_MANAGED",
        HealthChecks = @default.Id,
    });

    var errorBucket = new Gcp.Storage.Bucket("error", new()
    {
        Name = "static-asset-bucket",
        Location = "US",
    });

    var error = new Gcp.Compute.BackendBucket("error", new()
    {
        Name = "error-backend-bucket",
        BucketName = errorBucket.Name,
        EnableCdn = true,
    });

    var urlmap = new Gcp.Compute.URLMap("urlmap", new()
    {
        Name = "urlmap",
        Description = "a description",
        DefaultService = example.Id,
        DefaultCustomErrorResponsePolicy = new Gcp.Compute.Inputs.URLMapDefaultCustomErrorResponsePolicyArgs
        {
            ErrorResponseRules = new[]
            {
                new Gcp.Compute.Inputs.URLMapDefaultCustomErrorResponsePolicyErrorResponseRuleArgs
                {
                    MatchResponseCodes = new[]
                    {
                        "5xx",
                    },
                    Path = "/internal_error.html",
                    OverrideResponseCode = 502,
                },
            },
            ErrorService = error.Id,
        },
        HostRules = new[]
        {
            new Gcp.Compute.Inputs.URLMapHostRuleArgs
            {
                Hosts = new[]
                {
                    "mysite.com",
                },
                PathMatcher = "mysite",
            },
        },
        PathMatchers = new[]
        {
            new Gcp.Compute.Inputs.URLMapPathMatcherArgs
            {
                Name = "mysite",
                DefaultService = example.Id,
                DefaultCustomErrorResponsePolicy = new Gcp.Compute.Inputs.URLMapPathMatcherDefaultCustomErrorResponsePolicyArgs
                {
                    ErrorResponseRules = new[]
                    {
                        new Gcp.Compute.Inputs.URLMapPathMatcherDefaultCustomErrorResponsePolicyErrorResponseRuleArgs
                        {
                            MatchResponseCodes = new[]
                            {
                                "4xx",
                                "5xx",
                            },
                            Path = "/login_error.html",
                            OverrideResponseCode = 404,
                        },
                        new Gcp.Compute.Inputs.URLMapPathMatcherDefaultCustomErrorResponsePolicyErrorResponseRuleArgs
                        {
                            MatchResponseCodes = new[]
                            {
                                "503",
                            },
                            Path = "/bad_gateway.html",
                            OverrideResponseCode = 502,
                        },
                    },
                    ErrorService = error.Id,
                },
                PathRules = new[]
                {
                    new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleArgs
                    {
                        Paths = new[]
                        {
                            "/private/*",
                        },
                        Service = example.Id,
                        CustomErrorResponsePolicy = new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleCustomErrorResponsePolicyArgs
                        {
                            ErrorResponseRules = new[]
                            {
                                new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleCustomErrorResponsePolicyErrorResponseRuleArgs
                                {
                                    MatchResponseCodes = new[]
                                    {
                                        "4xx",
                                    },
                                    Path = "/login.html",
                                    OverrideResponseCode = 401,
                                },
                            },
                            ErrorService = error.Id,
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HttpHealthCheck;
import com.pulumi.gcp.compute.HttpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.storage.Bucket;
import com.pulumi.gcp.storage.BucketArgs;
import com.pulumi.gcp.compute.BackendBucket;
import com.pulumi.gcp.compute.BackendBucketArgs;
import com.pulumi.gcp.compute.URLMap;
import com.pulumi.gcp.compute.URLMapArgs;
import com.pulumi.gcp.compute.inputs.URLMapDefaultCustomErrorResponsePolicyArgs;
import com.pulumi.gcp.compute.inputs.URLMapHostRuleArgs;
import com.pulumi.gcp.compute.inputs.URLMapPathMatcherArgs;
import com.pulumi.gcp.compute.inputs.URLMapPathMatcherDefaultCustomErrorResponsePolicyArgs;
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 HttpHealthCheck("default", HttpHealthCheckArgs.builder()
            .name("health-check")
            .requestPath("/")
            .checkIntervalSec(1)
            .timeoutSec(1)
            .build());

        var example = new BackendService("example", BackendServiceArgs.builder()
            .name("login")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .loadBalancingScheme("EXTERNAL_MANAGED")
            .healthChecks(default_.id())
            .build());

        var errorBucket = new Bucket("errorBucket", BucketArgs.builder()
            .name("static-asset-bucket")
            .location("US")
            .build());

        var error = new BackendBucket("error", BackendBucketArgs.builder()
            .name("error-backend-bucket")
            .bucketName(errorBucket.name())
            .enableCdn(true)
            .build());

        var urlmap = new URLMap("urlmap", URLMapArgs.builder()
            .name("urlmap")
            .description("a description")
            .defaultService(example.id())
            .defaultCustomErrorResponsePolicy(URLMapDefaultCustomErrorResponsePolicyArgs.builder()
                .errorResponseRules(URLMapDefaultCustomErrorResponsePolicyErrorResponseRuleArgs.builder()
                    .matchResponseCodes("5xx")
                    .path("/internal_error.html")
                    .overrideResponseCode(502)
                    .build())
                .errorService(error.id())
                .build())
            .hostRules(URLMapHostRuleArgs.builder()
                .hosts("mysite.com")
                .pathMatcher("mysite")
                .build())
            .pathMatchers(URLMapPathMatcherArgs.builder()
                .name("mysite")
                .defaultService(example.id())
                .defaultCustomErrorResponsePolicy(URLMapPathMatcherDefaultCustomErrorResponsePolicyArgs.builder()
                    .errorResponseRules(                    
                        URLMapPathMatcherDefaultCustomErrorResponsePolicyErrorResponseRuleArgs.builder()
                            .matchResponseCodes(                            
                                "4xx",
                                "5xx")
                            .path("/login_error.html")
                            .overrideResponseCode(404)
                            .build(),
                        URLMapPathMatcherDefaultCustomErrorResponsePolicyErrorResponseRuleArgs.builder()
                            .matchResponseCodes("503")
                            .path("/bad_gateway.html")
                            .overrideResponseCode(502)
                            .build())
                    .errorService(error.id())
                    .build())
                .pathRules(URLMapPathMatcherPathRuleArgs.builder()
                    .paths("/private/*")
                    .service(example.id())
                    .customErrorResponsePolicy(URLMapPathMatcherPathRuleCustomErrorResponsePolicyArgs.builder()
                        .errorResponseRules(URLMapPathMatcherPathRuleCustomErrorResponsePolicyErrorResponseRuleArgs.builder()
                            .matchResponseCodes("4xx")
                            .path("/login.html")
                            .overrideResponseCode(401)
                            .build())
                        .errorService(error.id())
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  urlmap:
    type: gcp:compute:URLMap
    properties:
      name: urlmap
      description: a description
      defaultService: ${example.id}
      defaultCustomErrorResponsePolicy:
        errorResponseRules:
          - matchResponseCodes:
              - 5xx
            path: /internal_error.html
            overrideResponseCode: 502
        errorService: ${error.id}
      hostRules:
        - hosts:
            - mysite.com
          pathMatcher: mysite
      pathMatchers:
        - name: mysite
          defaultService: ${example.id}
          defaultCustomErrorResponsePolicy:
            errorResponseRules:
              - matchResponseCodes:
                  - 4xx
                  - 5xx
                path: /login_error.html
                overrideResponseCode: 404
              - matchResponseCodes:
                  - '503'
                path: /bad_gateway.html
                overrideResponseCode: 502
            errorService: ${error.id}
          pathRules:
            - paths:
                - /private/*
              service: ${example.id}
              customErrorResponsePolicy:
                errorResponseRules:
                  - matchResponseCodes:
                      - 4xx
                    path: /login.html
                    overrideResponseCode: 401
                errorService: ${error.id}
  example:
    type: gcp:compute:BackendService
    properties:
      name: login
      portName: http
      protocol: HTTP
      timeoutSec: 10
      loadBalancingScheme: EXTERNAL_MANAGED
      healthChecks: ${default.id}
  default:
    type: gcp:compute:HttpHealthCheck
    properties:
      name: health-check
      requestPath: /
      checkIntervalSec: 1
      timeoutSec: 1
  error:
    type: gcp:compute:BackendBucket
    properties:
      name: error-backend-bucket
      bucketName: ${errorBucket.name}
      enableCdn: true
  errorBucket:
    type: gcp:storage:Bucket
    name: error
    properties:
      name: static-asset-bucket
      location: US

The defaultCustomErrorResponsePolicy configures error handling at the URL map level. The errorResponseRules array maps response codes to custom error pages. The matchResponseCodes field accepts specific codes or ranges like 4xx and 5xx. The path field specifies the error page location in the errorService backend bucket. You can override this policy at the path matcher and path rule levels for more granular control.

Beyond these examples

These snippets focus on specific URL map features: path and host-based routing, header and query parameter matching, Traffic Director route actions (CORS, fault injection, retries), and custom error responses. They’re intentionally minimal rather than full load balancing configurations.

The examples reference pre-existing infrastructure such as backend services with health checks, backend buckets (Cloud Storage), and load balancing scheme configuration (INTERNAL_SELF_MANAGED or EXTERNAL_MANAGED). They focus on configuring routing rules rather than provisioning the complete load balancing stack.

To keep things focused, common URL map patterns are omitted, including:

  • Request mirroring configuration (requestMirrorPolicy with mirrorPercent)
  • URL redirect rules (urlRedirect at various levels)
  • HTTP filter configurations for service mesh (httpFilterConfigs, httpFilterMetadata)
  • Test configuration (tests array for validation)
  • Default route actions (defaultRouteAction)

These omissions are intentional: the goal is to illustrate how each routing feature is wired, not provide drop-in load balancing modules. See the URL Map resource reference for all available configuration options.

Let's configure GCP URL Maps for Load Balancing

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Setup
Can I use both defaultService and defaultRouteAction with weighted backends?
No. If defaultRouteAction specifies weightedBackendServices, you cannot set defaultService. Conversely, if defaultService is set, defaultRouteAction cannot contain weightedBackendServices. Choose one approach for your routing needs.
Can I configure both defaultRouteAction and defaultUrlRedirect?
No. Only one of defaultRouteAction or defaultUrlRedirect can be set. Use defaultRouteAction for backend routing or defaultUrlRedirect for redirects, but not both.
Why isn't my custom error response policy working?
Custom error response policies (defaultCustomErrorResponsePolicy) are only supported for global external Application Load Balancers. Verify your load balancer type matches this requirement.
Routing Mechanisms
What's the difference between pathRules and routeRules?
pathRules provide simple path-to-service mapping within a pathMatcher. routeRules offer advanced, priority-based routing with complex matching logic (headers, query parameters, metadata) and actions like URL rewrites and header transformations.
How do I set up A/B testing with header-based routing?
Use routeRules with matchRules containing headerMatches. Set different priorities and services for each variant. For example, route requests with header abtest: a to service A and abtest: b to service B.
How do I route traffic based on query parameters?
Configure routeRules with matchRules containing queryParameterMatches. Specify the parameter name and match criteria (exact, present, regex) to route to different backend services.
How do I use path templates for dynamic URL routing?
Use pathTemplateMatch in matchRules with variable placeholders like {username=*} or {cartid=**}. You can extract these variables and rewrite URLs using pathTemplateRewrite in the routeAction.
Advanced Features
Where can I configure request mirroring?
Request mirroring can be configured at four levels using requestMirrorPolicy: URL map level (defaultRouteAction), path matcher level (defaultRouteAction), individual path rules (routeAction), or route rules. Specify the backendService and mirrorPercent (0-100) at your chosen level.
How does the custom error response policy hierarchy work?
Error policies are evaluated from most specific to least specific: PathRule → RouteRule → PathMatcher → UrlMap. If an error code has no policy at a lower level, the policy from the next higher level takes effect. Retries take precedence over error policies.
What advanced routing features are available in routeAction?
routeAction supports CORS policies, fault injection (delays and aborts), request mirroring, retry policies with configurable conditions, timeouts, URL rewrites (host and path), and weighted backend services for traffic splitting.
How do I configure URL rewriting?
Use urlRewrite within routeAction to specify hostRewrite for changing the host and pathPrefixRewrite for modifying the path. For dynamic rewrites, use pathTemplateRewrite with path template variables.
Testing & Validation
How do I validate my URL map configuration?
Add test cases to the tests array (max 100). Each test specifies host, path, expected service, and optionally headers, expectedOutputUrl, and expectedRedirectResponseCode. Updates only succeed if all tests pass.
Limitations & Constraints
What are the naming requirements for URL maps?
The name must be 1-63 characters long, comply with RFC1035, and match the pattern a-z?. It must start with a lowercase letter, contain only lowercase letters, digits, or dashes, and cannot end with a dash. The name is immutable after creation.
How many tests can I configure per URL map?
You can specify a maximum of 100 tests per URL map. All tests must pass for an update to succeed.

Using a different cloud?

Explore networking guides for other cloud providers: