Configure GCP Edge Cache Origins

The gcp:networkservices/edgeCacheOrigin:EdgeCacheOrigin resource, part of the Pulumi Google Cloud provider, defines an origin server that Media CDN can fetch content from: 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 existing infrastructure like Cloud Storage buckets, external HTTP servers, or AWS S3 buckets. For AWS authentication, you’ll need Secret Manager to store credentials. The examples are intentionally small. Combine them with your own EdgeCacheService and routing configuration.

Connect to a Cloud Storage bucket origin

CDN deployments often start by pointing Media CDN at a Cloud Storage bucket that holds static assets like images, videos, or application bundles.

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 using HTTP2 on port 443 by default (not shown in the example). The name must be unique within your project and follow the naming pattern: start with a letter, 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, it tries the failoverOrigin. The timeout block controls connection, read, 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 version 4

When Media CDN needs to fetch content from AWS S3 buckets, it authenticates using AWS Signature Version 4, which requires storing the secret access key in Secret Manager.

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. You provide the accessKeyId directly, but the secret access key must be stored in Secret Manager and referenced via secretAccessKeyVersion. The originRegion can be set to “auto” to let Media CDN detect the bucket’s region automatically. This configuration allows Media CDN to access private S3 buckets as origin servers.

Beyond these examples

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

The examples reference pre-existing infrastructure such as Cloud Storage buckets or external HTTP servers, and Secret Manager secrets for AWS authentication. They focus on configuring the origin rather than provisioning the complete Media CDN service.

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

  • Protocol and port selection (protocol, port)
  • Request/response header manipulation (originOverrideAction)
  • Redirect handling (originRedirect)
  • Flex shielding configuration (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's the correct format for originAddress?
Use a bare FQDN (e.g., media-backend.example.com), IP address (e.g., 35.218.1.1), or Cloud Storage bucket in canonical format (gs://bucketname). Don’t include protocols like https:// or any slashes. For Cloud Storage, other formats like storage.googleapis.com will be rejected.
What protocol should I use and why?
Use HTTP2 (the default), which is strongly recommended for both security and performance. When using HTTP2 or HTTPS, your origin server must present a valid, publicly-signed, unexpired TLS certificate. The HTTP protocol defaults to port 80, while HTTP2 and HTTPS default to port 443.
Does my origin need to be publicly accessible?
Yes. FQDNs must be publicly resolvable (e.g., via Google public DNS) and IP addresses must be publicly routable.
Retry & Failover
How does retry and failover logic work?
When a request fails with a configured retryCondition (default: CONNECT_FAILURE), it’s retried up to maxAttempts times (default: 1, max: 3). After exhausting attempts, the failoverOrigin is used if configured. The total attempts across primary and failover origins is limited to 4. If all origins fail, clients receive an HTTP 502 error.
What retry conditions are available?
Six conditions: CONNECT_FAILURE (connection timeouts), HTTP_5XX (any 5xx or no response), GATEWAY_ERROR (502/503/504 only), RETRIABLE_4XX (409/429), NOT_FOUND (404), and FORBIDDEN (403). The default is CONNECT_FAILURE.
How do I set up a failover origin?
Create a separate EdgeCacheOrigin resource and reference its ID in the failoverOrigin property. The failover origin can have its own maxAttempts, retryConditions, and even its own failoverOrigin.
Authentication & Security
How do I configure AWS S3 as an origin with authentication?
Use awsV4Authentication with accessKeyId, secretAccessKeyVersion (referencing a Secret Manager secret), and originRegion. This enables AWS Signature Version 4 authentication.
What TLS certificate requirements exist for HTTPS origins?
When using HTTP2 or HTTPS protocols, the origin server must present a valid, publicly-signed, unexpired TLS (SSL) certificate.
Advanced Features
How do I configure custom timeouts?
Use the timeout property with connectTimeout, maxAttemptsTimeout, responseTimeout, and readTimeout. For example, connectTimeout: "10s" sets a 10-second connection timeout.
Can I rewrite URLs or modify headers for origin requests?
Yes. Use originOverrideAction with urlRewrite for URL modifications (e.g., hostRewrite) and headerAction for adding or modifying request headers.
Resource Management
Can I rename an EdgeCacheOrigin after creation?
No, the name property is immutable. It must be 1-64 characters, start with a letter, and contain only letters, digits, dashes, or underscores.

Using a different cloud?

Explore networking guides for other cloud providers: