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 configuration, mutual TLS authentication, and Certificate Manager integration.

Target HTTPS proxies sit between forwarding rules and URL maps. They reference SSL certificates (either compute SSLCertificate resources or Certificate Manager certificates) and route decrypted traffic to backend services. The examples are intentionally small. Combine them with your own forwarding rules, backend instances, and health checks.

Route HTTPS traffic to backend services

Most HTTPS load balancers connect SSL certificates to a URL map that routes requests 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 forwards decrypted requests according to the urlMap. The URL map matches hostnames and paths to backend services. Here, all traffic to “mysite.com” routes to a single backend service.

Configure connection keep-alive for external load balancers

External managed load balancers can tune how long idle connections stay open after completing a response.

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 reuse. Setting it to 610 seconds (the default for external load balancers) keeps connections open longer, reducing handshake overhead for clients making multiple requests. This property only applies when the backend service uses loadBalancingScheme set to EXTERNAL_MANAGED.

Enforce mutual TLS authentication with trust configs

Applications 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 property references a ServerTlsPolicy resource that defines client validation rules. The TrustConfig specifies which certificate authorities to trust for client certificates. The mtlsPolicy determines whether to require valid client certificates or allow missing ones.

Use Certificate Manager for internal load balancers

Internal managed load balancers can reference certificates from Certificate Manager rather than creating compute SSL certificates.

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 accepts Certificate Manager certificate URIs. This approach centralizes certificate management and works only with INTERNAL_MANAGED load balancing schemes. For EXTERNAL or EXTERNAL_MANAGED schemes, use sslCertificates or certificateMap instead.

Beyond these examples

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

The examples may reference pre-existing infrastructure such as URL maps and backend services, health checks, and certificate files in PEM format. 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 configuration (sslPolicy)
  • TLS 1.3 early data handling (tlsEarlyData)
  • Certificate maps for EXTERNAL load balancers (certificateMap)
  • Forwarding rule creation and attachment

These omissions are intentional: the goal is to illustrate how each proxy feature is wired, not provide drop-in load balancer 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

SSL/TLS & Certificates
Can I use both sslCertificates and certificateManagerCertificates on the same proxy?
No, sslCertificates and certificateManagerCertificates cannot be defined together. You must choose one certificate type based on your load balancing scheme.
Which certificate type should I use for my load balancing scheme?
Use certificateManagerCertificates for INTERNAL_MANAGED schemes. Use certificateMap for EXTERNAL and EXTERNAL_MANAGED schemes. Use sslCertificates for EXTERNAL and EXTERNAL_MANAGED schemes (but not INTERNAL_SELF_MANAGED).
How many SSL certificates can I attach to a target HTTPS proxy?
You can specify up to 15 SSL certificates using the sslCertificates property.
How do I configure mTLS authentication for my HTTPS proxy?
Set serverTlsPolicy to reference a networksecurity.ServerTlsPolicy resource that includes mtlsPolicy configuration with client validation settings and trust config.
Why am I getting a resourceInUseByAnotherResource error when removing serverTlsPolicy?
This error occurs when you remove serverTlsPolicy from your configuration while simultaneously deleting or recreating the referenced ServerTlsPolicy resource. Use lifecycle.create_before_destroy within the ServerTlsPolicy resource to avoid this.
Connection Settings & Timeouts
What are the default and maximum values for HTTP keep-alive timeout?
For Global external HTTP(S) load balancers, the default is 610 seconds (min 5s, max 1200s). For cross-region internal HTTP(S) load balancers, the default is 600 seconds (min 5s, max 600s).
How do I enable QUIC protocol support?
Set quicOverride to ENABLE. The default value is NONE, which lets Google manage QUIC usage. You can also explicitly set it to DISABLE.
What TLS 1.3 Early Data policies are available?
You can set tlsEarlyData to STRICT, PERMISSIVE, UNRESTRICTED, or DISABLED. Early Data allows TLS resumption handshakes to include the initial HTTP request, reducing round trips to zero for TLS 1.3 connections.
Resource Configuration & Constraints
What are the naming requirements for a target HTTPS proxy?
The name must be 1-63 characters long and match the regex [a-z](?:[-a-z0-9]{0,61}[a-z0-9])?. It must start with a lowercase letter, contain only lowercase letters, digits, or dashes, and cannot end with a dash.
What properties can't I change after creating the proxy?
The following properties are immutable: name, project, proxyBind, tlsEarlyData, description, and httpKeepAliveTimeoutSec.
When does the proxyBind property apply?
The proxyBind property only applies when the forwarding rule that references this target proxy has a loadBalancingScheme set to INTERNAL_SELF_MANAGED.

Using a different cloud?

Explore networking guides for other cloud providers: