Configure GCP Target HTTPS Proxies

The gcp:compute/targetHttpsProxy:TargetHttpsProxy resource, part of the Pulumi GCP provider, defines the HTTPS termination layer for global load balancers: which SSL certificates to use, which URL map routes traffic, and optional mTLS or connection tuning. This guide focuses on four capabilities: SSL certificate attachment, connection keep-alive tuning, mutual TLS authentication, and Certificate Manager integration.

Target HTTPS proxies sit between forwarding rules and URL maps. They require SSL certificates and backend services to exist before you can route traffic. The examples are intentionally small. Combine them with your own forwarding rules and backend infrastructure.

Route HTTPS traffic to backend services

Most HTTPS load balancers connect SSL certificates to a URL map, which routes requests to backend services based on hostname and path.

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

const defaultSSLCertificate = new gcp.compute.SSLCertificate("default", {
    name: "my-certificate",
    privateKey: std.file({
        input: "path/to/private.key",
    }).then(invoke => invoke.result),
    certificate: std.file({
        input: "path/to/certificate.crt",
    }).then(invoke => invoke.result),
});
const defaultHttpHealthCheck = new gcp.compute.HttpHealthCheck("default", {
    name: "http-health-check",
    requestPath: "/",
    checkIntervalSec: 1,
    timeoutSec: 1,
});
const defaultBackendService = new gcp.compute.BackendService("default", {
    name: "backend-service",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    healthChecks: defaultHttpHealthCheck.id,
});
const defaultURLMap = new gcp.compute.URLMap("default", {
    name: "url-map",
    description: "a description",
    defaultService: defaultBackendService.id,
    hostRules: [{
        hosts: ["mysite.com"],
        pathMatcher: "allpaths",
    }],
    pathMatchers: [{
        name: "allpaths",
        defaultService: defaultBackendService.id,
        pathRules: [{
            paths: ["/*"],
            service: defaultBackendService.id,
        }],
    }],
});
const _default = new gcp.compute.TargetHttpsProxy("default", {
    name: "test-proxy",
    urlMap: defaultURLMap.id,
    sslCertificates: [defaultSSLCertificate.id],
});
import pulumi
import pulumi_gcp as gcp
import pulumi_std as std

default_ssl_certificate = gcp.compute.SSLCertificate("default",
    name="my-certificate",
    private_key=std.file(input="path/to/private.key").result,
    certificate=std.file(input="path/to/certificate.crt").result)
default_http_health_check = gcp.compute.HttpHealthCheck("default",
    name="http-health-check",
    request_path="/",
    check_interval_sec=1,
    timeout_sec=1)
default_backend_service = gcp.compute.BackendService("default",
    name="backend-service",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    health_checks=default_http_health_check.id)
default_url_map = gcp.compute.URLMap("default",
    name="url-map",
    description="a description",
    default_service=default_backend_service.id,
    host_rules=[{
        "hosts": ["mysite.com"],
        "path_matcher": "allpaths",
    }],
    path_matchers=[{
        "name": "allpaths",
        "default_service": default_backend_service.id,
        "path_rules": [{
            "paths": ["/*"],
            "service": default_backend_service.id,
        }],
    }])
default = gcp.compute.TargetHttpsProxy("default",
    name="test-proxy",
    url_map=default_url_map.id,
    ssl_certificates=[default_ssl_certificate.id])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		invokeFile, err := std.File(ctx, &std.FileArgs{
			Input: "path/to/private.key",
		}, nil)
		if err != nil {
			return err
		}
		invokeFile1, err := std.File(ctx, &std.FileArgs{
			Input: "path/to/certificate.crt",
		}, nil)
		if err != nil {
			return err
		}
		defaultSSLCertificate, err := compute.NewSSLCertificate(ctx, "default", &compute.SSLCertificateArgs{
			Name:        pulumi.String("my-certificate"),
			PrivateKey:  pulumi.String(invokeFile.Result),
			Certificate: pulumi.String(invokeFile1.Result),
		})
		if err != nil {
			return err
		}
		defaultHttpHealthCheck, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
			Name:             pulumi.String("http-health-check"),
			RequestPath:      pulumi.String("/"),
			CheckIntervalSec: pulumi.Int(1),
			TimeoutSec:       pulumi.Int(1),
		})
		if err != nil {
			return err
		}
		defaultBackendService, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
			Name:         pulumi.String("backend-service"),
			PortName:     pulumi.String("http"),
			Protocol:     pulumi.String("HTTP"),
			TimeoutSec:   pulumi.Int(10),
			HealthChecks: defaultHttpHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		defaultURLMap, err := compute.NewURLMap(ctx, "default", &compute.URLMapArgs{
			Name:           pulumi.String("url-map"),
			Description:    pulumi.String("a description"),
			DefaultService: defaultBackendService.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: defaultBackendService.ID(),
					PathRules: compute.URLMapPathMatcherPathRuleArray{
						&compute.URLMapPathMatcherPathRuleArgs{
							Paths: pulumi.StringArray{
								pulumi.String("/*"),
							},
							Service: defaultBackendService.ID(),
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewTargetHttpsProxy(ctx, "default", &compute.TargetHttpsProxyArgs{
			Name:   pulumi.String("test-proxy"),
			UrlMap: defaultURLMap.ID(),
			SslCertificates: pulumi.StringArray{
				defaultSSLCertificate.ID(),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Std = Pulumi.Std;

return await Deployment.RunAsync(() => 
{
    var defaultSSLCertificate = new Gcp.Compute.SSLCertificate("default", new()
    {
        Name = "my-certificate",
        PrivateKey = Std.File.Invoke(new()
        {
            Input = "path/to/private.key",
        }).Apply(invoke => invoke.Result),
        Certificate = Std.File.Invoke(new()
        {
            Input = "path/to/certificate.crt",
        }).Apply(invoke => invoke.Result),
    });

    var defaultHttpHealthCheck = new Gcp.Compute.HttpHealthCheck("default", new()
    {
        Name = "http-health-check",
        RequestPath = "/",
        CheckIntervalSec = 1,
        TimeoutSec = 1,
    });

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

    var defaultURLMap = new Gcp.Compute.URLMap("default", new()
    {
        Name = "url-map",
        Description = "a description",
        DefaultService = defaultBackendService.Id,
        HostRules = new[]
        {
            new Gcp.Compute.Inputs.URLMapHostRuleArgs
            {
                Hosts = new[]
                {
                    "mysite.com",
                },
                PathMatcher = "allpaths",
            },
        },
        PathMatchers = new[]
        {
            new Gcp.Compute.Inputs.URLMapPathMatcherArgs
            {
                Name = "allpaths",
                DefaultService = defaultBackendService.Id,
                PathRules = new[]
                {
                    new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleArgs
                    {
                        Paths = new[]
                        {
                            "/*",
                        },
                        Service = defaultBackendService.Id,
                    },
                },
            },
        },
    });

    var @default = new Gcp.Compute.TargetHttpsProxy("default", new()
    {
        Name = "test-proxy",
        UrlMap = defaultURLMap.Id,
        SslCertificates = new[]
        {
            defaultSSLCertificate.Id,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.SSLCertificate;
import com.pulumi.gcp.compute.SSLCertificateArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.FileArgs;
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 com.pulumi.gcp.compute.TargetHttpsProxy;
import com.pulumi.gcp.compute.TargetHttpsProxyArgs;
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 defaultSSLCertificate = new SSLCertificate("defaultSSLCertificate", SSLCertificateArgs.builder()
            .name("my-certificate")
            .privateKey(StdFunctions.file(FileArgs.builder()
                .input("path/to/private.key")
                .build()).result())
            .certificate(StdFunctions.file(FileArgs.builder()
                .input("path/to/certificate.crt")
                .build()).result())
            .build());

        var defaultHttpHealthCheck = new HttpHealthCheck("defaultHttpHealthCheck", HttpHealthCheckArgs.builder()
            .name("http-health-check")
            .requestPath("/")
            .checkIntervalSec(1)
            .timeoutSec(1)
            .build());

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

        var defaultURLMap = new URLMap("defaultURLMap", URLMapArgs.builder()
            .name("url-map")
            .description("a description")
            .defaultService(defaultBackendService.id())
            .hostRules(URLMapHostRuleArgs.builder()
                .hosts("mysite.com")
                .pathMatcher("allpaths")
                .build())
            .pathMatchers(URLMapPathMatcherArgs.builder()
                .name("allpaths")
                .defaultService(defaultBackendService.id())
                .pathRules(URLMapPathMatcherPathRuleArgs.builder()
                    .paths("/*")
                    .service(defaultBackendService.id())
                    .build())
                .build())
            .build());

        var default_ = new TargetHttpsProxy("default", TargetHttpsProxyArgs.builder()
            .name("test-proxy")
            .urlMap(defaultURLMap.id())
            .sslCertificates(defaultSSLCertificate.id())
            .build());

    }
}
resources:
  default:
    type: gcp:compute:TargetHttpsProxy
    properties:
      name: test-proxy
      urlMap: ${defaultURLMap.id}
      sslCertificates:
        - ${defaultSSLCertificate.id}
  defaultSSLCertificate:
    type: gcp:compute:SSLCertificate
    name: default
    properties:
      name: my-certificate
      privateKey:
        fn::invoke:
          function: std:file
          arguments:
            input: path/to/private.key
          return: result
      certificate:
        fn::invoke:
          function: std:file
          arguments:
            input: path/to/certificate.crt
          return: result
  defaultURLMap:
    type: gcp:compute:URLMap
    name: default
    properties:
      name: url-map
      description: a description
      defaultService: ${defaultBackendService.id}
      hostRules:
        - hosts:
            - mysite.com
          pathMatcher: allpaths
      pathMatchers:
        - name: allpaths
          defaultService: ${defaultBackendService.id}
          pathRules:
            - paths:
                - /*
              service: ${defaultBackendService.id}
  defaultBackendService:
    type: gcp:compute:BackendService
    name: default
    properties:
      name: backend-service
      portName: http
      protocol: HTTP
      timeoutSec: 10
      healthChecks: ${defaultHttpHealthCheck.id}
  defaultHttpHealthCheck:
    type: gcp:compute:HttpHealthCheck
    name: default
    properties:
      name: http-health-check
      requestPath: /
      checkIntervalSec: 1
      timeoutSec: 1

The proxy terminates SSL using the certificate specified in sslCertificates, then routes requests according to the urlMap. The URL map defines host rules and path matchers that direct traffic to the appropriate BackendService. This configuration handles SSL termination and basic routing without connection tuning or client authentication.

Configure connection keep-alive for external load balancers

Applications with specific connection reuse requirements can tune how long the load balancer keeps idle connections open.

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

const defaultSSLCertificate = new gcp.compute.SSLCertificate("default", {
    name: "my-certificate",
    privateKey: std.file({
        input: "path/to/private.key",
    }).then(invoke => invoke.result),
    certificate: std.file({
        input: "path/to/certificate.crt",
    }).then(invoke => invoke.result),
});
const defaultHttpHealthCheck = new gcp.compute.HttpHealthCheck("default", {
    name: "http-health-check",
    requestPath: "/",
    checkIntervalSec: 1,
    timeoutSec: 1,
});
const defaultBackendService = new gcp.compute.BackendService("default", {
    name: "backend-service",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    loadBalancingScheme: "EXTERNAL_MANAGED",
    healthChecks: defaultHttpHealthCheck.id,
});
const defaultURLMap = new gcp.compute.URLMap("default", {
    name: "url-map",
    description: "a description",
    defaultService: defaultBackendService.id,
    hostRules: [{
        hosts: ["mysite.com"],
        pathMatcher: "allpaths",
    }],
    pathMatchers: [{
        name: "allpaths",
        defaultService: defaultBackendService.id,
        pathRules: [{
            paths: ["/*"],
            service: defaultBackendService.id,
        }],
    }],
});
const _default = new gcp.compute.TargetHttpsProxy("default", {
    name: "test-http-keep-alive-timeout-proxy",
    httpKeepAliveTimeoutSec: 610,
    urlMap: defaultURLMap.id,
    sslCertificates: [defaultSSLCertificate.id],
});
import pulumi
import pulumi_gcp as gcp
import pulumi_std as std

default_ssl_certificate = gcp.compute.SSLCertificate("default",
    name="my-certificate",
    private_key=std.file(input="path/to/private.key").result,
    certificate=std.file(input="path/to/certificate.crt").result)
default_http_health_check = gcp.compute.HttpHealthCheck("default",
    name="http-health-check",
    request_path="/",
    check_interval_sec=1,
    timeout_sec=1)
default_backend_service = gcp.compute.BackendService("default",
    name="backend-service",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    load_balancing_scheme="EXTERNAL_MANAGED",
    health_checks=default_http_health_check.id)
default_url_map = gcp.compute.URLMap("default",
    name="url-map",
    description="a description",
    default_service=default_backend_service.id,
    host_rules=[{
        "hosts": ["mysite.com"],
        "path_matcher": "allpaths",
    }],
    path_matchers=[{
        "name": "allpaths",
        "default_service": default_backend_service.id,
        "path_rules": [{
            "paths": ["/*"],
            "service": default_backend_service.id,
        }],
    }])
default = gcp.compute.TargetHttpsProxy("default",
    name="test-http-keep-alive-timeout-proxy",
    http_keep_alive_timeout_sec=610,
    url_map=default_url_map.id,
    ssl_certificates=[default_ssl_certificate.id])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		invokeFile, err := std.File(ctx, &std.FileArgs{
			Input: "path/to/private.key",
		}, nil)
		if err != nil {
			return err
		}
		invokeFile1, err := std.File(ctx, &std.FileArgs{
			Input: "path/to/certificate.crt",
		}, nil)
		if err != nil {
			return err
		}
		defaultSSLCertificate, err := compute.NewSSLCertificate(ctx, "default", &compute.SSLCertificateArgs{
			Name:        pulumi.String("my-certificate"),
			PrivateKey:  pulumi.String(invokeFile.Result),
			Certificate: pulumi.String(invokeFile1.Result),
		})
		if err != nil {
			return err
		}
		defaultHttpHealthCheck, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
			Name:             pulumi.String("http-health-check"),
			RequestPath:      pulumi.String("/"),
			CheckIntervalSec: pulumi.Int(1),
			TimeoutSec:       pulumi.Int(1),
		})
		if err != nil {
			return err
		}
		defaultBackendService, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
			Name:                pulumi.String("backend-service"),
			PortName:            pulumi.String("http"),
			Protocol:            pulumi.String("HTTP"),
			TimeoutSec:          pulumi.Int(10),
			LoadBalancingScheme: pulumi.String("EXTERNAL_MANAGED"),
			HealthChecks:        defaultHttpHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		defaultURLMap, err := compute.NewURLMap(ctx, "default", &compute.URLMapArgs{
			Name:           pulumi.String("url-map"),
			Description:    pulumi.String("a description"),
			DefaultService: defaultBackendService.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: defaultBackendService.ID(),
					PathRules: compute.URLMapPathMatcherPathRuleArray{
						&compute.URLMapPathMatcherPathRuleArgs{
							Paths: pulumi.StringArray{
								pulumi.String("/*"),
							},
							Service: defaultBackendService.ID(),
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewTargetHttpsProxy(ctx, "default", &compute.TargetHttpsProxyArgs{
			Name:                    pulumi.String("test-http-keep-alive-timeout-proxy"),
			HttpKeepAliveTimeoutSec: pulumi.Int(610),
			UrlMap:                  defaultURLMap.ID(),
			SslCertificates: pulumi.StringArray{
				defaultSSLCertificate.ID(),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Std = Pulumi.Std;

return await Deployment.RunAsync(() => 
{
    var defaultSSLCertificate = new Gcp.Compute.SSLCertificate("default", new()
    {
        Name = "my-certificate",
        PrivateKey = Std.File.Invoke(new()
        {
            Input = "path/to/private.key",
        }).Apply(invoke => invoke.Result),
        Certificate = Std.File.Invoke(new()
        {
            Input = "path/to/certificate.crt",
        }).Apply(invoke => invoke.Result),
    });

    var defaultHttpHealthCheck = new Gcp.Compute.HttpHealthCheck("default", new()
    {
        Name = "http-health-check",
        RequestPath = "/",
        CheckIntervalSec = 1,
        TimeoutSec = 1,
    });

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

    var defaultURLMap = new Gcp.Compute.URLMap("default", new()
    {
        Name = "url-map",
        Description = "a description",
        DefaultService = defaultBackendService.Id,
        HostRules = new[]
        {
            new Gcp.Compute.Inputs.URLMapHostRuleArgs
            {
                Hosts = new[]
                {
                    "mysite.com",
                },
                PathMatcher = "allpaths",
            },
        },
        PathMatchers = new[]
        {
            new Gcp.Compute.Inputs.URLMapPathMatcherArgs
            {
                Name = "allpaths",
                DefaultService = defaultBackendService.Id,
                PathRules = new[]
                {
                    new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleArgs
                    {
                        Paths = new[]
                        {
                            "/*",
                        },
                        Service = defaultBackendService.Id,
                    },
                },
            },
        },
    });

    var @default = new Gcp.Compute.TargetHttpsProxy("default", new()
    {
        Name = "test-http-keep-alive-timeout-proxy",
        HttpKeepAliveTimeoutSec = 610,
        UrlMap = defaultURLMap.Id,
        SslCertificates = new[]
        {
            defaultSSLCertificate.Id,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.SSLCertificate;
import com.pulumi.gcp.compute.SSLCertificateArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.FileArgs;
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 com.pulumi.gcp.compute.TargetHttpsProxy;
import com.pulumi.gcp.compute.TargetHttpsProxyArgs;
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 defaultSSLCertificate = new SSLCertificate("defaultSSLCertificate", SSLCertificateArgs.builder()
            .name("my-certificate")
            .privateKey(StdFunctions.file(FileArgs.builder()
                .input("path/to/private.key")
                .build()).result())
            .certificate(StdFunctions.file(FileArgs.builder()
                .input("path/to/certificate.crt")
                .build()).result())
            .build());

        var defaultHttpHealthCheck = new HttpHealthCheck("defaultHttpHealthCheck", HttpHealthCheckArgs.builder()
            .name("http-health-check")
            .requestPath("/")
            .checkIntervalSec(1)
            .timeoutSec(1)
            .build());

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

        var defaultURLMap = new URLMap("defaultURLMap", URLMapArgs.builder()
            .name("url-map")
            .description("a description")
            .defaultService(defaultBackendService.id())
            .hostRules(URLMapHostRuleArgs.builder()
                .hosts("mysite.com")
                .pathMatcher("allpaths")
                .build())
            .pathMatchers(URLMapPathMatcherArgs.builder()
                .name("allpaths")
                .defaultService(defaultBackendService.id())
                .pathRules(URLMapPathMatcherPathRuleArgs.builder()
                    .paths("/*")
                    .service(defaultBackendService.id())
                    .build())
                .build())
            .build());

        var default_ = new TargetHttpsProxy("default", TargetHttpsProxyArgs.builder()
            .name("test-http-keep-alive-timeout-proxy")
            .httpKeepAliveTimeoutSec(610)
            .urlMap(defaultURLMap.id())
            .sslCertificates(defaultSSLCertificate.id())
            .build());

    }
}
resources:
  default:
    type: gcp:compute:TargetHttpsProxy
    properties:
      name: test-http-keep-alive-timeout-proxy
      httpKeepAliveTimeoutSec: 610
      urlMap: ${defaultURLMap.id}
      sslCertificates:
        - ${defaultSSLCertificate.id}
  defaultSSLCertificate:
    type: gcp:compute:SSLCertificate
    name: default
    properties:
      name: my-certificate
      privateKey:
        fn::invoke:
          function: std:file
          arguments:
            input: path/to/private.key
          return: result
      certificate:
        fn::invoke:
          function: std:file
          arguments:
            input: path/to/certificate.crt
          return: result
  defaultURLMap:
    type: gcp:compute:URLMap
    name: default
    properties:
      name: url-map
      description: a description
      defaultService: ${defaultBackendService.id}
      hostRules:
        - hosts:
            - mysite.com
          pathMatcher: allpaths
      pathMatchers:
        - name: allpaths
          defaultService: ${defaultBackendService.id}
          pathRules:
            - paths:
                - /*
              service: ${defaultBackendService.id}
  defaultBackendService:
    type: gcp:compute:BackendService
    name: default
    properties:
      name: backend-service
      portName: http
      protocol: HTTP
      timeoutSec: 10
      loadBalancingScheme: EXTERNAL_MANAGED
      healthChecks: ${defaultHttpHealthCheck.id}
  defaultHttpHealthCheck:
    type: gcp:compute:HttpHealthCheck
    name: default
    properties:
      name: http-health-check
      requestPath: /
      checkIntervalSec: 1
      timeoutSec: 1

The httpKeepAliveTimeoutSec property controls connection pooling behavior. For EXTERNAL_MANAGED load balancers, the default is 610 seconds; this example sets it to 610 explicitly. Longer timeouts reduce connection overhead for clients making repeated requests; shorter timeouts free resources faster. This property only applies to external and cross-region internal load balancers.

Enforce mutual TLS authentication with trust configs

Services requiring client certificate validation use mutual TLS to verify both server and client identities.

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

const project = gcp.organizations.getProject({});
const defaultTrustConfig = new gcp.certificatemanager.TrustConfig("default", {
    name: "my-trust-config",
    description: "sample description for the trust config",
    location: "global",
    trustStores: [{
        trustAnchors: [{
            pemCertificate: std.file({
                input: "test-fixtures/ca_cert.pem",
            }).then(invoke => invoke.result),
        }],
        intermediateCas: [{
            pemCertificate: std.file({
                input: "test-fixtures/ca_cert.pem",
            }).then(invoke => invoke.result),
        }],
    }],
    labels: {
        foo: "bar",
    },
});
const defaultServerTlsPolicy = new gcp.networksecurity.ServerTlsPolicy("default", {
    name: "my-tls-policy",
    description: "my description",
    location: "global",
    allowOpen: false,
    mtlsPolicy: {
        clientValidationMode: "ALLOW_INVALID_OR_MISSING_CLIENT_CERT",
        clientValidationTrustConfig: pulumi.all([project, defaultTrustConfig.name]).apply(([project, name]) => `projects/${project.number}/locations/global/trustConfigs/${name}`),
    },
});
const defaultSSLCertificate = new gcp.compute.SSLCertificate("default", {
    name: "my-certificate",
    privateKey: std.file({
        input: "path/to/private.key",
    }).then(invoke => invoke.result),
    certificate: std.file({
        input: "path/to/certificate.crt",
    }).then(invoke => invoke.result),
});
const defaultHttpHealthCheck = new gcp.compute.HttpHealthCheck("default", {
    name: "http-health-check",
    requestPath: "/",
    checkIntervalSec: 1,
    timeoutSec: 1,
});
const defaultBackendService = new gcp.compute.BackendService("default", {
    name: "backend-service",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    healthChecks: defaultHttpHealthCheck.id,
});
const defaultURLMap = new gcp.compute.URLMap("default", {
    name: "url-map",
    description: "a description",
    defaultService: defaultBackendService.id,
    hostRules: [{
        hosts: ["mysite.com"],
        pathMatcher: "allpaths",
    }],
    pathMatchers: [{
        name: "allpaths",
        defaultService: defaultBackendService.id,
        pathRules: [{
            paths: ["/*"],
            service: defaultBackendService.id,
        }],
    }],
});
const _default = new gcp.compute.TargetHttpsProxy("default", {
    name: "test-mtls-proxy",
    urlMap: defaultURLMap.id,
    sslCertificates: [defaultSSLCertificate.id],
    serverTlsPolicy: defaultServerTlsPolicy.id,
});
import pulumi
import pulumi_gcp as gcp
import pulumi_std as std

project = gcp.organizations.get_project()
default_trust_config = gcp.certificatemanager.TrustConfig("default",
    name="my-trust-config",
    description="sample description for the trust config",
    location="global",
    trust_stores=[{
        "trust_anchors": [{
            "pem_certificate": std.file(input="test-fixtures/ca_cert.pem").result,
        }],
        "intermediate_cas": [{
            "pem_certificate": std.file(input="test-fixtures/ca_cert.pem").result,
        }],
    }],
    labels={
        "foo": "bar",
    })
default_server_tls_policy = gcp.networksecurity.ServerTlsPolicy("default",
    name="my-tls-policy",
    description="my description",
    location="global",
    allow_open=False,
    mtls_policy={
        "client_validation_mode": "ALLOW_INVALID_OR_MISSING_CLIENT_CERT",
        "client_validation_trust_config": default_trust_config.name.apply(lambda name: f"projects/{project.number}/locations/global/trustConfigs/{name}"),
    })
default_ssl_certificate = gcp.compute.SSLCertificate("default",
    name="my-certificate",
    private_key=std.file(input="path/to/private.key").result,
    certificate=std.file(input="path/to/certificate.crt").result)
default_http_health_check = gcp.compute.HttpHealthCheck("default",
    name="http-health-check",
    request_path="/",
    check_interval_sec=1,
    timeout_sec=1)
default_backend_service = gcp.compute.BackendService("default",
    name="backend-service",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    health_checks=default_http_health_check.id)
default_url_map = gcp.compute.URLMap("default",
    name="url-map",
    description="a description",
    default_service=default_backend_service.id,
    host_rules=[{
        "hosts": ["mysite.com"],
        "path_matcher": "allpaths",
    }],
    path_matchers=[{
        "name": "allpaths",
        "default_service": default_backend_service.id,
        "path_rules": [{
            "paths": ["/*"],
            "service": default_backend_service.id,
        }],
    }])
default = gcp.compute.TargetHttpsProxy("default",
    name="test-mtls-proxy",
    url_map=default_url_map.id,
    ssl_certificates=[default_ssl_certificate.id],
    server_tls_policy=default_server_tls_policy.id)
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/certificatemanager"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networksecurity"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/organizations"
	"github.com/pulumi/pulumi-std/sdk/go/std"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		project, err := organizations.LookupProject(ctx, &organizations.LookupProjectArgs{}, nil)
		if err != nil {
			return err
		}
		invokeFile, err := std.File(ctx, &std.FileArgs{
			Input: "test-fixtures/ca_cert.pem",
		}, nil)
		if err != nil {
			return err
		}
		invokeFile1, err := std.File(ctx, &std.FileArgs{
			Input: "test-fixtures/ca_cert.pem",
		}, nil)
		if err != nil {
			return err
		}
		defaultTrustConfig, err := certificatemanager.NewTrustConfig(ctx, "default", &certificatemanager.TrustConfigArgs{
			Name:        pulumi.String("my-trust-config"),
			Description: pulumi.String("sample description for the trust config"),
			Location:    pulumi.String("global"),
			TrustStores: certificatemanager.TrustConfigTrustStoreArray{
				&certificatemanager.TrustConfigTrustStoreArgs{
					TrustAnchors: certificatemanager.TrustConfigTrustStoreTrustAnchorArray{
						&certificatemanager.TrustConfigTrustStoreTrustAnchorArgs{
							PemCertificate: pulumi.String(invokeFile.Result),
						},
					},
					IntermediateCas: certificatemanager.TrustConfigTrustStoreIntermediateCaArray{
						&certificatemanager.TrustConfigTrustStoreIntermediateCaArgs{
							PemCertificate: pulumi.String(invokeFile1.Result),
						},
					},
				},
			},
			Labels: pulumi.StringMap{
				"foo": pulumi.String("bar"),
			},
		})
		if err != nil {
			return err
		}
		defaultServerTlsPolicy, err := networksecurity.NewServerTlsPolicy(ctx, "default", &networksecurity.ServerTlsPolicyArgs{
			Name:        pulumi.String("my-tls-policy"),
			Description: pulumi.String("my description"),
			Location:    pulumi.String("global"),
			AllowOpen:   pulumi.Bool(false),
			MtlsPolicy: &networksecurity.ServerTlsPolicyMtlsPolicyArgs{
				ClientValidationMode: pulumi.String("ALLOW_INVALID_OR_MISSING_CLIENT_CERT"),
				ClientValidationTrustConfig: defaultTrustConfig.Name.ApplyT(func(name string) (string, error) {
					return fmt.Sprintf("projects/%v/locations/global/trustConfigs/%v", project.Number, name), nil
				}).(pulumi.StringOutput),
			},
		})
		if err != nil {
			return err
		}
		invokeFile2, err := std.File(ctx, &std.FileArgs{
			Input: "path/to/private.key",
		}, nil)
		if err != nil {
			return err
		}
		invokeFile3, err := std.File(ctx, &std.FileArgs{
			Input: "path/to/certificate.crt",
		}, nil)
		if err != nil {
			return err
		}
		defaultSSLCertificate, err := compute.NewSSLCertificate(ctx, "default", &compute.SSLCertificateArgs{
			Name:        pulumi.String("my-certificate"),
			PrivateKey:  pulumi.String(invokeFile2.Result),
			Certificate: pulumi.String(invokeFile3.Result),
		})
		if err != nil {
			return err
		}
		defaultHttpHealthCheck, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
			Name:             pulumi.String("http-health-check"),
			RequestPath:      pulumi.String("/"),
			CheckIntervalSec: pulumi.Int(1),
			TimeoutSec:       pulumi.Int(1),
		})
		if err != nil {
			return err
		}
		defaultBackendService, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
			Name:         pulumi.String("backend-service"),
			PortName:     pulumi.String("http"),
			Protocol:     pulumi.String("HTTP"),
			TimeoutSec:   pulumi.Int(10),
			HealthChecks: defaultHttpHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		defaultURLMap, err := compute.NewURLMap(ctx, "default", &compute.URLMapArgs{
			Name:           pulumi.String("url-map"),
			Description:    pulumi.String("a description"),
			DefaultService: defaultBackendService.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: defaultBackendService.ID(),
					PathRules: compute.URLMapPathMatcherPathRuleArray{
						&compute.URLMapPathMatcherPathRuleArgs{
							Paths: pulumi.StringArray{
								pulumi.String("/*"),
							},
							Service: defaultBackendService.ID(),
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewTargetHttpsProxy(ctx, "default", &compute.TargetHttpsProxyArgs{
			Name:   pulumi.String("test-mtls-proxy"),
			UrlMap: defaultURLMap.ID(),
			SslCertificates: pulumi.StringArray{
				defaultSSLCertificate.ID(),
			},
			ServerTlsPolicy: defaultServerTlsPolicy.ID(),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Std = Pulumi.Std;

return await Deployment.RunAsync(() => 
{
    var project = Gcp.Organizations.GetProject.Invoke();

    var defaultTrustConfig = new Gcp.CertificateManager.TrustConfig("default", new()
    {
        Name = "my-trust-config",
        Description = "sample description for the trust config",
        Location = "global",
        TrustStores = new[]
        {
            new Gcp.CertificateManager.Inputs.TrustConfigTrustStoreArgs
            {
                TrustAnchors = new[]
                {
                    new Gcp.CertificateManager.Inputs.TrustConfigTrustStoreTrustAnchorArgs
                    {
                        PemCertificate = Std.File.Invoke(new()
                        {
                            Input = "test-fixtures/ca_cert.pem",
                        }).Apply(invoke => invoke.Result),
                    },
                },
                IntermediateCas = new[]
                {
                    new Gcp.CertificateManager.Inputs.TrustConfigTrustStoreIntermediateCaArgs
                    {
                        PemCertificate = Std.File.Invoke(new()
                        {
                            Input = "test-fixtures/ca_cert.pem",
                        }).Apply(invoke => invoke.Result),
                    },
                },
            },
        },
        Labels = 
        {
            { "foo", "bar" },
        },
    });

    var defaultServerTlsPolicy = new Gcp.NetworkSecurity.ServerTlsPolicy("default", new()
    {
        Name = "my-tls-policy",
        Description = "my description",
        Location = "global",
        AllowOpen = false,
        MtlsPolicy = new Gcp.NetworkSecurity.Inputs.ServerTlsPolicyMtlsPolicyArgs
        {
            ClientValidationMode = "ALLOW_INVALID_OR_MISSING_CLIENT_CERT",
            ClientValidationTrustConfig = Output.Tuple(project, defaultTrustConfig.Name).Apply(values =>
            {
                var project = values.Item1;
                var name = values.Item2;
                return $"projects/{project.Apply(getProjectResult => getProjectResult.Number)}/locations/global/trustConfigs/{name}";
            }),
        },
    });

    var defaultSSLCertificate = new Gcp.Compute.SSLCertificate("default", new()
    {
        Name = "my-certificate",
        PrivateKey = Std.File.Invoke(new()
        {
            Input = "path/to/private.key",
        }).Apply(invoke => invoke.Result),
        Certificate = Std.File.Invoke(new()
        {
            Input = "path/to/certificate.crt",
        }).Apply(invoke => invoke.Result),
    });

    var defaultHttpHealthCheck = new Gcp.Compute.HttpHealthCheck("default", new()
    {
        Name = "http-health-check",
        RequestPath = "/",
        CheckIntervalSec = 1,
        TimeoutSec = 1,
    });

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

    var defaultURLMap = new Gcp.Compute.URLMap("default", new()
    {
        Name = "url-map",
        Description = "a description",
        DefaultService = defaultBackendService.Id,
        HostRules = new[]
        {
            new Gcp.Compute.Inputs.URLMapHostRuleArgs
            {
                Hosts = new[]
                {
                    "mysite.com",
                },
                PathMatcher = "allpaths",
            },
        },
        PathMatchers = new[]
        {
            new Gcp.Compute.Inputs.URLMapPathMatcherArgs
            {
                Name = "allpaths",
                DefaultService = defaultBackendService.Id,
                PathRules = new[]
                {
                    new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleArgs
                    {
                        Paths = new[]
                        {
                            "/*",
                        },
                        Service = defaultBackendService.Id,
                    },
                },
            },
        },
    });

    var @default = new Gcp.Compute.TargetHttpsProxy("default", new()
    {
        Name = "test-mtls-proxy",
        UrlMap = defaultURLMap.Id,
        SslCertificates = new[]
        {
            defaultSSLCertificate.Id,
        },
        ServerTlsPolicy = defaultServerTlsPolicy.Id,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.organizations.OrganizationsFunctions;
import com.pulumi.gcp.organizations.inputs.GetProjectArgs;
import com.pulumi.gcp.certificatemanager.TrustConfig;
import com.pulumi.gcp.certificatemanager.TrustConfigArgs;
import com.pulumi.gcp.certificatemanager.inputs.TrustConfigTrustStoreArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.FileArgs;
import com.pulumi.gcp.networksecurity.ServerTlsPolicy;
import com.pulumi.gcp.networksecurity.ServerTlsPolicyArgs;
import com.pulumi.gcp.networksecurity.inputs.ServerTlsPolicyMtlsPolicyArgs;
import com.pulumi.gcp.compute.SSLCertificate;
import com.pulumi.gcp.compute.SSLCertificateArgs;
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 com.pulumi.gcp.compute.TargetHttpsProxy;
import com.pulumi.gcp.compute.TargetHttpsProxyArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        final var project = OrganizationsFunctions.getProject(GetProjectArgs.builder()
            .build());

        var defaultTrustConfig = new TrustConfig("defaultTrustConfig", TrustConfigArgs.builder()
            .name("my-trust-config")
            .description("sample description for the trust config")
            .location("global")
            .trustStores(TrustConfigTrustStoreArgs.builder()
                .trustAnchors(TrustConfigTrustStoreTrustAnchorArgs.builder()
                    .pemCertificate(StdFunctions.file(FileArgs.builder()
                        .input("test-fixtures/ca_cert.pem")
                        .build()).result())
                    .build())
                .intermediateCas(TrustConfigTrustStoreIntermediateCaArgs.builder()
                    .pemCertificate(StdFunctions.file(FileArgs.builder()
                        .input("test-fixtures/ca_cert.pem")
                        .build()).result())
                    .build())
                .build())
            .labels(Map.of("foo", "bar"))
            .build());

        var defaultServerTlsPolicy = new ServerTlsPolicy("defaultServerTlsPolicy", ServerTlsPolicyArgs.builder()
            .name("my-tls-policy")
            .description("my description")
            .location("global")
            .allowOpen(false)
            .mtlsPolicy(ServerTlsPolicyMtlsPolicyArgs.builder()
                .clientValidationMode("ALLOW_INVALID_OR_MISSING_CLIENT_CERT")
                .clientValidationTrustConfig(defaultTrustConfig.name().applyValue(_name -> String.format("projects/%s/locations/global/trustConfigs/%s", project.number(),_name)))
                .build())
            .build());

        var defaultSSLCertificate = new SSLCertificate("defaultSSLCertificate", SSLCertificateArgs.builder()
            .name("my-certificate")
            .privateKey(StdFunctions.file(FileArgs.builder()
                .input("path/to/private.key")
                .build()).result())
            .certificate(StdFunctions.file(FileArgs.builder()
                .input("path/to/certificate.crt")
                .build()).result())
            .build());

        var defaultHttpHealthCheck = new HttpHealthCheck("defaultHttpHealthCheck", HttpHealthCheckArgs.builder()
            .name("http-health-check")
            .requestPath("/")
            .checkIntervalSec(1)
            .timeoutSec(1)
            .build());

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

        var defaultURLMap = new URLMap("defaultURLMap", URLMapArgs.builder()
            .name("url-map")
            .description("a description")
            .defaultService(defaultBackendService.id())
            .hostRules(URLMapHostRuleArgs.builder()
                .hosts("mysite.com")
                .pathMatcher("allpaths")
                .build())
            .pathMatchers(URLMapPathMatcherArgs.builder()
                .name("allpaths")
                .defaultService(defaultBackendService.id())
                .pathRules(URLMapPathMatcherPathRuleArgs.builder()
                    .paths("/*")
                    .service(defaultBackendService.id())
                    .build())
                .build())
            .build());

        var default_ = new TargetHttpsProxy("default", TargetHttpsProxyArgs.builder()
            .name("test-mtls-proxy")
            .urlMap(defaultURLMap.id())
            .sslCertificates(defaultSSLCertificate.id())
            .serverTlsPolicy(defaultServerTlsPolicy.id())
            .build());

    }
}
resources:
  default:
    type: gcp:compute:TargetHttpsProxy
    properties:
      name: test-mtls-proxy
      urlMap: ${defaultURLMap.id}
      sslCertificates:
        - ${defaultSSLCertificate.id}
      serverTlsPolicy: ${defaultServerTlsPolicy.id}
  defaultTrustConfig:
    type: gcp:certificatemanager:TrustConfig
    name: default
    properties:
      name: my-trust-config
      description: sample description for the trust config
      location: global
      trustStores:
        - trustAnchors:
            - pemCertificate:
                fn::invoke:
                  function: std:file
                  arguments:
                    input: test-fixtures/ca_cert.pem
                  return: result
          intermediateCas:
            - pemCertificate:
                fn::invoke:
                  function: std:file
                  arguments:
                    input: test-fixtures/ca_cert.pem
                  return: result
      labels:
        foo: bar
  defaultServerTlsPolicy:
    type: gcp:networksecurity:ServerTlsPolicy
    name: default
    properties:
      name: my-tls-policy
      description: my description
      location: global
      allowOpen: 'false'
      mtlsPolicy:
        clientValidationMode: ALLOW_INVALID_OR_MISSING_CLIENT_CERT
        clientValidationTrustConfig: projects/${project.number}/locations/global/trustConfigs/${defaultTrustConfig.name}
  defaultSSLCertificate:
    type: gcp:compute:SSLCertificate
    name: default
    properties:
      name: my-certificate
      privateKey:
        fn::invoke:
          function: std:file
          arguments:
            input: path/to/private.key
          return: result
      certificate:
        fn::invoke:
          function: std:file
          arguments:
            input: path/to/certificate.crt
          return: result
  defaultURLMap:
    type: gcp:compute:URLMap
    name: default
    properties:
      name: url-map
      description: a description
      defaultService: ${defaultBackendService.id}
      hostRules:
        - hosts:
            - mysite.com
          pathMatcher: allpaths
      pathMatchers:
        - name: allpaths
          defaultService: ${defaultBackendService.id}
          pathRules:
            - paths:
                - /*
              service: ${defaultBackendService.id}
  defaultBackendService:
    type: gcp:compute:BackendService
    name: default
    properties:
      name: backend-service
      portName: http
      protocol: HTTP
      timeoutSec: 10
      healthChecks: ${defaultHttpHealthCheck.id}
  defaultHttpHealthCheck:
    type: gcp:compute:HttpHealthCheck
    name: default
    properties:
      name: http-health-check
      requestPath: /
      checkIntervalSec: 1
      timeoutSec: 1
variables:
  project:
    fn::invoke:
      function: gcp:organizations:getProject
      arguments: {}

The serverTlsPolicy references a ServerTlsPolicy resource that defines client validation rules. The TrustConfig specifies trust anchors (root CAs) and intermediate CAs used to validate client certificates. The clientValidationMode determines whether invalid or missing client certificates are rejected or allowed. This configuration enables API gateways or internal services to authenticate clients via certificates.

Use Certificate Manager for centralized certificate lifecycle

Organizations managing certificates across multiple services can use Certificate Manager to provision and rotate certificates independently.

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

const defaultCertificate = new gcp.certificatemanager.Certificate("default", {
    name: "my-certificate",
    scope: "ALL_REGIONS",
    selfManaged: {
        pemCertificate: std.file({
            input: "test-fixtures/cert.pem",
        }).then(invoke => invoke.result),
        pemPrivateKey: std.file({
            input: "test-fixtures/private-key.pem",
        }).then(invoke => invoke.result),
    },
});
const defaultBackendService = new gcp.compute.BackendService("default", {
    name: "backend-service",
    portName: "http",
    protocol: "HTTP",
    timeoutSec: 10,
    loadBalancingScheme: "INTERNAL_MANAGED",
});
const defaultURLMap = new gcp.compute.URLMap("default", {
    name: "url-map",
    description: "a description",
    defaultService: defaultBackendService.id,
    hostRules: [{
        hosts: ["mysite.com"],
        pathMatcher: "allpaths",
    }],
    pathMatchers: [{
        name: "allpaths",
        defaultService: defaultBackendService.id,
        pathRules: [{
            paths: ["/*"],
            service: defaultBackendService.id,
        }],
    }],
});
const _default = new gcp.compute.TargetHttpsProxy("default", {
    name: "target-http-proxy",
    urlMap: defaultURLMap.id,
    certificateManagerCertificates: [pulumi.interpolate`//certificatemanager.googleapis.com/${defaultCertificate.id}`],
});
import pulumi
import pulumi_gcp as gcp
import pulumi_std as std

default_certificate = gcp.certificatemanager.Certificate("default",
    name="my-certificate",
    scope="ALL_REGIONS",
    self_managed={
        "pem_certificate": std.file(input="test-fixtures/cert.pem").result,
        "pem_private_key": std.file(input="test-fixtures/private-key.pem").result,
    })
default_backend_service = gcp.compute.BackendService("default",
    name="backend-service",
    port_name="http",
    protocol="HTTP",
    timeout_sec=10,
    load_balancing_scheme="INTERNAL_MANAGED")
default_url_map = gcp.compute.URLMap("default",
    name="url-map",
    description="a description",
    default_service=default_backend_service.id,
    host_rules=[{
        "hosts": ["mysite.com"],
        "path_matcher": "allpaths",
    }],
    path_matchers=[{
        "name": "allpaths",
        "default_service": default_backend_service.id,
        "path_rules": [{
            "paths": ["/*"],
            "service": default_backend_service.id,
        }],
    }])
default = gcp.compute.TargetHttpsProxy("default",
    name="target-http-proxy",
    url_map=default_url_map.id,
    certificate_manager_certificates=[default_certificate.id.apply(lambda id: f"//certificatemanager.googleapis.com/{id}")])
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/certificatemanager"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi-std/sdk/go/std"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		invokeFile, err := std.File(ctx, &std.FileArgs{
			Input: "test-fixtures/cert.pem",
		}, nil)
		if err != nil {
			return err
		}
		invokeFile1, err := std.File(ctx, &std.FileArgs{
			Input: "test-fixtures/private-key.pem",
		}, nil)
		if err != nil {
			return err
		}
		defaultCertificate, err := certificatemanager.NewCertificate(ctx, "default", &certificatemanager.CertificateArgs{
			Name:  pulumi.String("my-certificate"),
			Scope: pulumi.String("ALL_REGIONS"),
			SelfManaged: &certificatemanager.CertificateSelfManagedArgs{
				PemCertificate: pulumi.String(invokeFile.Result),
				PemPrivateKey:  pulumi.String(invokeFile1.Result),
			},
		})
		if err != nil {
			return err
		}
		defaultBackendService, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
			Name:                pulumi.String("backend-service"),
			PortName:            pulumi.String("http"),
			Protocol:            pulumi.String("HTTP"),
			TimeoutSec:          pulumi.Int(10),
			LoadBalancingScheme: pulumi.String("INTERNAL_MANAGED"),
		})
		if err != nil {
			return err
		}
		defaultURLMap, err := compute.NewURLMap(ctx, "default", &compute.URLMapArgs{
			Name:           pulumi.String("url-map"),
			Description:    pulumi.String("a description"),
			DefaultService: defaultBackendService.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: defaultBackendService.ID(),
					PathRules: compute.URLMapPathMatcherPathRuleArray{
						&compute.URLMapPathMatcherPathRuleArgs{
							Paths: pulumi.StringArray{
								pulumi.String("/*"),
							},
							Service: defaultBackendService.ID(),
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewTargetHttpsProxy(ctx, "default", &compute.TargetHttpsProxyArgs{
			Name:   pulumi.String("target-http-proxy"),
			UrlMap: defaultURLMap.ID(),
			CertificateManagerCertificates: pulumi.StringArray{
				defaultCertificate.ID().ApplyT(func(id string) (string, error) {
					return fmt.Sprintf("//certificatemanager.googleapis.com/%v", id), nil
				}).(pulumi.StringOutput),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Std = Pulumi.Std;

return await Deployment.RunAsync(() => 
{
    var defaultCertificate = new Gcp.CertificateManager.Certificate("default", new()
    {
        Name = "my-certificate",
        Scope = "ALL_REGIONS",
        SelfManaged = new Gcp.CertificateManager.Inputs.CertificateSelfManagedArgs
        {
            PemCertificate = Std.File.Invoke(new()
            {
                Input = "test-fixtures/cert.pem",
            }).Apply(invoke => invoke.Result),
            PemPrivateKey = Std.File.Invoke(new()
            {
                Input = "test-fixtures/private-key.pem",
            }).Apply(invoke => invoke.Result),
        },
    });

    var defaultBackendService = new Gcp.Compute.BackendService("default", new()
    {
        Name = "backend-service",
        PortName = "http",
        Protocol = "HTTP",
        TimeoutSec = 10,
        LoadBalancingScheme = "INTERNAL_MANAGED",
    });

    var defaultURLMap = new Gcp.Compute.URLMap("default", new()
    {
        Name = "url-map",
        Description = "a description",
        DefaultService = defaultBackendService.Id,
        HostRules = new[]
        {
            new Gcp.Compute.Inputs.URLMapHostRuleArgs
            {
                Hosts = new[]
                {
                    "mysite.com",
                },
                PathMatcher = "allpaths",
            },
        },
        PathMatchers = new[]
        {
            new Gcp.Compute.Inputs.URLMapPathMatcherArgs
            {
                Name = "allpaths",
                DefaultService = defaultBackendService.Id,
                PathRules = new[]
                {
                    new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleArgs
                    {
                        Paths = new[]
                        {
                            "/*",
                        },
                        Service = defaultBackendService.Id,
                    },
                },
            },
        },
    });

    var @default = new Gcp.Compute.TargetHttpsProxy("default", new()
    {
        Name = "target-http-proxy",
        UrlMap = defaultURLMap.Id,
        CertificateManagerCertificates = new[]
        {
            defaultCertificate.Id.Apply(id => $"//certificatemanager.googleapis.com/{id}"),
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.certificatemanager.Certificate;
import com.pulumi.gcp.certificatemanager.CertificateArgs;
import com.pulumi.gcp.certificatemanager.inputs.CertificateSelfManagedArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.FileArgs;
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.TargetHttpsProxy;
import com.pulumi.gcp.compute.TargetHttpsProxyArgs;
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 defaultCertificate = new Certificate("defaultCertificate", CertificateArgs.builder()
            .name("my-certificate")
            .scope("ALL_REGIONS")
            .selfManaged(CertificateSelfManagedArgs.builder()
                .pemCertificate(StdFunctions.file(FileArgs.builder()
                    .input("test-fixtures/cert.pem")
                    .build()).result())
                .pemPrivateKey(StdFunctions.file(FileArgs.builder()
                    .input("test-fixtures/private-key.pem")
                    .build()).result())
                .build())
            .build());

        var defaultBackendService = new BackendService("defaultBackendService", BackendServiceArgs.builder()
            .name("backend-service")
            .portName("http")
            .protocol("HTTP")
            .timeoutSec(10)
            .loadBalancingScheme("INTERNAL_MANAGED")
            .build());

        var defaultURLMap = new URLMap("defaultURLMap", URLMapArgs.builder()
            .name("url-map")
            .description("a description")
            .defaultService(defaultBackendService.id())
            .hostRules(URLMapHostRuleArgs.builder()
                .hosts("mysite.com")
                .pathMatcher("allpaths")
                .build())
            .pathMatchers(URLMapPathMatcherArgs.builder()
                .name("allpaths")
                .defaultService(defaultBackendService.id())
                .pathRules(URLMapPathMatcherPathRuleArgs.builder()
                    .paths("/*")
                    .service(defaultBackendService.id())
                    .build())
                .build())
            .build());

        var default_ = new TargetHttpsProxy("default", TargetHttpsProxyArgs.builder()
            .name("target-http-proxy")
            .urlMap(defaultURLMap.id())
            .certificateManagerCertificates(defaultCertificate.id().applyValue(_id -> String.format("//certificatemanager.googleapis.com/%s", _id)))
            .build());

    }
}
resources:
  default:
    type: gcp:compute:TargetHttpsProxy
    properties:
      name: target-http-proxy
      urlMap: ${defaultURLMap.id}
      certificateManagerCertificates: # [google_certificate_manager_certificate.default.id] is also acceptable
        - //certificatemanager.googleapis.com/${defaultCertificate.id}
  defaultCertificate:
    type: gcp:certificatemanager:Certificate
    name: default
    properties:
      name: my-certificate
      scope: ALL_REGIONS
      selfManaged:
        pemCertificate:
          fn::invoke:
            function: std:file
            arguments:
              input: test-fixtures/cert.pem
            return: result
        pemPrivateKey:
          fn::invoke:
            function: std:file
            arguments:
              input: test-fixtures/private-key.pem
            return: result
  defaultURLMap:
    type: gcp:compute:URLMap
    name: default
    properties:
      name: url-map
      description: a description
      defaultService: ${defaultBackendService.id}
      hostRules:
        - hosts:
            - mysite.com
          pathMatcher: allpaths
      pathMatchers:
        - name: allpaths
          defaultService: ${defaultBackendService.id}
          pathRules:
            - paths:
                - /*
              service: ${defaultBackendService.id}
  defaultBackendService:
    type: gcp:compute:BackendService
    name: default
    properties:
      name: backend-service
      portName: http
      protocol: HTTP
      timeoutSec: 10
      loadBalancingScheme: INTERNAL_MANAGED

The certificateManagerCertificates property references certificates managed by Certificate Manager rather than Compute Engine SSL certificates. This approach works only with INTERNAL_MANAGED load balancers. Certificate Manager handles renewal and rotation separately from the proxy configuration, reducing operational overhead for certificate lifecycle management.

Beyond these examples

These snippets focus on specific target proxy features: SSL certificate attachment, connection keep-alive tuning, and mutual TLS with trust configs. They’re intentionally minimal rather than full load balancing deployments.

The examples may reference pre-existing infrastructure such as URL maps and backend services, SSL certificate files in PEM format, and forwarding rules that aren’t created in the examples. They focus on configuring the proxy rather than provisioning the complete load balancing stack.

To keep things focused, common proxy patterns are omitted, including:

  • QUIC protocol negotiation (quicOverride)
  • SSL policy references for cipher suite control
  • Certificate maps for SNI-based routing
  • TLS 1.3 Early Data configuration (tlsEarlyData)

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

Let's configure GCP Target HTTPS Proxies

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Certificate Configuration
Can I use both sslCertificates and certificateManagerCertificates on the same proxy?
No, these fields are mutually exclusive. You must choose one certificate method based on your load balancing scheme.
Which certificate option should I use for my load balancing scheme?

Choose based on your scheme:

  • INTERNAL_MANAGED: Use certificateManagerCertificates
  • EXTERNAL/EXTERNAL_MANAGED: Use certificateMap
  • Other schemes (except INTERNAL_SELF_MANAGED): Use sslCertificates
  • INTERNAL_SELF_MANAGED: sslCertificates do not apply
How many SSL certificates can I attach to a target HTTPS proxy?
You can specify up to 15 SSL certificates using the sslCertificates field.
What format should I use for Certificate Manager certificates?
Use //certificatemanager.googleapis.com/projects/{project}/locations/{location}/certificates/{resourceName} or just the self_link projects/{project}/locations/{location}/certificates/{resourceName}.
Resource Lifecycle & Updates
Why am I getting a resourceInUseByAnotherResource error when updating serverTlsPolicy?
This occurs when you remove serverTlsPolicy while simultaneously deleting or recreating the referenced ServerTlsPolicy resource. Use lifecycle.create_before_destroy within the ServerTlsPolicy resource to avoid this error.
Which properties are immutable after creation?
The following properties cannot be changed after creation: name, project, proxyBind, tlsEarlyData, description, and httpKeepAliveTimeoutSec.
Connection & Performance Settings
What are the HTTP keep-alive timeout defaults and limits?

Defaults and limits vary by load balancer type:

  • Global external HTTP(S): Default 610s, min 5s, max 1200s
  • Cross-region internal HTTP(S): Default 600s, min 5s, max 600s
  • Global external HTTP(S) classic: Not publicly available
How does QUIC override work?
Set quicOverride to control QUIC negotiation. Default is NONE (Google manages QUIC). Options are NONE, ENABLE, or DISABLE.
What does TLS Early Data do?
TLS 1.3 0-RTT Data (Early Data) allows including the initial HTTP request alongside the TLS handshake, reducing round trips to zero. This applies to HTTP/2 over TCP and QUIC/h3 over UDP. Options: STRICT, PERMISSIVE, UNRESTRICTED, DISABLED.
Configuration & Setup
How do I configure mutual TLS (mTLS) for my HTTPS proxy?
Set serverTlsPolicy to reference a networksecurity.ServerTlsPolicy resource that includes mtlsPolicy configuration with client validation settings and trust config.
What are the naming requirements for a target HTTPS proxy?
Names must be 1-63 characters long and match the regex [a-z][-a-z0-9]*[a-z0-9]: start with a lowercase letter, contain only lowercase letters, digits, or dashes, and end with a letter or digit (not a dash).

Using a different cloud?

Explore networking guides for other cloud providers: