Skip to content

Commit 4e1b4ed

Browse files
feat: lamda at edge function for prereder
1 parent ff9ee53 commit 4e1b4ed

64 files changed

Lines changed: 6639 additions & 3616 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Release Lambda@Edge Functions
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "lib/lambda-at-edge/**"
8+
- ".github/workflows/release-lambda-at-edge.yml"
9+
10+
concurrency:
11+
group: release-lambda-at-edge
12+
cancel-in-progress: false
13+
14+
permissions:
15+
contents: write
16+
packages: write
17+
issues: write
18+
pull-requests: write
19+
20+
jobs:
21+
release:
22+
name: semantic-release (${{ matrix.package }})
23+
runs-on: ubuntu-latest
24+
strategy:
25+
fail-fast: false
26+
max-parallel: 1
27+
matrix:
28+
package:
29+
- filter-function
30+
- prerender-proxy
31+
- geo-redirect
32+
- response-handler
33+
steps:
34+
- name: Checkout
35+
uses: actions/checkout@v4
36+
with:
37+
fetch-depth: 0
38+
persist-credentials: false
39+
40+
- name: Setup Node.js
41+
uses: actions/setup-node@v4
42+
with:
43+
node-version-file: lib/lambda-at-edge/.nvmrc
44+
registry-url: https://npm.pkg.github.com
45+
scope: "@krishanthisera"
46+
47+
- name: Install dependencies
48+
run: yarn install --frozen-lockfile
49+
working-directory: lib/lambda-at-edge
50+
51+
- name: Build
52+
run: yarn build
53+
working-directory: lib/lambda-at-edge
54+
55+
- name: Release
56+
run: npx --no-install semantic-release
57+
working-directory: lib/lambda-at-edge/packages/${{ matrix.package }}
58+
env:
59+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60+
NPM_TOKEN: ${{ secrets.GITHUB_TOKEN }}
61+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,21 @@ override.tf.json
3131

3232
# Ignore CLI configuration files
3333
.terraformrc
34-
terraform.rc
34+
terraform.rc
35+
36+
# ---- Node / JS ----
37+
# The edge-function workspaces under lib/ are authoritative in lib/.gitignore;
38+
# these are repo-wide safety nets.
39+
**/node_modules/
40+
**/.turbo/
41+
**/build/
42+
**/dist/
43+
**/coverage/
44+
**/*.tsbuildinfo
45+
**/*.tgz
46+
**/.eslintcache
47+
48+
# ---- OS / editor ----
49+
**/.DS_Store
50+
Thumbs.db
51+
*.swp

Makefile

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
.DEFAULT_GOAL := help
2+
3+
# Edge-function workspaces (TypeScript source; built + published to GitHub Packages by CI)
4+
LAMBDA_DIR := lib/lambda-at-edge
5+
CF_DIR := lib/cloudfront-functions
6+
7+
##@ General
8+
9+
.PHONY: help
10+
help: ## Display this help
11+
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-25s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
12+
13+
##@ Dependencies
14+
15+
.PHONY: install
16+
install: ## Install all dependencies (Lambda@Edge + CloudFront Functions)
17+
@echo "Installing Lambda@Edge dependencies..."
18+
cd $(LAMBDA_DIR) && yarn install
19+
@echo "Installing CloudFront Functions dependencies..."
20+
cd $(CF_DIR) && yarn install
21+
@echo "✓ Dependencies installation complete"
22+
23+
##@ Tests
24+
25+
.PHONY: test
26+
test: ## Run all tests (Lambda@Edge + CloudFront Functions)
27+
@echo "Running Lambda@Edge tests..."
28+
cd $(LAMBDA_DIR) && yarn test
29+
@echo "Running CloudFront Function tests..."
30+
cd $(CF_DIR) && yarn test
31+
@echo "✓ Tests complete"
32+
33+
.PHONY: test-lambda
34+
test-lambda: ## Run all Lambda@Edge tests
35+
cd $(LAMBDA_DIR) && yarn test
36+
37+
.PHONY: test-cloudfront
38+
test-cloudfront: ## Run all CloudFront Function tests
39+
cd $(CF_DIR) && yarn test
40+
41+
.PHONY: test-filter-function
42+
test-filter-function: ## Run tests for filter-function (Lambda@Edge)
43+
cd $(LAMBDA_DIR) && yarn workspace @krishanthisera/filter-function test
44+
45+
.PHONY: test-geo-redirect
46+
test-geo-redirect: ## Run tests for geo-redirect (Lambda@Edge)
47+
cd $(LAMBDA_DIR) && yarn workspace @krishanthisera/geo-redirect test
48+
49+
.PHONY: test-prerender-proxy
50+
test-prerender-proxy: ## Run tests for prerender-proxy (Lambda@Edge)
51+
cd $(LAMBDA_DIR) && yarn workspace @krishanthisera/prerender-proxy test
52+
53+
.PHONY: test-response-handler
54+
test-response-handler: ## Run tests for response-handler (Lambda@Edge)
55+
cd $(LAMBDA_DIR) && yarn workspace @krishanthisera/response-handler test
56+
57+
.PHONY: test-uri-rewrite
58+
test-uri-rewrite: ## Run tests for uri-rewrite (CloudFront Function)
59+
cd $(CF_DIR) && yarn workspace @krishanthisera/uri-rewrite test
60+
61+
##@ Build
62+
63+
.PHONY: build
64+
build: ## Build all functions (Lambda@Edge + CloudFront Functions)
65+
@echo "Building Lambda@Edge functions..."
66+
cd $(LAMBDA_DIR) && yarn build
67+
@echo "Building CloudFront Functions..."
68+
cd $(CF_DIR) && yarn build
69+
@echo "✓ Build complete"
70+
71+
.PHONY: build-lambda
72+
build-lambda: ## Build all Lambda@Edge functions
73+
cd $(LAMBDA_DIR) && yarn build
74+
75+
.PHONY: build-cloudfront
76+
build-cloudfront: ## Build all CloudFront Functions
77+
cd $(CF_DIR) && yarn build
78+
79+
.PHONY: build-filter-function
80+
build-filter-function: ## Build filter-function (Lambda@Edge)
81+
cd $(LAMBDA_DIR) && yarn workspace @krishanthisera/filter-function build
82+
83+
.PHONY: build-geo-redirect
84+
build-geo-redirect: ## Build geo-redirect (Lambda@Edge)
85+
cd $(LAMBDA_DIR) && yarn workspace @krishanthisera/geo-redirect build
86+
87+
.PHONY: build-prerender-proxy
88+
build-prerender-proxy: ## Build prerender-proxy (Lambda@Edge)
89+
cd $(LAMBDA_DIR) && yarn workspace @krishanthisera/prerender-proxy build
90+
91+
.PHONY: build-response-handler
92+
build-response-handler: ## Build response-handler (Lambda@Edge)
93+
cd $(LAMBDA_DIR) && yarn workspace @krishanthisera/response-handler build
94+
95+
.PHONY: build-uri-rewrite
96+
build-uri-rewrite: ## Build uri-rewrite (CloudFront Function)
97+
cd $(CF_DIR) && yarn workspace @krishanthisera/uri-rewrite build
98+
99+
##@ Lint
100+
101+
.PHONY: lint
102+
lint: ## Run linters (Lambda@Edge)
103+
cd $(LAMBDA_DIR) && yarn lint:check
104+
105+
.PHONY: lint-fix
106+
lint-fix: ## Run linters and fix issues (Lambda@Edge)
107+
cd $(LAMBDA_DIR) && yarn lint:fix
108+
109+
##@ Format
110+
111+
.PHONY: format
112+
format: ## Check code formatting (Lambda@Edge)
113+
cd $(LAMBDA_DIR) && yarn format:check
114+
115+
.PHONY: format-fix
116+
format-fix: ## Fix code formatting (Lambda@Edge)
117+
cd $(LAMBDA_DIR) && yarn format:fix
118+
119+
##@ Release
120+
121+
# Function code is published to the GitHub Packages npm registry (@krishanthisera/*)
122+
# by the release-* GitHub Actions workflows on push to main, driven by
123+
# Conventional Commits. These targets only preview what would be released.
124+
125+
.PHONY: release-dry-run-lambda
126+
release-dry-run-lambda: ## Dry-run semantic-release for every Lambda@Edge package (needs GITHUB_TOKEN)
127+
@for pkg in filter-function prerender-proxy geo-redirect response-handler; do \
128+
echo "== $$pkg =="; \
129+
cd $(LAMBDA_DIR)/packages/$$pkg && npx --no-install semantic-release --dry-run --no-ci; cd - >/dev/null; \
130+
done
131+
132+
.PHONY: release-dry-run-cloudfront
133+
release-dry-run-cloudfront: ## Dry-run semantic-release for uri-rewrite (needs GITHUB_TOKEN)
134+
cd $(CF_DIR)/packages/uri-rewrite && npx --no-install semantic-release --dry-run --no-ci
135+
136+
##@ Terraform
137+
138+
.PHONY: tf-init
139+
tf-init: ## Initialize Terraform
140+
terraform init
141+
142+
.PHONY: tf-plan
143+
tf-plan: ## Run Terraform plan
144+
terraform plan
145+
146+
.PHONY: tf-apply
147+
tf-apply: ## Apply Terraform changes
148+
terraform apply
149+
150+
.PHONY: tf-docs
151+
tf-docs: ## Regenerate Terraform documentation (requires terraform-docs)
152+
terraform-docs markdown table --output-file README.md --output-mode inject .
153+
terraform-docs markdown table --output-file modules/edge-functions/README.md --output-mode inject modules/edge-functions
154+
155+
##@ Development
156+
157+
.PHONY: dev
158+
dev: install build test ## Full development setup (install, build, test)
159+
@echo "✓ Development environment ready"
160+
161+
.PHONY: watch-lambda
162+
watch-lambda: ## Watch Lambda@Edge tests
163+
cd $(LAMBDA_DIR) && yarn test --watch
164+
165+
.PHONY: watch-cloudfront
166+
watch-cloudfront: ## Watch CloudFront Function tests
167+
cd $(CF_DIR) && yarn workspace @krishanthisera/uri-rewrite test:watch
168+
169+
##@ Deployment
170+
171+
.PHONY: pre-deploy
172+
pre-deploy: build test ## Build and test before deployment
173+
@echo "✓ Pre-deployment checks passed"
174+
175+
.PHONY: deploy
176+
deploy: pre-deploy tf-apply ## Full deployment (build, test, apply)
177+
@echo "✓ Deployment complete"
178+
179+
##@ Clean
180+
181+
.PHONY: clean
182+
clean: ## Clean build artifacts
183+
@echo "Cleaning Lambda@Edge build artifacts..."
184+
cd $(LAMBDA_DIR) && rm -rf packages/*/build function_archives .turbo packages/*/.turbo
185+
@echo "Cleaning CloudFront Functions build artifacts..."
186+
cd $(CF_DIR) && rm -rf packages/*/build .turbo packages/*/.turbo
187+
@echo "✓ Build artifacts cleaned"
188+
189+
.PHONY: clean-all
190+
clean-all: clean ## Clean everything including node_modules
191+
@echo "Removing node_modules..."
192+
rm -rf $(LAMBDA_DIR)/node_modules $(LAMBDA_DIR)/packages/*/node_modules
193+
rm -rf $(CF_DIR)/node_modules $(CF_DIR)/packages/*/node_modules
194+
@echo "✓ Everything cleaned"

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Browser → CloudFront (CDN + Lambda@Edge) → S3 (private bucket)
2222
| **CloudFront Distribution** | CDN with IPv6, forced HTTPS, 1-year cache TTL, and Lambda@Edge associations |
2323
| **ACM Certificate** | SSL/TLS certificate provisioned in `us-east-1` (required by CloudFront) |
2424
| **Route 53 Records** | Optional DNS validation records for the ACM certificate (see [SSL Certificate Validation](#ssl-certificate-validation)) |
25-
| **Lambda@Edge Module** | Local Terraform module (`modules/lambda-at-edge/`) deploying edge functions for viewer filtering, prerender proxy, geo-redirect, and response handling |
25+
| **Lambda@Edge Module** | Local Terraform module (`modules/edge-functions/`) deploying edge functions for viewer filtering, prerender proxy, geo-redirect, and response handling. Function code is published to GitHub Packages (`@krishanthisera/*`) from `lib/lambda-at-edge/` and `lib/cloudfront-functions/` |
2626
| **IAM User & Group** | Deployer user (`<domain>_deployer`) with scoped S3 PUT and CloudFront invalidation permissions for CI/CD |
2727

2828
## Prerequisites
@@ -63,7 +63,7 @@ By default, three Lambda@Edge functions are associated with the CloudFront distr
6363
| `origin-request` | `prerender-proxy` | Proxies bot/crawler traffic to a prerender service for server-side rendering |
6464
| `origin-response` | `response-handler` | Applies cache-control headers to origin responses |
6565

66-
These functions are managed by a local Terraform module located in `modules/lambda-at-edge/`. The TypeScript source code for each function is in `modules/lambda-at-edge/edge-functions/packages/`.
66+
These functions are managed by a local Terraform module located in `modules/edge-functions/`. The TypeScript source lives in `lib/lambda-at-edge/packages/` (Lambda@Edge) and `lib/cloudfront-functions/packages/` (CloudFront Functions); each package is built and published to the GitHub Packages npm registry as `@krishanthisera/<name>` by CI, and Terraform consumes a pinned version. Per-deployment config reaches the Lambda@Edge functions through CloudFront origin custom headers (`x-edge-cfg-*`) — see `lib/lambda-at-edge/README.md`.
6767

6868
### Additional Functions
6969

lib/.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ dist/
1313
# TypeScript
1414
*.tsbuildinfo
1515

16-
# Tests
16+
# Lint / test caches and reports
17+
.eslintcache
1718
coverage/
1819

20+
# Package tarballs (npm pack / semantic-release dry runs)
21+
*.tgz
22+
1923
# Lambda@Edge local packaging artifacts
2024
function_archives/
2125

lib/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Edge Libraries
2+
3+
Edge code for the CloudFront distribution. Two libraries, one per CloudFront
4+
compute type. Both are TypeScript yarn-workspace monorepos, bundled with esbuild,
5+
tested with Vitest, and **published to the GitHub Packages npm registry**
6+
(`@krishanthisera/*`) by CI. Terraform consumes a pinned published version of each
7+
function — it does not build anything.
8+
9+
| Library | CloudFront compute | Runs at | Use for |
10+
| ------- | ------------------ | ------- | ------- |
11+
| [`cloudfront-functions/`](cloudfront-functions/README.md) | CloudFront Functions | `viewer-request` / `viewer-response` | Lightweight, sub-millisecond URI/header rewrites (JS runtime, no network, no `require`) |
12+
| [`lambda-at-edge/`](lambda-at-edge/README.md) | Lambda@Edge | `viewer-*` / `origin-*` | Heavier logic — origin swaps, prerender proxying, geo redirects, response shaping (full Node.js runtime) |
13+
14+
## Functions
15+
16+
**`cloudfront-functions/`**
17+
18+
- `uri-rewrite` — rewrites request URIs (e.g. directory paths to `index.html`).
19+
20+
**`lambda-at-edge/`**
21+
22+
- `filter-function` (`viewer-request`) — flags bot/crawler traffic.
23+
- `prerender-proxy` (`origin-request`) — swaps the origin to a prerender service for flagged traffic.
24+
- `geo-redirect` (`origin-request`) — redirects viewers to a locale path by country.
25+
- `response-handler` (`origin-response`) — sets `Cache-Control` on prerender responses and injects a custom error page.
26+
27+
See each library's `README.md` for structure, build/test commands, and runtime
28+
configuration.
File renamed without changes.
File renamed without changes.

lib/lambda-at-edge/.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@krishanthisera:registry=https://npm.pkg.github.com

lib/lambda-at-edge/.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
26.5

0 commit comments

Comments
 (0)