infra: enable ALB target group stickiness on prod-deploy (fixes #268, companion to #514)#516
Open
ejanalysis wants to merge 1 commit into
Open
infra: enable ALB target group stickiness on prod-deploy (fixes #268, companion to #514)#516ejanalysis wants to merge 1 commit into
ejanalysis wants to merge 1 commit into
Conversation
Mirrors the same one-block change on dev-deploy (PR #514) so the two deploy branches do not drift. terraform apply reads main.tf from whatever checkout it runs in, so prod-deploy needs this too -- otherwise applying prod from a prod-deploy checkout would silently undo the fix. Shiny keeps session state in one R process, and a file upload is a separate HTTP POST from the page load. With desired_count=2 in prod and no stickiness, the load balancer round-robins that POST to the other container, which 404s with <h1>Not Found</h1> -- the red bar users see on upload. Reproduced 2026-07-25: prod 6/12 uploads failed (50%, perfectly alternating), dev (1 container) 0/12.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #268 — file uploads intermittently fail in production with a red
<h1>Not Found</h1>bar.Companion to #514. That PR makes the identical change on
dev-deploy; this one makes it onprod-deployso the two branches do not drift.Why this second PR is needed
ejam-infra/exists on both deploy branches, and the twomain.tffiles were byte-identical before these PRs.terraform applyreadsmain.tffrom whatever checkout it is run in. If prod were applied from aprod-deploycheckout carrying the old file, the fix would not take effect — and the apply could silently undo the console toggle right after it was set. Landing the change on both branches removes that trap.What this changes
Adds a
stickinessblock toaws_lb_target_group "app"inejam-infra/main.tf. One block, no other changes.Why
Shiny keeps session state in the memory of one R process. A file upload arrives as a separate HTTP POST from the page load. Production runs
desired_count = 2, and target-group stickiness is currently off, so the load balancer round-robins that POST to the other container — which has never heard of the session and answers404 <h1>Not Found</h1>. The app's upload bar renders that body unescaped, which is why users see raw HTML tags in the red bar.Reproduced 2026-07-25
Drove the real browser flow programmatically (open Shiny session over websocket →
uploadInit→ POST the realinst/testdata/latlon/testpoints_10.xlsxbytes to the returneduploadUrl). Pershiny:::ShinySession$handleRequest, only a POST with a livejobIdcan return200 OK, so a 200 proves the request reached the session's own container.ejam.publicenvirodata.org)Perfect alternation is round-robin across exactly two targets. Confirmed independently: prod returns no
Set-Cookie: AWSALB, and prod is served directly by the ALB (no Cloudflare in front), so that is a true negative.Why it came back
This was fixed in Feb 2026 by hand in the AWS console and closed as "fixed not in this repo but in the configuration of the deployment." It was never codified in Terraform, so it only ever existed as out-of-band console state, and it did not survive.
How to apply this (for @Gabe-Epic)
Merging this PR does not change anything in AWS. No workflow runs Terraform — it is entirely manual. Two steps:
1. Immediate unbreak (~1 minute, no Terraform needed)
AWS Console → EC2 → Target Groups →
ejam-prod-tg→ Attributes → Edit → turn Stickiness on.Type: load balancer generated cookie. Duration: 1 day.
This fixes production right away for users.
2. Make it permanent
Run locally from the
ejam-infra/directory of a checkout of this branch. Requiresterraform+awscliand the customejam-terraform-deployIAM policy on your user.State lives in S3 bucket
ejam-terraform-state-<ACCOUNT_ID>, with a separate state key per environment — so prod and dev are applied independently.Production (this is the one that fixes the bug — prod runs 2 containers):
Dev (optional — dev runs 1 container so stickiness is a no-op there, but applying keeps the two environments consistent):
Please check the plan output
terraform planshould show exactly one in-place update toaws_lb_target_group.app(~ update in-place), adding thestickinessblock. It is an attribute change, so there is no downtime.Order matters
Do step 1 and step 2. Step 1 alone is exactly what happened in Feb 2026 — the console setting was never codified, and it was silently lost. Step 2 alone leaves production broken until someone applies.
Verifying it worked
curl -sS -D - -o /dev/null https://ejam.publicenvirodata.org/ | grep -i set-cookieOnce stickiness is on, that prints an
AWSALBcookie. Right now it prints nothing.