rvn-cloudfront · Latest version: 0.3.1
Dependencies and consumers
Every dependency input can be specified manually to reference existing external infrastructure rather than a Ravion module.Readme
CloudFront distribution that serves web applications and private S3 buckets from ECS services, load balancers, S3 origins, and other custom origins.Overview
The CloudFront module puts the AWS CloudFront edge network in front of a dynamic web application or private S3 bucket. Point it at an existing ECS web service, an ECS cluster load balancer, an S3 bucket, or any custom domain, and Ravion provisions the distribution, origin configuration, cache behaviors, optional access logging bucket, and metrics. The default configuration is safe for dynamic apps: responses are cached at the edge only when your app returns Cache-Control headers, and the full viewer request, including the Host header, cookies, and query strings, is forwarded to the origin. You get TLS termination close to users, HTTP/2 and HTTP/3, connection reuse to the origin, optional WAF, and per-path caching for static assets. Terraform source: flightcontrolhq/modules/cdn/cloudfrontUse cases
How the ECS connection works
An ECS cluster load balancer routes requests to services using listener rules that match the request’s host and path. CloudFront preserves that behavior: the default origin request policy (AWS managed AllViewer) forwards the viewer’s Host header to the load balancer, so the same listener rules keep routing each request to the right service. That means the origin is really the load balancer, not an individual service:
Both ECS options resolve to the same ALB when the service runs on that cluster, so pick whichever is easier to select. One distribution can front all services behind the load balancer.
Domain aliases and host routing
If your services route by Domain host rules, the forwarded Host header must match those rules:- Add each domain to Domain aliases (for example app.example.com and api.example.com).
- Point the domains’ DNS at the CloudFront distribution domain.
- Keep the same domains in the ECS services’ Domain host rules.
TLS between CloudFront and the origin
Origin protocol policy defaults to HTTPS only. For that to work, the load balancer must have an HTTPS listener with a certificate that is valid for the forwarded Host domain, which is the same certificate the ALB already needs to serve those domains directly. Use HTTP only when the load balancer has no HTTPS listener; traffic from CloudFront to the origin is then unencrypted.Private S3 origins
S3 origins use CloudFront Origin Access Control so the bucket can stay private. Use the None origin request policy unless you intentionally need CORS headers, because forwarding the viewer Host header to S3 can break OAC-signed origin requests. The bucket policy must allow CloudFront to read objects, scoped to this distribution ARN. For rvn-s3 buckets, apply the CloudFront stack first, then edit the S3 bucket and add the CloudFront OAC read policy template with the CloudFront distribution ARN.Signed URLs
Enable Require signed URLs to set trusted key groups on the default cache behavior. Each custom cache behavior can also require signed URLs for only that path and must provide its own trusted key group IDs. Ravion does not create key groups in this module; provide existing CloudFront key group IDs and keep the private signing key in your application.Edge redirects
Redirect rules run at viewer request time before CloudFront checks its cache or contacts an origin. Rules are evaluated in order and the first match wins. Sources and destinations accept absolute HTTPS URLs or host-agnostic paths. Use:name to capture one path segment and a final :name* to capture the remaining path, then place those named values anywhere in the destination. Query preservation is optional and disabled by default.
The managed redirect function is attached to the default cache behavior and every custom cache behavior so redirects cover every request path. CloudFront allows only one viewer-request edge association per behavior, so redirect rules cannot be combined with a viewer-request CloudFront Function or Lambda@Edge association supplied through Advanced Terraform variables.
The module prevents a rule from redirecting back into its own source pattern. It cannot detect cycles spanning multiple independently matching rules, so review rule ordering and destinations when defining bidirectional or multi-domain redirects.
Avoid overlapping same-host rules
Before returning a redirect, the edge function checks whether the destination would match the same source pattern on the same host. If it would, the function skips that rule and evaluates the next rule. If no later rule matches, CloudFront sends the original request to the configured origin. This prevents an infinite loop, but it can make an overlapping rule appear inactive. For example, a source ofhttps://example.cloudfront.net/:path* and destination of https://example.cloudfront.net/docs/:path* does not redirect. The destination /docs/guide still matches the broad source and would otherwise become /docs/docs/guide on the next request.
Use different hosts for a domain migration, such as https://docs.example.com/:path* to https://www.example.com/docs/:path*. For same-host testing, use non-overlapping namespaces such as https://example.cloudfront.net/old/:path* to https://example.cloudfront.net/docs/:path*. To redirect only the root, use the exact source https://example.cloudfront.net without a path parameter.
Redirect patterns do not currently support exclusions such as “all paths except /docs”.
Certificates
Domain aliases require a certificate issued in us-east-1, because CloudFront is a global service. Select an ACM Certificate module instance in the ACM certificate field; its certificate ARN is mapped automatically. Request the certificate with the primary domain and any additional aliases as subject alternative names. This certificate is for viewers connecting to CloudFront. The load balancer keeps its own regional certificate for the origin leg.Caching
The default cache behavior applies to all requests that do not match a custom cache behavior path:
With the default cache policy, nothing is cached until the app opts in by returning Cache-Control headers such as public, max-age=300. Responses without caching headers always go to the origin. Choose CachingDisabled to turn off edge caching entirely, or CachingOptimized to cache aggressively regardless of origin headers. Pick Custom policy ID to use a cache or origin request policy you created in your own account.
Response headers policy is optional and adds headers such as the SecurityHeadersPolicy set or CORS headers to every response.
To cache static content, add Custom cache behaviors. A typical setup adds /assets/* or /static/* with the CachingOptimized policy and GET, HEAD methods. Each behavior can also target an additional origin for path-based traffic splitting. Per-behavior policies use the managed policy lists; for a custom per-path policy, override ordered_cache_behaviors in Advanced Terraform variables.
CloudFront accepts only three allowed-method combinations per behavior: GET,HEAD; GET,HEAD,OPTIONS; or all seven methods.
Distribution settings
Monitoring
The dashboard always shows the default CloudFront distribution metrics: requests, total error rate, 4xx error rate, 5xx error rate, bytes downloaded, and bytes uploaded. CloudFront publishes these default metrics to CloudWatch at no additional CloudWatch metric cost. You can also enable all additional metrics charts for cache hit rate, origin latency, and per-status error rates. AWS enables all 8 additional metrics together and CloudWatch charges a flat per-metric monthly rate, about 0.30 per metric rate. This cost does not change with request volume.Access logging
CloudFront access logging is on by default, delivered to CloudWatch Logs and viewable in Ravion. Choose where logs are delivered:
Logging retention days defaults to 90 and controls the CloudWatch log group retention or the S3 bucket lifecycle expiry, depending on the destination. CloudWatch retention must be one of the standard CloudWatch Logs retention values (1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, and larger).
Configuration
Design decisions
- The primary origin is always the load balancer or domain you select, with the fixed origin ID primary. ECS references exist to discover the load balancer DNS name, not to create per-service origins, because listener rules already fan traffic out behind one origin.
- Caching is disabled by default. A wrong edge cache on dynamic responses is worse than no cache, so caching is an explicit per-path opt-in.
- The AllViewer origin request policy is the default so Host-based listener rules, cookies, and query strings keep working unchanged behind CloudFront.
- Redirects use one managed CloudFront Function shared by the module’s distributions and attached to every cache behavior.
- One module instance manages one distribution. Create additional instances when domains need different edge configuration; they can share the same origin.
- The certificate is referenced from an ACM Certificate module instance so the us-east-1 requirement is explicit and reusable.
Learn more
- Amazon CloudFront developer guide
- Using managed cache and origin request policies
- Requirements for using alternate domain names
- Amazon CloudFront metrics
Inputs reference
All inputs forrvn-cloudfront version 0.3.1. Use the name shown for each field as the input key in module config.
AWS account & region
AWS account.
- Immutable after creation
Region. CloudFront is global. Access logs go to CloudWatch Logs in us-east-1 by default; this region is used for the optional S3 logging bucket.
- Default:
us-east-1 - Immutable after creation
Distribution
Name slug. Name prefix for the distribution comment, origin access control, and logging bucket.
- Default:
<<project.given_id>>-<<environment.given_id>>-<<module.given_id>> - Immutable after creation
- Pattern:
^[a-zA-Z][a-zA-Z0-9-]{0,62}$— 1-63 letters, numbers, or hyphens. Start with a letter.
Domain aliases. Custom domain names like app.example.com. Leave empty to use the default cloudfront.net domain. Aliases must match the domain host rules on the origin load balancer when it routes by host.
- Default:
[]
ACM certificate. Certificate for the domain aliases. Required when aliases are set. CloudFront requires the certificate to be issued in us-east-1.
Origin
Origin source. Choose an existing ECS module, private S3 bucket, or custom origin domain name.
- Default:
ecs_web_service - Allowed values:
ecs_web_service(ECS web service),ecs_cluster(ECS cluster),s3_bucket(S3 bucket),custom(Custom domain)
ECS web service. ECS web service whose load balancer becomes the origin. The service must be on rvn-ecs-web 0.8.0 or later so its stack exposes the load balancer DNS name.
- Shown when:
{"origin_source":"ecs_web_service"}
ECS cluster. ECS cluster whose public ALB becomes the origin. Listener rules on the ALB keep routing requests to the right services.
- Shown when:
{"origin_source":"ecs_cluster"}
Origin domain name. Domain name CloudFront connects to for the primary origin.
- Shown when:
{"origin_source":"custom"}
S3 bucket. Private S3 bucket to serve through CloudFront Origin Access Control. After this CloudFront stack applies, add its distribution ARN to the S3 bucket’s CloudFront OAC read policy template.
- Shown when:
{"origin_source":"s3_bucket"}
Origin protocol policy. How CloudFront connects to the origin. HTTPS only requires the origin load balancer to serve a certificate valid for the forwarded host.
- Default:
https-only - Allowed values:
https-only(HTTPS only),http-only(HTTP only),match-viewer(Match viewer) - Shown when:
{"origin_source":["ecs_web_service","ecs_cluster","custom"]}
Additional origins. Optional extra origins that custom cache behaviors can route paths to. Each origin needs a unique ID.
- Default:
[]
Edge redirects
Redirect rules. Optional URL-pattern redirects handled by a CloudFront Function at viewer request time.
- Default:
[]
Default cache behavior
Viewer protocol policy. How viewers connect to CloudFront.
- Default:
redirect-to-https - Allowed values:
redirect-to-https(Redirect to HTTPS),https-only(HTTPS only),allow-all(Allow all)
Allowed methods. HTTP methods CloudFront forwards to the origin. Use all methods for apps that accept form posts or API writes.
- Default:
all - Allowed values:
all(All methods),read_options(Read and OPTIONS),read(Read only)
Cache policy. Controls edge caching for the default behavior. The default respects your app’s Cache-Control headers, so nothing is cached unless the app asks for it.
- Default:
4cc15a8a-d715-48a4-82b8-cc0b614638fe - Allowed values:
4cc15a8a-d715-48a4-82b8-cc0b614638fe(UseOriginCacheControlHeaders-QueryStrings (recommended)),83da9c7e-98b4-4e11-a168-04f0df8e2c65(UseOriginCacheControlHeaders),4135ea2d-6df8-44a3-9df3-4b5a84be39ad(CachingDisabled),658327ea-f89d-4fab-a63d-7e88639e58f6(CachingOptimized),custom(Custom policy ID)
Custom cache policy ID. ID of a cache policy from your AWS account.
- Pattern:
^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$— Invalid CloudFront policy ID. Use the 36-character policy ID, not the name or ARN. - Shown when:
{"cache_policy":"custom"}
Origin request policy. Controls what CloudFront forwards to the origin. Use None for private S3 origins so CloudFront can sign OAC requests without forwarding the viewer Host header.
- Default:
216adef6-5c7f-47e4-b989-5492eafa07d3 - Allowed values:
none(None),216adef6-5c7f-47e4-b989-5492eafa07d3(AllViewer (recommended)),b689b0a8-53d0-40ab-baf2-68738e2966ac(AllViewerExceptHostHeader),33f36d7e-f396-46d9-90e0-52428a34d9dc(AllViewerAndCloudFrontHeaders-2022-06),59781a5b-3903-41f3-afcb-af62929ccde1(CORS-CustomOrigin),88a5eaf4-2fd4-4709-b370-b4c650ea3fcf(CORS-S3Origin),custom(Custom policy ID)
Custom origin request policy ID. ID of an origin request policy from your AWS account.
- Pattern:
^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$— Invalid CloudFront policy ID. Use the 36-character policy ID, not the name or ARN. - Shown when:
{"origin_request_policy":"custom"}
Custom cache behaviors. Optional path-based behaviors evaluated before the default behavior, such as caching /assets/* or routing /api/* to another origin.
- Default:
[]
Signed URLs
Require signed URLs. Require signed URLs or signed cookies for the default cache behavior. Unsigned requests receive 403 responses from CloudFront.
- Default:
false
Trusted key group IDs. Existing CloudFront key group IDs whose public keys are trusted for signed URLs or signed cookies. Add at least one key group before enabling Require signed URLs on the default behavior or any custom cache behavior.
- Default:
[] - Pattern:
^[A-Z0-9]+$— Invalid CloudFront key group ID. - Shown when:
{"signed_urls_enabled":true}
Response headers policy. Optional headers CloudFront adds to responses, such as security headers or CORS. Leave empty to add none.
- Allowed values:
67f7725c-6f97-4210-82d7-5512b31e9d03(SecurityHeadersPolicy),60669652-455b-4ae9-85a4-c4c02393f86c(SimpleCORS),5cc3b908-e619-4b99-88e5-2cf7f45965bd(CORS-With-Preflight),e61eb60c-9c35-4d20-a928-2b84e02af89c(CORS-and-SecurityHeadersPolicy),eaab4381-ed33-4a86-88ca-d9558dc6cd63(CORS-with-preflight-and-SecurityHeadersPolicy),custom(Custom policy ID)
Custom response headers policy ID. ID of a response headers policy from your AWS account.
- Pattern:
^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$— Invalid CloudFront policy ID. Use the 36-character policy ID, not the name or ARN. - Shown when:
{"response_headers_policy":"custom"}
Distribution settings
Price class. You can reduce edge locations for some cost savings if it becomes an issue.
- Default:
PriceClass_All - Allowed values:
PriceClass_All(All edge locations),PriceClass_200(Most edge locations),PriceClass_100(US, Canada, Europe)
HTTP version.
- Default:
http2and3 - Allowed values:
http2and3(HTTP/2 and HTTP/3),http2(HTTP/2),http1.1(HTTP/1.1)
WAF web ACL ARN. Optional WAFv2 web ACL to associate with the distribution. Must be a global (CloudFront) web ACL.
Geo restriction.
- Default:
none - Allowed values:
none(None),whitelist(Whitelist),blacklist(Blacklist)
Geo restriction country codes.
- Default:
[] - Shown when:
{"geo_restriction_type":["whitelist","blacklist"]}
Monitoring
Additional metrics. Enable
CacheHitRate, OriginLatency, and 401/403/404/502/503/504 error rate charts. Adds a flat CloudWatch cost of about $2.40/month per distribution.- Default:
false
Access logging
CloudFront access logging. Enable CloudFront access logging. Logs are delivered to CloudWatch Logs by default and can be viewed in Ravion.
- Default:
true
Logging destination. Where CloudFront delivers access logs.
- Default:
cloudwatch - Allowed values:
cloudwatch(CloudWatch Logs),s3(S3 bucket) - Shown when:
{"logging_enabled":true}
Logging retention days. Days to retain CloudFront access logs in CloudWatch Logs or the automatically created S3 logging bucket.
- Default:
90 - Min:
1 - Shown when:
{"logging_enabled":true}
Misc
Tags. A map of tags to assign to all resources. Default tags are
Owner, ProjectGivenId, EnvironmentGivenId, ModuleGivenId, ModuleIdTerraform settings
OpenTofu version override. Override the environment’s default version for this module
Ravion Terraform workspace name. Override Terraform state backend workspace name. Defaults to project + environment + module given ids.
- Immutable after creation
Advanced Terraform variables. Optional raw Terraform variable overrides for advanced module inputs or one-off overrides. Values here override the generated variables above.
- Default:
{}
Terraform execution environment. Override the execution environment for Terraform runners. Must use the same AWS account as selected above.