Skip to content

Commit a3181c6

Browse files
authored
feat: Add support for path-based redirects via ordered cache behaviors. (#49)
1 parent 335aaa9 commit a3181c6

4 files changed

Lines changed: 79 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog][changelog], and this project adheres
66
to [Semantic Versioning][semver].
77

8+
## 2.4.0 (2026-07-01)
9+
10+
### Feat
11+
12+
- Support path-based redirects via ordered cache behaviors.
13+
814
## 2.3.0 (2026-07-01)
915

1016
### Feat

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ webhooks_priority = 100
167167
| [ip_set_rules] | Custom IP Set rules for the WAF | `map(object)` | `{}` | no |
168168
| redacted_headers | Headers to redact from logs. Keys are the header names, and values are the action to take. Valid actions are `"HASH"` and `"SUBSTITUTION"`. | `map(string)` | `{sane defaults}` | no |
169169
| [rate_limit_rules] | Rate limiting configuration for the WAF. | `map(object)` | `{}` | no |
170+
| [redirect_paths] | Ordered cache behaviors for path-based redirects. Each entry attaches a CloudFront function that performs the redirect for requests matching the given path pattern. | `list(object)` | `[]` | no |
170171
| origin_domain | Optional custom origin domain to point to. Defaults to `origin.subdomain.domain`. Only used if `use_custom_origin` is set to `true`. | `string` | n/a | no |
171172
| passive | Enable passive mode for the WAF, counting all requests rather than blocking. | `bool` | `false` | no |
172173
| request_policy | Managed request policy to associate with the distribution. See the [managed policies][managed-policies] for valid values. | `string` | `"AllViewer"` | no |
@@ -293,6 +294,41 @@ module "cloudfront_waf" {
293294
| priority | Rule priority. Defaults to the rule's position in the map + the number of IP set rules. | `number` | `null` | no |
294295
| window | Number of seconds to limit requests in. Options are: 60, 120, 300, 600 | `number` | `60` | no |
295296

297+
### redirect_paths
298+
299+
To redirect traffic from a specific path to another URL, you can specify a list
300+
of path-based redirect behaviors. Each entry creates an [ordered cache
301+
behavior][ordered-behaviors] that fires a CloudFront function before the request
302+
reaches the origin.
303+
304+
> [!TIP]
305+
> Use the [`tofu-modules-aws-cloudfront-redirect`][cloudfront-redirect] module
306+
> with `create_distribution = false` to create the CloudFront function, then
307+
> pass the `function_arn` output here.
308+
309+
```hcl
310+
module "cloudfront_waf" {
311+
source = "github.com/codeforamerica/tofu-modules-aws-cloudfront-waf?ref=2.3.0"
312+
313+
project = "my-project"
314+
environment = "staging"
315+
domain = "my-project.org"
316+
log_bucket = module.logging.bucket
317+
318+
redirect_paths = [
319+
{
320+
path_pattern = "/old-path*"
321+
function_arn = module.redirect.function_arn
322+
}
323+
]
324+
}
325+
```
326+
327+
| Name | Description | Type | Default | Required |
328+
| ------------ | ------------------------------------------------------------------------------ | -------- | ------- | -------- |
329+
| path_pattern | CloudFront path pattern to match (e.g. `/old-path*`). | `string` | n/a | yes |
330+
| function_arn | ARN of the CloudFront function to fire on `viewer-request` for matching paths. | `string` | n/a | yes |
331+
296332
### upload_paths
297333

298334
The [AWSManagedRulesCommonRuleSet][rules-common] rule group, by default, will
@@ -433,7 +469,10 @@ will be allowed through.
433469
[ip_set_rules]: #ip_set_rules
434470
[latest-release]: https://github.com/codeforamerica/tofu-modules-aws-cloudfront-waf/releases/latest
435471
[managed-policies]: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html
472+
[cloudfront-redirect]: https://github.com/codeforamerica/tofu-modules-aws-cloudfront-redirect
473+
[ordered-behaviors]: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesPathPattern
436474
[rate_limit_rules]: #rate_limit_rules
475+
[redirect_paths]: #redirect_paths
437476
[route53]: https://aws.amazon.com/route53/
438477
[rules-common]: https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-baseline.html#aws-managed-rule-groups-baseline-crs
439478
[rules-inputs]: https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-baseline.html#aws-managed-rule-groups-baseline-known-bad-inputs

main.tf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,27 @@ resource "aws_cloudfront_distribution" "waf" {
6767
viewer_protocol_policy = "redirect-to-https"
6868
}
6969

70+
dynamic "ordered_cache_behavior" {
71+
for_each = var.redirect_paths
72+
73+
content {
74+
path_pattern = ordered_cache_behavior.value.path_pattern
75+
allowed_methods = ["GET", "HEAD"]
76+
cached_methods = ["GET", "HEAD"]
77+
target_origin_id = local.origin_domain
78+
viewer_protocol_policy = "redirect-to-https"
79+
min_ttl = 0
80+
default_ttl = 0
81+
max_ttl = 0
82+
cache_policy_id = data.aws_cloudfront_cache_policy.policy.id
83+
84+
function_association {
85+
event_type = "viewer-request"
86+
function_arn = ordered_cache_behavior.value.function_arn
87+
}
88+
}
89+
}
90+
7091
restrictions {
7192
geo_restriction {
7293
restriction_type = "none"

variables.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,19 @@ variable "use_custom_origin" {
223223
default = false
224224
}
225225

226+
variable "redirect_paths" {
227+
type = list(object({
228+
path_pattern = string
229+
function_arn = string
230+
}))
231+
description = <<-EOT
232+
Ordered cache behaviors for path-based redirects. Each entry attaches a
233+
CloudFront function that performs the redirect for requests matching the
234+
given path pattern.
235+
EOT
236+
default = []
237+
}
238+
226239
variable "webhooks" {
227240
type = map(object({
228241
paths = list(object({

0 commit comments

Comments
 (0)