Skip to content

aws-cf-reverse-proxy: add per-behavior gRPC support via grpc_routes#64

Merged
sam-at-luther merged 1 commit into
mainfrom
sam/issue-63-cf-grpc-routes
May 7, 2026
Merged

aws-cf-reverse-proxy: add per-behavior gRPC support via grpc_routes#64
sam-at-luther merged 1 commit into
mainfrom
sam/issue-63-cf-grpc-routes

Conversation

@sam-at-luther

Copy link
Copy Markdown
Member

Closes #63
Companion follow-up: luthersystems/ui-infrastructure#241

Summary

Adds opt-in gRPC support to aws-cf-reverse-proxy so consumers can register CloudFront cache behaviors that speak gRPC to an EKS ALB origin. Existing distributions with no grpc_routes set produce a zero-diff plan.

Changes

  • vars.tf: new grpc_routes = map(string) (default {}).
  • main.tf:
    • New local.grpc_origin_configs derives an origin per gRPC route with a distinct origin-grpc-... id. A combined local.all_origin_configs feeds the dynamic "origin" block; when grpc_routes = {} it is identical to local.origin_configs, preserving the exact origin set.
    • http_version flips to http2and3 only when length(grpc_routes) > 0, otherwise stays http2.
    • New dynamic "ordered_cache_behavior" iterates grpc_origin_configs and emits grpc_config { enabled = true } plus the full method set CloudFront requires for gRPC behaviors. Reuses the existing cache and response-headers policies.

Design notes

  • gRPC origins use origin-grpc-<sanitized-path> ids so they never collide with HTTP origins, even when the underlying origin URL is the same ALB. No de-duplication: CloudFront accepts multiple origins pointing at the same domain under distinct ids, and this keeps the locals graph dead simple. If a future consumer wants a shared origin between HTTP and gRPC behaviors, that's an additive change.
  • compress is intentionally omitted on gRPC behaviors (provider default false); gRPC handles compression at the protocol layer.
  • The new internal map key prefix __grpc__<path> exists only for for_each iteration; it never appears in any rendered AWS resource (the dynamic block emits origin.value.origin_id, not the key).

Verification

  • terraform fmt -recursive aws-cf-reverse-proxy/ clean.
  • terraform validate against aws-cf-reverse-proxy/tests/test1/ (AWS provider 6.44.0): clean both with the default test (grpc_routes unset) and with a sample entry {"/a2a.v1.A2AService/*" = "https://eks-alb.example.com"}.
  • Back-compat for grpc_routes = {} is structurally guaranteed:
    • local.grpc_origin_configs = {}
    • local.all_origin_configs = merge(origin_configs, {}) == origin_configs
    • new dynamic "ordered_cache_behavior" iterates over {} -> zero blocks
    • http_version = length({}) > 0 ? "http2and3" : "http2" -> "http2"
  • With one grpc_routes entry, plan would show: 1 added origin (origin-grpc-...), 1 added ordered_cache_behavior with grpc_config { enabled = true }, and http_version flipping http2 -> http2and3. No other in-place changes.

Follow-up

  • Tag a new release after merge so ui-infrastructure can bump ?ref= and add a grpc_routes entry. The issue suggests v56.0.0; current latest tag is v55.15.2. Not cutting the tag here — leaving that to a maintainer.
  • The ui-infrastructure consumer side is tracked in luthersystems/ui-infrastructure#241; chart side in insideoutmcp chart: add gRPC port + service.annotations passthrough mars#131.

Adds opt-in gRPC support so consumers can register CloudFront cache
behaviors that speak gRPC to an EKS ALB origin. Existing distributions
with no grpc_routes set produce a zero-diff plan.

- vars.tf: new grpc_routes = map(string) (default {}).
- main.tf:
  - New local.grpc_origin_configs derives an origin per gRPC route with
    a distinct origin-grpc-... id. A combined all_origin_configs feeds
    the dynamic "origin" block; when grpc_routes = {} it equals
    local.origin_configs, preserving the exact origin set.
  - http_version flips to http2and3 only when length(grpc_routes) > 0,
    otherwise stays http2.
  - New dynamic "ordered_cache_behavior" iterates grpc_origin_configs
    and emits grpc_config { enabled = true } plus the full method set
    CloudFront requires for gRPC behaviors. Reuses the existing cache
    policy.

Closes #63
@sam-at-luther sam-at-luther merged commit f2f8117 into main May 7, 2026
23 checks passed
sam-at-luther added a commit that referenced this pull request May 7, 2026
…d_cache_behavior shuffle diffs (#67)

CloudFront's ordered_cache_behavior and origin blocks are TypeList in the
provider schema; terraform iterates the for_each map in sorted-key order
and the resulting list is diffed by index. When local.origin_configs was
keyed by raw path, inserting a new path that sorted earlier than an
existing key (e.g. "/.well-known/agent-card.json" sorts before
"/.well-known/agent.json" because "-" < ".") shifted every later entry
down by one index and produced cosmetic ~ diffs across every behavior.

Switch local.origin_configs and local.grpc_origin_configs to be keyed by
"<sha256(path)[:8]>-<path>" — a stable hash-prefix that spreads entries
over the keyspace so insertions don't predictably shift siblings. The
path is appended after the hash purely so generated keys remain
human-readable in plan output. path_pattern is now carried in the value
so the dynamic blocks can stop reading it from .key.

Public API is unchanged: var.origin_routes and var.grpc_routes keep
their existing schemas. The output "origin_configs" is re-keyed by
path_pattern so its observable shape stays the same for downstream
consumers — only internal iteration order changes.

The "__grpc__" prefix from #64 was no longer needed because gRPC keys
now carry an unambiguous "grpc-" hash-prefixed namespace; the merge into
all_origin_configs simplifies to a plain merge().

First apply after consumers bump to this version produces a one-time
index shuffle as existing keys migrate from raw-path to hash-prefixed
layout. End-state is byte-identical, but reviewers will see what looks
like a major rewrite of every existing cache behavior in their first
plan. Subsequent additions produce clean single-add diffs.

Refs luthersystems/ui-infrastructure#240
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

aws-cf-reverse-proxy: add per-behavior gRPC support

1 participant