Stacktape
Stacktape


CDNs



A Content Delivery Network (CDN) is a geographically distributed network of servers that work together to provide fast delivery of internet content. By caching content in locations closer to your users, a CDN can significantly reduce latency and decrease the load on your application's origin servers. It can also improve security by providing a layer of defense against DDoS attacks.

Under the hood, Stacktape uses Amazon CloudFront, which has over 300 points of presence (PoPs) worldwide.

How a CDN works

A CDN acts as a layer between your application (the origin) and your clients.

  • Instead of sending requests directly to your application, clients send them to the CDN.
  • The CDN routes the request to the nearest PoP.
  • The PoP retrieves the response from your application (the origin).
  • The PoP sends the response to the client and caches it for future requests.
  • Subsequent requests for the same content can be served directly from the cache (a cache hit), which is much faster.

You can control which responses are cached and for how long. See the section on cache control for more information.

A diagram showing the client application flow with a CDN

Basic usage

In Stacktape, you configure a CDN on a resource, which then becomes the default origin for the CDN. You can use a CDN with a bucket, HTTP API Gateway, or Application Load Balancer.

resources:
myBucket:
type: bucket
properties:
cdn:
enabled: true

You can also configure route rewrites to forward requests for specific paths to different origins. This allows you to create hybrid infrastructures where, for example, static content is served from a bucket and dynamic content is served from an API.

CdnConfiguration  API reference
enabled
Required
cachingOptions
forwardingOptions
routeRewrites
customDomains
edgeFunctions
cloudfrontPriceClass
Default: PriceClass_All
defaultRoutePrefix
errorDocument
Default: /404.html
indexDocument
Default: '/index.html'
disableInvalidationAfterDeploy
useFirewall

CDN with a bucket

You can enable a CDN for a bucket with just two lines of configuration. By default, content from the bucket is cached for six months. This is a common pattern for serving static websites.

resources:
myBucket:
type: bucket
properties:
cdn:
enabled: true

CDN with an HTTP API Gateway

You can also enable a CDN for an HTTP API Gateway. By default, the CDN does not cache any content from an API gateway, as it's assumed to be dynamic. You can control the caching behavior by setting the Cache-Control header in your API's responses.

resources:
myApiGateway:
type: http-api-gateway
properties:
cdn:
enabled: true

CDN with an Application Load Balancer

Similarly, you can enable a CDN for an Application Load Balancer. As with an API gateway, content is not cached by default.

resources:
myLoadBalancer:
type: application-load-balancer
properties:
cdn:
enabled: true

Custom domain names

Stacktape allows you to connect your custom domain names to some of your resources (Web Service, Nextjs web, HTTP API Gateways, Application Load Balancers and Buckets with CDNs).

Connecting a custom domain to the resource does 2 things:

  • Creates DNS records:
    • If you use your custom domain with a resource, Stacktape automatically creates a DNS record (during deploy) pointing the specified domain name to the resource.
  • Adds TLS certificates
    • If the origin resource (HTTP API Gateway, Application Load Balancer or CDN) uses HTTPS protocol, Stacktape takes care of issuing and attaching correct (free, AWS-managed) certificate to the resource. This means, you do not have to deal with TLS termination as it is handled by the connected resource.
    • If you want to use your own certificates, you can configure customCertificateArns.

To manage a custom domain, it first needs to be added to your AWS account. This means that a hosted zone (collection of records managed together for a given domain) for your domain exists in your AWS account and your domain registrar's name servers are pointing to it. To learn more, refer to Adding a domain guide.

domainName
Required
customCertificateArn
disableDnsRecordCreation
resources:
myHttpApi:
type: 'http-api-gateway'
properties:
cdn:
enabled: true
customDomains:
- domainName: mydomain.com

Edge Lambda functions

You can run Lambda functions at the edge to customize the content that the CDN delivers. For more information, see the Edge Lambda Functions page.

  • You can associate edge-lambda-function with CDN to be executed:

    • onRequest - function is executed when CDN receives a request from a client(viewer) before checking CDN cache
    • onResponse - function is executed before returning the response to the client(viewer)
  • Potential use-cases for using edge functions:

    • generating immediate HTTP response without the need to check CDN cache or forward to the origin
    • modifying request (i.e rewrite url, headers etc) before forwarding to the origin
    • inspection of cookies
    • inspection/validation of authorization headers and tokens
EdgeFunctionsConfig  API reference
Parent:CdnConfigurationorCdnRouteRewrite
onRequest
onResponse
onOriginRequest
onOriginResponse
resources:
authFunction:
type: edge-lambda-function
properties:
packaging:
type: stacktape-lambda-buildpack
properties:
entryfilePath: auth-function.ts
myBucket:
type: bucket
properties:
cdn:
enabled: true
edgeFunctions:
onRequest: authFunction

Cache control

You can control the caching behavior of the CDN in two ways:

  1. Using the Cache-Control header (recommended): This gives you fine-grained control over the caching behavior for each response from your origin.
  2. Using CDN caching options: This allows you to set basic caching rules but is less flexible.

Stacktape automatically invalidates the entire CDN cache after each successful deployment. This ensures that your users always receive the latest version of your content. You can disable this behavior in the automatic invalidation settings.

Cache-Control header with buckets

You can set the Cache-Control header for objects in a bucket using metadata. When you use the directory upload feature, Stacktape can automatically set the correct headers for you using presets.

resources:
myBucket:
type: bucket
properties:
directoryUpload:
directoryPath: my-web/build
headersPreset: static-website
cdn:
enabled: true

Cache-Control header with an HTTP API Gateway or Application Load Balancer

When using a CDN with an API gateway or an ALB, you can set the Cache-Control header in the responses from your application.

resources:
myApiGateway:
type: http-api-gateway
properties:
cdn:
enabled: true
myFunction:
type: function
properties:
packaging:
type: stacktape-lambda-buildpack
properties:
entryfilePath: hello.ts
events:
- type: http-api-gateway
properties:
httpApiGatewayName: myApiGateway
method: GET
path: /hello
export default async (event, context) => {
return {
statusCode: 200,
statusDescription: '200 OK',
isBase64Encoded: false,
headers: {
'Content-Type': 'text/plain',
'Cache-Control': 'max-age=30'
},
body: 'Hello !!!'
};
};

A Lambda function that returns a response with a Cache-Control header.

For more information on the Cache-Control header, see the MDN docs.

CDN caching options

You can specify default caching behavior for your CDN. Different caching options can be set for each route rewrite.

If you don't specify any caching options, Stacktape uses the following defaults:

Origin typeminTTLmaxTTLdefaultTTL
Bucket03153600015768000
HTTP API Gateway0315360000
Application Load Balancer0315360000
resources:
myHttpApi:
type: 'http-api-gateway'
properties:
cdn:
enabled: true
cachingOptions:
defaultTTL: 60
routeRewrites:
- path: /static/*
cachingOptions:
defaultTTL: 604800
CdnCachingOptions  API reference
cacheMethods
minTTL
maxTTL
defaultTTL
disableCompression
cacheKeyParameters
cachePolicyId

Controlling the cache key

The cache key is a unique identifier for each object in the cache. It determines whether a request results in a cache hit. By default, the cache key is based on the URL path, but you can configure it to include headers, cookies, or query parameters.

If you don't specify a cache key, Stacktape uses the following defaults:

Origin typeParts of request included in cache key
BucketURL path
HTTP API GatewayURL path, all query params, and the Authorization header
Application Load BalancerURL path, all query params, and the Authorization header

For example, if your origin uses the Accept-Language header to return different content based on the client's language, you should include that header in the cache key.

resources:
myApiGateway:
type: http-api-gateway
properties:
cdn:
enabled: true
cachingOptions:
cacheKeyParameters:
headers:
whitelist:
- Accept-Language
CdnCacheKey  API reference
cookies
headers
queryString

CDN forwarding options

Forwarding options specify which parts of a request are forwarded to the origin. You can also filter which request methods are forwarded.

If you don't specify any forwarding options, Stacktape uses the following defaults:

Origin typeParts of request forwarded to origin
BucketURL path
HTTP API GatewayURL path, all query params, all headers, and all cookies
Application Load BalancerURL path, all query params, all headers, and all cookies
resources:
myHttpApi:
type: 'http-api-gateway'
properties:
cdn:
enabled: true
forwardingOptions:
allowedMethods:
- 'GET'
- 'POST'
CdnForwardingOptions  API reference
customRequestHeaders
allowedMethods
cookies
headers
queryString
originRequestPolicyId

Route rewrites

Route rewrites allow you to route incoming requests to different origins based on the URL path.

  • Each incoming request to the CDN is first evaluated against route rewrites. The requested path is compared with path pattern specified in route rewrite.
  • If the requested path matches the path pattern specified by route rewrite, the request is sent to the configured route.
  • Route rewrites are evaluated in order. The first match is where the request will be sent to.
  • If no match is found, request is sent to the default origin (the one that the CDN is attached to).

Example use cases:

  • Most of the content you are serving is a static content served from a bucket (static website). Some content however needs to be rendered dynamically by a lambda function. You can route paths that need to be rendered dynamically to the Lambda function.
  • You want to cache your jpg files longer than other files. You can create route rewrite that will catch every path ending with jpg and set custom caching options for these paths.
CdnRouteRewrite  API reference
path
Required
routePrefix
routeTo
cachingOptions
forwardingOptions
edgeFunctions

Routing to a bucket

In this example, requests with a URL path starting with /static are routed to a bucket, while all other requests are routed to an HTTP API Gateway.

CdnBucketRoute  API reference
type
Required
properties.bucketName
Required
properties.disableUrlNormalization
resources:
myHttpApi:
type: 'http-api-gateway'
properties:
cdn:
enabled: true
routeRewrites:
- path: /static/*
routeTo:
type: bucket
properties:
bucketName: myBucket
disableUrlNormalization: true
myBucket:
type: 'bucket'

A diagram showing CDN route rewrites

Routing to an Application Load Balancer

CdnLoadBalancerRoute  API reference
type
Required
properties.loadBalancerName
Required
properties.listenerPort
properties.originDomainName
resources:
myHttpApi:
type: 'http-api-gateway'
properties:
cdn:
enabled: true
routeRewrites:
- path: /app2/*
routeTo:
type: 'application-load-balancer'
properties:
loadBalancerName: myLoadBalancer
myLoadBalancer:
type: 'application-load-balancer'

Routing to an HTTP API Gateway

CdnHttpApiGatewayRoute  API reference
type
Required
properties.httpApiGatewayName
Required
resources:
myHttpApi:
type: 'http-api-gateway'
properties:
cdn:
enabled: true
routeRewrites:
- path: /app2/*
routeTo:
type: 'http-api-gateway'
properties:
httpApiGatewayName: appApiGateway
appApiGateway:
type: 'http-api-gateway'

Routing to a custom origin

CdnCustomDomainRoute  API reference
type
Required
properties.domainName
Required
properties.protocol
Default: HTTPS
properties.port
Default: 443
resources:
myLoadBalancer:
type: 'application-load-balancer'
properties:
cdn:
enabled: true
routeRewrites:
- path: /external/*
routeTo:
type: custom-origin
properties:
domainName: my-custom-origin.example.com

Automatic invalidation

You can disable the automatic cache invalidation that occurs after each deployment by setting invalidateAfterDeploy to false.

resources:
myApiGateway:
type: http-api-gateway
properties:
cdn:
enabled: true
invalidateAfterDeploy: false

Price class

You can set a price class to reduce the cost of your CDN by limiting the number of edge locations from which it serves traffic.

  • Higher price class results in more locations that serve your traffic.
  • This can result in better performance in some regions, but is more costly.
  • Example: If your users are located only in US & Europe, you can save money by configuring PriceClass_100
  • To learn more about price classes, refer to AWS docs
resources:
myApiGateway:
type: http-api-gateway
properties:
cdn:
enabled: true
cloudfrontPriceClass: PriceClass_200

Firewall

You can protect your CDN with a web application firewall.

  • You can use web-app-firewall to protect your resources from common web exploits that could affect application availability, compromise security, or consume excessive resources.
  • Web app firewall protects your application by filtering dangerous requests coming to your app. You can read more about the firewall in our docs.

To learn more, see the Web Application Firewall documentation.

resources:
myFirewall:
type: web-app-firewall
properties:
scope: cdn
myApiGateway:
type: http-api-gateway
properties:
cdn:
enabled: true
useFirewall: myFirewall

API reference

CacheKeyCookies  API reference
none
whitelist
allExcept
all
CacheKeyHeaders  API reference
none
whitelist
CacheKeyQueryString  API reference
all
none
whitelist
CdnCustomRequestHeader  API reference
headerName
Required
value
Required
ForwardCookies  API reference
none
whitelist
all
ForwardHeaders  API reference
none
whitelist
allViewer
allViewerAndWhitelistCloudFront
allExcept
ForwardQueryString  API reference
all
none
whitelist

Contents