Configure GCP Edge Cache Origins

The gcp:networkservices/edgeCacheOrigin:EdgeCacheOrigin resource, part of the Pulumi GCP provider, defines an HTTP-reachable backend for Media CDN: its address, connection settings, and authentication. This guide focuses on three capabilities: Cloud Storage bucket origins, retry and failover configuration, and AWS S3 authentication.

Origins reference Cloud Storage buckets, HTTP servers, or AWS S3 buckets that must exist separately. Some configurations require Secret Manager for authentication credentials. The examples are intentionally small. Combine them with your own EdgeCacheService and routing rules.

Connect to a Cloud Storage bucket origin

Media CDN deployments often start by pointing to a Cloud Storage bucket that holds static assets or media files, providing a simple origin without managing HTTP servers.

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

const _default = new gcp.networkservices.EdgeCacheOrigin("default", {
    name: "my-origin",
    originAddress: "gs://media-edge-default",
    description: "The default bucket for media edge test",
});
import pulumi
import pulumi_gcp as gcp

default = gcp.networkservices.EdgeCacheOrigin("default",
    name="my-origin",
    origin_address="gs://media-edge-default",
    description="The default bucket for media edge test")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := networkservices.NewEdgeCacheOrigin(ctx, "default", &networkservices.EdgeCacheOriginArgs{
			Name:          pulumi.String("my-origin"),
			OriginAddress: pulumi.String("gs://media-edge-default"),
			Description:   pulumi.String("The default bucket for media edge test"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var @default = new Gcp.NetworkServices.EdgeCacheOrigin("default", new()
    {
        Name = "my-origin",
        OriginAddress = "gs://media-edge-default",
        Description = "The default bucket for media edge test",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networkservices.EdgeCacheOrigin;
import com.pulumi.gcp.networkservices.EdgeCacheOriginArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

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

    public static void stack(Context ctx) {
        var default_ = new EdgeCacheOrigin("default", EdgeCacheOriginArgs.builder()
            .name("my-origin")
            .originAddress("gs://media-edge-default")
            .description("The default bucket for media edge test")
            .build());

    }
}
resources:
  default:
    type: gcp:networkservices:EdgeCacheOrigin
    properties:
      name: my-origin
      originAddress: gs://media-edge-default
      description: The default bucket for media edge test

The originAddress property accepts Cloud Storage buckets in canonical “gs://bucketname” format. Media CDN connects to the bucket using HTTP2 on port 443 by default. The name must be unique within your project and follow the naming pattern (letter first, then letters, digits, dashes, or underscores).

Configure retry logic and failover origins

Production CDN configurations need resilience against origin failures. Media CDN retries failed requests based on specific conditions and falls back to alternate origins when the primary becomes unavailable.

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

const fallback = new gcp.networkservices.EdgeCacheOrigin("fallback", {
    name: "my-fallback",
    originAddress: "fallback.example.com",
    description: "The default bucket for media edge test",
    maxAttempts: 3,
    protocol: "HTTP",
    port: 80,
    retryConditions: [
        "CONNECT_FAILURE",
        "NOT_FOUND",
        "HTTP_5XX",
        "FORBIDDEN",
    ],
    timeout: {
        connectTimeout: "10s",
        maxAttemptsTimeout: "20s",
        responseTimeout: "60s",
        readTimeout: "5s",
    },
    originOverrideAction: {
        urlRewrite: {
            hostRewrite: "example.com",
        },
        headerAction: {
            requestHeadersToAdds: [{
                headerName: "x-header",
                headerValue: "value",
                replace: true,
            }],
        },
    },
    originRedirect: {
        redirectConditions: [
            "MOVED_PERMANENTLY",
            "FOUND",
            "SEE_OTHER",
            "TEMPORARY_REDIRECT",
            "PERMANENT_REDIRECT",
        ],
    },
});
const _default = new gcp.networkservices.EdgeCacheOrigin("default", {
    name: "my-origin",
    originAddress: "gs://media-edge-default",
    failoverOrigin: fallback.id,
    description: "The default bucket for media edge test",
    maxAttempts: 2,
    labels: {
        a: "b",
    },
    timeout: {
        connectTimeout: "10s",
    },
});
import pulumi
import pulumi_gcp as gcp

fallback = gcp.networkservices.EdgeCacheOrigin("fallback",
    name="my-fallback",
    origin_address="fallback.example.com",
    description="The default bucket for media edge test",
    max_attempts=3,
    protocol="HTTP",
    port=80,
    retry_conditions=[
        "CONNECT_FAILURE",
        "NOT_FOUND",
        "HTTP_5XX",
        "FORBIDDEN",
    ],
    timeout={
        "connect_timeout": "10s",
        "max_attempts_timeout": "20s",
        "response_timeout": "60s",
        "read_timeout": "5s",
    },
    origin_override_action={
        "url_rewrite": {
            "host_rewrite": "example.com",
        },
        "header_action": {
            "request_headers_to_adds": [{
                "header_name": "x-header",
                "header_value": "value",
                "replace": True,
            }],
        },
    },
    origin_redirect={
        "redirect_conditions": [
            "MOVED_PERMANENTLY",
            "FOUND",
            "SEE_OTHER",
            "TEMPORARY_REDIRECT",
            "PERMANENT_REDIRECT",
        ],
    })
default = gcp.networkservices.EdgeCacheOrigin("default",
    name="my-origin",
    origin_address="gs://media-edge-default",
    failover_origin=fallback.id,
    description="The default bucket for media edge test",
    max_attempts=2,
    labels={
        "a": "b",
    },
    timeout={
        "connect_timeout": "10s",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		fallback, err := networkservices.NewEdgeCacheOrigin(ctx, "fallback", &networkservices.EdgeCacheOriginArgs{
			Name:          pulumi.String("my-fallback"),
			OriginAddress: pulumi.String("fallback.example.com"),
			Description:   pulumi.String("The default bucket for media edge test"),
			MaxAttempts:   pulumi.Int(3),
			Protocol:      pulumi.String("HTTP"),
			Port:          pulumi.Int(80),
			RetryConditions: pulumi.StringArray{
				pulumi.String("CONNECT_FAILURE"),
				pulumi.String("NOT_FOUND"),
				pulumi.String("HTTP_5XX"),
				pulumi.String("FORBIDDEN"),
			},
			Timeout: &networkservices.EdgeCacheOriginTimeoutArgs{
				ConnectTimeout:     pulumi.String("10s"),
				MaxAttemptsTimeout: pulumi.String("20s"),
				ResponseTimeout:    pulumi.String("60s"),
				ReadTimeout:        pulumi.String("5s"),
			},
			OriginOverrideAction: &networkservices.EdgeCacheOriginOriginOverrideActionArgs{
				UrlRewrite: &networkservices.EdgeCacheOriginOriginOverrideActionUrlRewriteArgs{
					HostRewrite: pulumi.String("example.com"),
				},
				HeaderAction: &networkservices.EdgeCacheOriginOriginOverrideActionHeaderActionArgs{
					RequestHeadersToAdds: networkservices.EdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddArray{
						&networkservices.EdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddArgs{
							HeaderName:  pulumi.String("x-header"),
							HeaderValue: pulumi.String("value"),
							Replace:     pulumi.Bool(true),
						},
					},
				},
			},
			OriginRedirect: &networkservices.EdgeCacheOriginOriginRedirectArgs{
				RedirectConditions: pulumi.StringArray{
					pulumi.String("MOVED_PERMANENTLY"),
					pulumi.String("FOUND"),
					pulumi.String("SEE_OTHER"),
					pulumi.String("TEMPORARY_REDIRECT"),
					pulumi.String("PERMANENT_REDIRECT"),
				},
			},
		})
		if err != nil {
			return err
		}
		_, err = networkservices.NewEdgeCacheOrigin(ctx, "default", &networkservices.EdgeCacheOriginArgs{
			Name:           pulumi.String("my-origin"),
			OriginAddress:  pulumi.String("gs://media-edge-default"),
			FailoverOrigin: fallback.ID(),
			Description:    pulumi.String("The default bucket for media edge test"),
			MaxAttempts:    pulumi.Int(2),
			Labels: pulumi.StringMap{
				"a": pulumi.String("b"),
			},
			Timeout: &networkservices.EdgeCacheOriginTimeoutArgs{
				ConnectTimeout: pulumi.String("10s"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var fallback = new Gcp.NetworkServices.EdgeCacheOrigin("fallback", new()
    {
        Name = "my-fallback",
        OriginAddress = "fallback.example.com",
        Description = "The default bucket for media edge test",
        MaxAttempts = 3,
        Protocol = "HTTP",
        Port = 80,
        RetryConditions = new[]
        {
            "CONNECT_FAILURE",
            "NOT_FOUND",
            "HTTP_5XX",
            "FORBIDDEN",
        },
        Timeout = new Gcp.NetworkServices.Inputs.EdgeCacheOriginTimeoutArgs
        {
            ConnectTimeout = "10s",
            MaxAttemptsTimeout = "20s",
            ResponseTimeout = "60s",
            ReadTimeout = "5s",
        },
        OriginOverrideAction = new Gcp.NetworkServices.Inputs.EdgeCacheOriginOriginOverrideActionArgs
        {
            UrlRewrite = new Gcp.NetworkServices.Inputs.EdgeCacheOriginOriginOverrideActionUrlRewriteArgs
            {
                HostRewrite = "example.com",
            },
            HeaderAction = new Gcp.NetworkServices.Inputs.EdgeCacheOriginOriginOverrideActionHeaderActionArgs
            {
                RequestHeadersToAdds = new[]
                {
                    new Gcp.NetworkServices.Inputs.EdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddArgs
                    {
                        HeaderName = "x-header",
                        HeaderValue = "value",
                        Replace = true,
                    },
                },
            },
        },
        OriginRedirect = new Gcp.NetworkServices.Inputs.EdgeCacheOriginOriginRedirectArgs
        {
            RedirectConditions = new[]
            {
                "MOVED_PERMANENTLY",
                "FOUND",
                "SEE_OTHER",
                "TEMPORARY_REDIRECT",
                "PERMANENT_REDIRECT",
            },
        },
    });

    var @default = new Gcp.NetworkServices.EdgeCacheOrigin("default", new()
    {
        Name = "my-origin",
        OriginAddress = "gs://media-edge-default",
        FailoverOrigin = fallback.Id,
        Description = "The default bucket for media edge test",
        MaxAttempts = 2,
        Labels = 
        {
            { "a", "b" },
        },
        Timeout = new Gcp.NetworkServices.Inputs.EdgeCacheOriginTimeoutArgs
        {
            ConnectTimeout = "10s",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networkservices.EdgeCacheOrigin;
import com.pulumi.gcp.networkservices.EdgeCacheOriginArgs;
import com.pulumi.gcp.networkservices.inputs.EdgeCacheOriginTimeoutArgs;
import com.pulumi.gcp.networkservices.inputs.EdgeCacheOriginOriginOverrideActionArgs;
import com.pulumi.gcp.networkservices.inputs.EdgeCacheOriginOriginOverrideActionUrlRewriteArgs;
import com.pulumi.gcp.networkservices.inputs.EdgeCacheOriginOriginOverrideActionHeaderActionArgs;
import com.pulumi.gcp.networkservices.inputs.EdgeCacheOriginOriginRedirectArgs;
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 fallback = new EdgeCacheOrigin("fallback", EdgeCacheOriginArgs.builder()
            .name("my-fallback")
            .originAddress("fallback.example.com")
            .description("The default bucket for media edge test")
            .maxAttempts(3)
            .protocol("HTTP")
            .port(80)
            .retryConditions(            
                "CONNECT_FAILURE",
                "NOT_FOUND",
                "HTTP_5XX",
                "FORBIDDEN")
            .timeout(EdgeCacheOriginTimeoutArgs.builder()
                .connectTimeout("10s")
                .maxAttemptsTimeout("20s")
                .responseTimeout("60s")
                .readTimeout("5s")
                .build())
            .originOverrideAction(EdgeCacheOriginOriginOverrideActionArgs.builder()
                .urlRewrite(EdgeCacheOriginOriginOverrideActionUrlRewriteArgs.builder()
                    .hostRewrite("example.com")
                    .build())
                .headerAction(EdgeCacheOriginOriginOverrideActionHeaderActionArgs.builder()
                    .requestHeadersToAdds(EdgeCacheOriginOriginOverrideActionHeaderActionRequestHeadersToAddArgs.builder()
                        .headerName("x-header")
                        .headerValue("value")
                        .replace(true)
                        .build())
                    .build())
                .build())
            .originRedirect(EdgeCacheOriginOriginRedirectArgs.builder()
                .redirectConditions(                
                    "MOVED_PERMANENTLY",
                    "FOUND",
                    "SEE_OTHER",
                    "TEMPORARY_REDIRECT",
                    "PERMANENT_REDIRECT")
                .build())
            .build());

        var default_ = new EdgeCacheOrigin("default", EdgeCacheOriginArgs.builder()
            .name("my-origin")
            .originAddress("gs://media-edge-default")
            .failoverOrigin(fallback.id())
            .description("The default bucket for media edge test")
            .maxAttempts(2)
            .labels(Map.of("a", "b"))
            .timeout(EdgeCacheOriginTimeoutArgs.builder()
                .connectTimeout("10s")
                .build())
            .build());

    }
}
resources:
  fallback:
    type: gcp:networkservices:EdgeCacheOrigin
    properties:
      name: my-fallback
      originAddress: fallback.example.com
      description: The default bucket for media edge test
      maxAttempts: 3
      protocol: HTTP
      port: 80
      retryConditions:
        - CONNECT_FAILURE
        - NOT_FOUND
        - HTTP_5XX
        - FORBIDDEN
      timeout:
        connectTimeout: 10s
        maxAttemptsTimeout: 20s
        responseTimeout: 60s
        readTimeout: 5s
      originOverrideAction:
        urlRewrite:
          hostRewrite: example.com
        headerAction:
          requestHeadersToAdds:
            - headerName: x-header
              headerValue: value
              replace: true
      originRedirect:
        redirectConditions:
          - MOVED_PERMANENTLY
          - FOUND
          - SEE_OTHER
          - TEMPORARY_REDIRECT
          - PERMANENT_REDIRECT
  default:
    type: gcp:networkservices:EdgeCacheOrigin
    properties:
      name: my-origin
      originAddress: gs://media-edge-default
      failoverOrigin: ${fallback.id}
      description: The default bucket for media edge test
      maxAttempts: 2
      labels:
        a: b
      timeout:
        connectTimeout: 10s

When a cache fill fails with one of the configured retryConditions (like CONNECT_FAILURE or HTTP_5XX), Media CDN retries up to maxAttempts times. If all attempts fail, the failoverOrigin handles the request. The timeout block controls connection, response, and overall attempt timeouts. The originOverrideAction lets you rewrite URLs or add headers before forwarding requests, while originRedirect specifies which HTTP redirect codes to follow automatically.

Authenticate to AWS S3 with Signature V4

When using AWS S3 as an origin, Media CDN can authenticate requests using AWS Signature Version 4, allowing secure access to private S3 buckets without making them public.

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

const secret_basic = new gcp.secretmanager.Secret("secret-basic", {
    secretId: "secret-name",
    replication: {
        auto: {},
    },
});
const secret_version_basic = new gcp.secretmanager.SecretVersion("secret-version-basic", {
    secret: secret_basic.id,
    secretData: "secret-data",
});
const _default = new gcp.networkservices.EdgeCacheOrigin("default", {
    name: "my-origin",
    originAddress: "gs://media-edge-default",
    description: "The default bucket for V4 authentication",
    awsV4Authentication: {
        accessKeyId: "ACCESSKEYID",
        secretAccessKeyVersion: secret_version_basic.id,
        originRegion: "auto",
    },
});
import pulumi
import pulumi_gcp as gcp

secret_basic = gcp.secretmanager.Secret("secret-basic",
    secret_id="secret-name",
    replication={
        "auto": {},
    })
secret_version_basic = gcp.secretmanager.SecretVersion("secret-version-basic",
    secret=secret_basic.id,
    secret_data="secret-data")
default = gcp.networkservices.EdgeCacheOrigin("default",
    name="my-origin",
    origin_address="gs://media-edge-default",
    description="The default bucket for V4 authentication",
    aws_v4_authentication={
        "access_key_id": "ACCESSKEYID",
        "secret_access_key_version": secret_version_basic.id,
        "origin_region": "auto",
    })
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networkservices"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/secretmanager"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		secret_basic, err := secretmanager.NewSecret(ctx, "secret-basic", &secretmanager.SecretArgs{
			SecretId: pulumi.String("secret-name"),
			Replication: &secretmanager.SecretReplicationArgs{
				Auto: &secretmanager.SecretReplicationAutoArgs{},
			},
		})
		if err != nil {
			return err
		}
		secret_version_basic, err := secretmanager.NewSecretVersion(ctx, "secret-version-basic", &secretmanager.SecretVersionArgs{
			Secret:     secret_basic.ID(),
			SecretData: pulumi.String("secret-data"),
		})
		if err != nil {
			return err
		}
		_, err = networkservices.NewEdgeCacheOrigin(ctx, "default", &networkservices.EdgeCacheOriginArgs{
			Name:          pulumi.String("my-origin"),
			OriginAddress: pulumi.String("gs://media-edge-default"),
			Description:   pulumi.String("The default bucket for V4 authentication"),
			AwsV4Authentication: &networkservices.EdgeCacheOriginAwsV4AuthenticationArgs{
				AccessKeyId:            pulumi.String("ACCESSKEYID"),
				SecretAccessKeyVersion: secret_version_basic.ID(),
				OriginRegion:           pulumi.String("auto"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var secret_basic = new Gcp.SecretManager.Secret("secret-basic", new()
    {
        SecretId = "secret-name",
        Replication = new Gcp.SecretManager.Inputs.SecretReplicationArgs
        {
            Auto = null,
        },
    });

    var secret_version_basic = new Gcp.SecretManager.SecretVersion("secret-version-basic", new()
    {
        Secret = secret_basic.Id,
        SecretData = "secret-data",
    });

    var @default = new Gcp.NetworkServices.EdgeCacheOrigin("default", new()
    {
        Name = "my-origin",
        OriginAddress = "gs://media-edge-default",
        Description = "The default bucket for V4 authentication",
        AwsV4Authentication = new Gcp.NetworkServices.Inputs.EdgeCacheOriginAwsV4AuthenticationArgs
        {
            AccessKeyId = "ACCESSKEYID",
            SecretAccessKeyVersion = secret_version_basic.Id,
            OriginRegion = "auto",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.secretmanager.Secret;
import com.pulumi.gcp.secretmanager.SecretArgs;
import com.pulumi.gcp.secretmanager.inputs.SecretReplicationArgs;
import com.pulumi.gcp.secretmanager.inputs.SecretReplicationAutoArgs;
import com.pulumi.gcp.secretmanager.SecretVersion;
import com.pulumi.gcp.secretmanager.SecretVersionArgs;
import com.pulumi.gcp.networkservices.EdgeCacheOrigin;
import com.pulumi.gcp.networkservices.EdgeCacheOriginArgs;
import com.pulumi.gcp.networkservices.inputs.EdgeCacheOriginAwsV4AuthenticationArgs;
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 secret_basic = new Secret("secret-basic", SecretArgs.builder()
            .secretId("secret-name")
            .replication(SecretReplicationArgs.builder()
                .auto(SecretReplicationAutoArgs.builder()
                    .build())
                .build())
            .build());

        var secret_version_basic = new SecretVersion("secret-version-basic", SecretVersionArgs.builder()
            .secret(secret_basic.id())
            .secretData("secret-data")
            .build());

        var default_ = new EdgeCacheOrigin("default", EdgeCacheOriginArgs.builder()
            .name("my-origin")
            .originAddress("gs://media-edge-default")
            .description("The default bucket for V4 authentication")
            .awsV4Authentication(EdgeCacheOriginAwsV4AuthenticationArgs.builder()
                .accessKeyId("ACCESSKEYID")
                .secretAccessKeyVersion(secret_version_basic.id())
                .originRegion("auto")
                .build())
            .build());

    }
}
resources:
  secret-basic:
    type: gcp:secretmanager:Secret
    properties:
      secretId: secret-name
      replication:
        auto: {}
  secret-version-basic:
    type: gcp:secretmanager:SecretVersion
    properties:
      secret: ${["secret-basic"].id}
      secretData: secret-data
  default:
    type: gcp:networkservices:EdgeCacheOrigin
    properties:
      name: my-origin
      originAddress: gs://media-edge-default
      description: The default bucket for V4 authentication
      awsV4Authentication:
        accessKeyId: ACCESSKEYID
        secretAccessKeyVersion: ${["secret-version-basic"].id}
        originRegion: auto

The awsV4Authentication block enables AWS authentication by providing an accessKeyId and a reference to a Secret Manager secret containing the secret access key. The originRegion specifies which AWS region to sign requests for (use “auto” to detect from the bucket). Media CDN retrieves the secret at runtime to sign each origin request.

Beyond these examples

These snippets focus on specific origin-level features: Cloud Storage and HTTP origins, retry logic and failover, and AWS S3 authentication. They’re intentionally minimal rather than full CDN deployments.

The examples may reference pre-existing infrastructure such as Cloud Storage buckets or HTTP servers, Secret Manager secrets for AWS credentials, and publicly resolvable domain names. They focus on configuring the origin rather than provisioning the complete CDN stack.

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

  • Protocol and port customization (protocol, port)
  • Request/response header manipulation (originOverrideAction)
  • Redirect handling configuration (originRedirect)
  • FlexShielding caching options (flexShielding)

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

Let's configure GCP Edge Cache Origins

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Origin Configuration
What are the requirements for originAddress?
The originAddress must be a bare FQDN (e.g., media-backend.example.com), IP address, or Google Cloud Storage bucket. It cannot contain a protocol prefix like https:// or any slashes. For GCS buckets, use the canonical format gs://bucketname—other formats like storage.googleapis.com will be rejected. The address must be publicly resolvable.
What protocol should I use for my origin?
HTTP2 is the default and strongly recommended for both security and performance. When using HTTP2 or HTTPS, your origin server must present a valid, publicly-signed, unexpired TLS certificate. Use HTTP protocol only if TLS is not available.
What ports does the origin use by default?
Port 443 for HTTP2 and HTTPS protocols, port 80 for HTTP. You can override this with the port property.
Can I change the origin name after creation?
No, the name property is immutable. It must be 1-64 characters long and match the pattern [a-zA-Z][a-zA-Z0-9_-]* (start with a letter, followed by letters, digits, dashes, or underscores).
Retry & Failover
How does retry and failover work?
When a cache fill fails with a configured retryCondition, the origin request retries up to maxAttempts times (default: 1). If all attempts fail, the failoverOrigin is used if configured. The total attempts across primary and failover origins is limited to 4. If no origin returns a valid response, an HTTP 502 is returned to the client.
What retry conditions are available?

Six retry conditions are available:

  • CONNECT_FAILURE: Connection timeouts or failures
  • HTTP_5XX: Any 5xx response or no response (disconnects, timeouts)
  • GATEWAY_ERROR: Only 502, 503, or 504 responses
  • RETRIABLE_4XX: HTTP 409 (Conflict) and 429 (Too Many Requests)
  • NOT_FOUND: HTTP 404 (useful for video segment generation)
  • FORBIDDEN: HTTP 403

The default is CONNECT_FAILURE.

What are the limits on retry attempts?
The maxAttempts property must be greater than 0 and less than 4, with a default of 1. The total number of attempts across the primary origin and any failoverOrigin is limited to 4.
Timeouts & Performance
What timeout options can I configure?

The timeout property supports four timeout types:

  • connectTimeout: Time to establish connection
  • maxAttemptsTimeout: Total time across all retry attempts
  • responseTimeout: Time to receive complete response
  • readTimeout: Time to read response data
Advanced Features
How do I use AWS S3 as an origin?
Configure awsV4Authentication with three properties: accessKeyId, secretAccessKeyVersion (referencing a Secret Manager secret), and originRegion. This enables AWS Signature Version 4 authentication for S3 access.
How do I modify requests to the origin?
Use originOverrideAction to configure URL rewrites (via urlRewrite.hostRewrite) and header modifications (via headerAction.requestHeadersToAdds). You can also configure originRedirect to follow redirects with specific redirectConditions.

Using a different cloud?

Explore networking guides for other cloud providers: