Skip to content

feat(eks-ingress-migration): cover the LBC Ingress → Gateway API toolkit (lbc-migrate) - #154

Open
kritktongrakroj wants to merge 2 commits into
aws-samples:mainfrom
kritktongrakroj:feat/lbc-migrate-gateway-toolkit
Open

feat(eks-ingress-migration): cover the LBC Ingress → Gateway API toolkit (lbc-migrate)#154
kritktongrakroj wants to merge 2 commits into
aws-samples:mainfrom
kritktongrakroj:feat/lbc-migrate-gateway-toolkit

Conversation

@kritktongrakroj

Copy link
Copy Markdown
Collaborator

Adds coverage of the official AWS Load Balancer Controller Ingress → Gateway API migration toolkit (lbc-migrate CLI + Migration Console, shipped with LBC v3.4.0) as the automation
sub-path for Option 1 (Gateway API). The skill previously described only manual HTTPRoute authoring and had zero mention of the toolkit. Additive only — no scoring-model changes.

  • New references/lbc-migrate-toolkit.md: overview, version gate (LBC v3.4.0 / Gateway API standard CRDs v1.5.0 — higher than the manual path's ≥v2.14 / CRD v1.3.0 baseline), install
    (build from source), three input modes, output CRDs, the 6-step guided flow (translate → dry-run via gateway.k8s.aws/dry-run + the IngressPlanAnnotation feature gate → apply new ALBs
    alongside → verify → shift via Route 53 weighted or Global Accelerator → cleanup), dual-ALB cost + direct-ALB-DNS caveats, and skip-and-warn limitations (capture-group url-rewrite, WAF
    Classic → WAFv2 first, frontend-nlb-*, group.order, external TGs, defaultBackend). Every claim cites the launch blog + LBC docs.
  • Option 1 automation sub-path in report-generation.md and migration-plan.md, with manual authoring kept as the fallback.
  • Complete-path cross-links: NGINX Ingress (alb-migration.md) → LBC ALB Ingress → Gateway API (lbc-migrate-toolkit.md); gateway-api.md points to the toolkit and notes the higher
    version baseline.
  • SKILL.md reference table + an eval asserting lbc-migrate is recommended for the LBC→Gateway hop and the capture-group rewrite is hand-edited.

@utkarpun utkarpun left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice addition — and to get the obvious worry out of the way: the toolkit is real, not confabulated. Verified from primary sources: LBC v3.4.0 (released 2026-06-03) headlines the Ingress→Gateway toolkit in the release notes, the AWS launch blog is dated 2026-07-20, all 6 reference URLs are live and matching, cmd/lbc-migrate/ + both Makefile targets exist at the v3.4.0 tag, and every CLI flag/default/dry-run mechanic checks out verbatim against upstream. Scoring model is untouched, gates green, mirrors clean, and it test-merges cleanly with #153 in both orders. Two blockers before it lands.

Must-fix

M1 — The "higher baseline" version-gate framing is refuted at source (and leaks into the eval). references/lbc-migrate-toolkit.md:30-31 (+ mirror; echoed in the gateway-api.md banner and both callouts). The file constructs a two-tier model: manual = LBC ≥v2.14 / CRDs v1.3.0, toolkit = "higher baseline v3.4.0 + CRDs v1.5.0". Upstream v3.4.0 gateway.md refutes this — the LBC Gateway path generally is built for Gateway API v1.5.0 and its prerequisites require standard-install.yaml v1.5.0; there is no v1.3.0-manual vs v1.5.0-toolkit tier. The v1.3.0 figure is stale text in the untouched sibling gateway-api.md:9,18, and this PR leans on it to build the tier. Also "ships with and requires v3.4.0" isn't a documented runtime gate (the tool ships in the 3.4.0 tree; upstream Gateway prereqs say LBC ≥v2.13 L4 / ≥v2.14 L7). Please reframe as "the toolkit ships in LBC v3.4.0 (pin your build to that tag); the Gateway API path requires standard CRDs v1.5.0" — dropping the higher-vs-lower tier — fix or explicitly file the gateway-api.md v1.3.0 line (now quoted by the new banner), and update eval id:4's gate assertion to match.

M2 — Mutating commands are unfenced: a literal assessor executing this reference mutates a customer cluster. references/lbc-migrate-toolkit.md — CRD install (kubectl apply ×2, :20-24), Step 3 (--dry-run=false apply / kubectl annotate → creates real ALBs, :74), Step 6 (kubectl delete ingress, :77), feature-gate enable via Helm upgrade (:70). The file's banner says only "All discovery is read-only" — narrower than every sibling's "All checks are read-only" — and the 6-step flow reads as imperative executor instructions. SKILL.md frames this skill as assessment-only, handing manifests to the DevOps team. A literal agent routed here by the "Gateway API automation" row and following Steps 3/6 would delete Ingresses and create ALBs live. Please add an explicit fence: Step 1 translate + dry-run inspection are assessor-runnable (read-only); CRD install, feature-gate enable, and Steps 3–6 are OPERATOR/DevOps actions the assessor documents but never executes. Match the sibling read-only wording.

Should-fix

  • S1 — pin the build: git clone --branch v3.4.0 (the file pins CRDs to the tag but the clone builds HEAD) (:36-40).
  • S2IngressPlanAnnotation=true persists the controller's full model (cert ARNs, auth config, SG IDs) into annotations readable by anyone with Ingress read, and is itself a controller reconfig; add a sensitive-data caveat (:70-72).
  • S3 — add the upstream "Known Differences": migrated manifests can produce more ALB listener rules (Gateway API splits OR-conditions) + priority-order differences; the current list implies clean auto-translation (:85-91).
  • S4 — EKS Auto Mode "Gateway API built-in via eks.amazonaws.com" is unsourced upstream; soften to explicitly-unverified or cite (:31).
  • S5 — traffic-shift specifics (Route 53 weighted "no extra cost" vs Global Accelerator "per-request split") are PR-authored, not upstream (AGA dials endpoint weights, not per-request); soften (:76).
  • S6 — "finish the HTTPRoute by hand with the equivalent filter" gives executors a path to reclassify capture-group rewrites from Tier-A (cap 30, gate) to Tier-B (cap 10, no gate). Restate that a dynamic capture-group rewrite stays Tier-A/gate; only static prefix strips map to ReplacePrefixMatch (:85 + report-generation.md:375).
  • S7 — eval id:4 assertion #4 is internally contradictory ("cannot be represented in Gateway API" AND "requires a URLRewrite/ReplacePrefixMatch edit") and rewards the S6 erosion; assertion #5 is vacuous on an all-ALB fixture; and the load-bearing negative case (below-gate estate must fall back / upgrade) isn't tested. Recalibrate.
  • S8 — atx-guide.md (the automated first hop) has no forward pointer to lbc-migrate — only manual alb-migration.md does; the fully-automated NGINX→Gateway story (ATX hop 1 + lbc-migrate hop 2) is stitched nowhere. Add the pointer (+ Option 3 in report-generation.md).
  • S9 — dual-ALB cost + direct-ALB-DNS blocker live only in the file that full assessments skip; report-generation.md:375 carries the version gate + skip-list but not these two caveats, so they never reach the report. Add both.
  • S10 — report-generation.md Phase 2 step 1 says "automate with lbc-migrate" with no inline version gate (Phase 1 only guarantees ≥v2.14), and the skill never offers "upgrade LBC to v3.4.0 to unlock automation" — the obviously-right answer for a 20-ingress v2.14 estate. Add the gate + upgrade option (report-generation.md:388, gateway-api.md:5).
  • S11 — directive + hardcoded ship-date inside the H2 heading (":: this shipped 2026-07-20") pollutes the site TOC and conflates the blog date with the actual v3.4.0 release date (2026-06-03). Move to body prose as "announced 2026-07"; use ≥-floor version phrasing per M1 (:5, :14).

Nits

  • N1: literal + inside a backticked table cell renders as a diff-marker artifact (:49).
  • N2: trailing whitespace, External Target Groups bullet (:89).
  • N3: "LBC" used before first expansion in title/banner.
  • N4: skip-list flag enumeration repeated verbatim in both callouts (~90 words each); one could point to the file.
  • N5: url-rewrite bullet says "skips + warns" — upstream documents the skip but not a warning for this case; the original regex is discarded. Align wording.

M1 is a re-read of the corrected framing against upstream gateway.md at the v3.4.0 tag + the eval update; M2 is the fence banner + operator-only marking on Steps 3–6/CRD block (Step 1/dry-run stays assessor-runnable). Everything else verified clean.

krittong@amazon.com added 2 commits July 31, 2026 10:39
…lkit (lbc-migrate)

Adds the official AWS Load Balancer Controller Ingress-to-Gateway-API
migration toolkit (lbc-migrate CLI + Migration Console, shipped with LBC
v3.4.0) as the automation sub-path for Option 1 (Gateway API). The skill
previously described only manual HTTPRoute authoring and had zero mention
of the toolkit. Additive only — no scoring-model changes.

- New references/lbc-migrate-toolkit.md: overview, version gate
  (LBC v3.4.0 / Gateway API standard CRDs v1.5.0, higher than the manual
  path's >=v2.14 / CRD v1.3.0 baseline), install (build from source),
  three input modes, output CRDs, the 6-step guided flow (translate ->
  dry-run via gateway.k8s.aws/dry-run + IngressPlanAnnotation feature gate
  -> apply new ALBs alongside -> verify -> shift via Route 53 weighted or
  Global Accelerator -> cleanup), dual-ALB cost + direct-ALB-DNS caveats,
  and the skip-and-warn limitations (capture-group url-rewrite/host-header
  -rewrite, WAF Classic -> WAFv2 first, frontend-nlb-*, group.order,
  external TGs, defaultBackend). All claims cite the launch blog + LBC docs.
- report-generation.md Option 1: automation sub-path callout + Phase 2
  step 1 points at lbc-migrate; manual steps kept as the fallback.
- migration-plan.md Phase 2: same automation callout, manual authoring
  retained as fallback.
- Cross-links the complete path: NGINX Ingress (alb-migration.md) ->
  LBC ALB Ingress -> Gateway API (lbc-migrate-toolkit.md); gateway-api.md
  points to the toolkit and notes the higher version baseline.
- SKILL.md reference table: new row + skip-list entry.
- evals.json: new case asserting lbc-migrate is recommended for the
  LBC Ingress -> Gateway API hop and that the capture-group url-rewrite
  is hand-edited.
- Regenerated the Docusaurus mirror.
…on-gate reframe + assessor-safety fence

Addresses utkarpun's changes-requested review on aws-samples#154.

M1 (version-gate reframe): drop the false two-tier "higher baseline" framing.
The lbc-migrate CLI ships in the LBC v3.4.0 release (build from that tag); its
Gateway API *runtime* prerequisite is the same as the hand-authored path
(controller >= v2.13.3 L4 / >= v2.14 L7). The path uses the current standard
Gateway API CRDs (v1.5.0). Reframed lbc-migrate-toolkit.md version-gate block
and the gateway-api.md automation banner; aligned gateway-api.md's stale
v1.3.0 CRD references to the current v1.5.0 standard; reframed report-generation
Option 1 version wording; updated eval id 4's gate assertion.

M2 (assessor-safety fence): the skill is assessment-only. Added an explicit
assessor-vs-operator fence to lbc-migrate-toolkit.md — only Step 1 (Translate)
and the dry-run preview are assessor-runnable (read-only); the CRD install,
IngressPlanAnnotation feature-gate enable, Step 3 apply (--dry-run=false /
kubectl annotate, creates real ALBs), and Step 6 kubectl delete ingress are
OPERATOR/DevOps actions the assessor documents but never executes. Tagged each
mutating step accordingly. Matches the sibling "all checks are read-only" wording.

Should-fixes: S1 pin `git clone --branch v3.4.0`; S2 IngressPlanAnnotation
dry-run-plan sensitive-data caveat; S3 add upstream "Known Differences" (ALB
listener-rule count / priority order); S4 soften the unsourced EKS Auto Mode
claim; S5 soften the Route 53 / Global Accelerator traffic-shift specifics to
match the guide (mechanism is environment-dependent); S6 the capture-group
url-rewrite has NO Gateway API equivalent and stays Tier-A/gate — only static
prefix strips map to ReplacePrefixMatch (lbc-migrate-toolkit.md + report-gen);
S7 recalibrate eval id 4 (fix the contradictory ReplacePrefixMatch assertion
and the vacuous no-NGINX assertion) and add eval id 5 (raw-NGINX hop-order /
fallback negative case); S8 atx-guide.md forward pointer to lbc-migrate + the
ATX/Option 3 cross-link in report-generation; S9 surface dual-ALB cost +
direct-ALB-DNS traffic-shift blocker in report-generation Option 1; S10 align
report-generation wording.

Regenerated the Docusaurus mirror.
@kritktongrakroj
kritktongrakroj force-pushed the feat/lbc-migrate-gateway-toolkit branch from 4fb748e to 04cbbf9 Compare July 31, 2026 03:55
@kritktongrakroj

Copy link
Copy Markdown
Collaborator Author

M1: Dropped the "higher baseline" two-tier framing. Verified against the upstream migrate-from-ingress guide: the prerequisites are just LBC with Gateway API support + Gateway API CRDs at a compatible version + building the CLI — there's no higher controller tier. Reframed as: the lbc-migrate CLI ships in the LBC v3.4.0 release (build from that tag); Gateway API runtime support is the same as the hand-authored path (≥ v2.13.3 L4 / ≥ v2.14 L7); the path uses standard Gateway API CRDs v1.5.0. Also fixed gateway-api.md's stale v1.3.0 CRD references (the line the banner sat next to) to the current v1.5.0 standard, and updated eval id 4.

M2: Added an explicit assessor-vs-operator fence — only Translate + the dry-run preview are assessor-runnable (read-only); CRD install, the IngressPlanAnnotation feature-gate enable, Step 3 apply (--dry-run=false/kubectl annotate, which creates real ALBs), and Step 6 kubectl delete ingress are operator actions the assessor documents but never executes. Matches the sibling "all checks are read-only" wording. Should-fixes: all ten applied — pinned git clone --branch v3.4.0; IngressPlanAnnotation sensitive-data caveat; upstream "Known Differences" (ALB rule count/priority); softened the Auto Mode and Route 53 / Global Accelerator claims; the capture-group url-rewrite now correctly has no Gateway API equivalent and stays Tier-A/gate (only static prefix strips map to ReplacePrefixMatch); recalibrated eval id 4 and added eval id 5 (raw-NGINX hop-order/fallback case); atx-guide → lbc-migrate forward pointer; dual-ALB cost + direct-ALB-DNS traffic-shift blocker surfaced in report-generation Option 1.

All three CI gates green; mirror regenerated.

@utkarpun utkarpun left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round-2 review — fixup at 04cbbf9

Thanks Krit — the substance of both round-1 must-fixes is in and verified: the new framing at lbc-migrate-toolkit.md:33 matches upstream at the v3.4.0 tag exactly (L4 ≥ v2.13.3, L7 ≥ v2.14, standard CRDs v1.5.0, no documented CLI runtime gate — checked live against gateway.md and migrate_from_ingress.md), and the operator fence is now present and correct at all 5 round-1 mutating sites. The problem is that in both cases the old content wasn't swept out, so the file argues with itself. 3 must-fixes:

Must-fixes

M1 — Retired version-gate framing survives at 4 sites.
The corrected model (:33: toolkit ships in the v3.4.0 release — build from that tag; not a higher controller runtime tier) coexists with the framing round 1 refuted:

  • :14 heading "Version gate (prerequisites)" + :16 "the toolkit ships with and requires:" + :18 "AWS Load Balancer Controller v3.4.0" — the exact wording round-1 M1 was about, verbatim;
  • :99 "when prerequisites (v3.4.0 / CRD v1.5.0) are met" and :100 "estates below the toolkit's version gate";
  • migration-plan.md:46 "clusters below the toolkit's version gate";
  • report-generation.md:375 "Full flow, version gate, and limitations".

(All × 2 copies.) A reader asking "can my v2.14 estate use lbc-migrate without a controller upgrade?" gets opposite answers from :33 vs :14-18 in the same document.

Fix: rename the section (e.g. "Prerequisites (CRDs + build tag)"), replace "ships with and requires" with the :33 framing, and restate :99-:100 / migration-plan.md:46 / report-generation.md:375 to gate on the real prerequisites ("below the Gateway API runtime baseline (≥v2.13.3 L4 / ≥v2.14 L7) or CRDs <v1.5.0") rather than v3.4.0-as-runtime. The PR body needs the same edit (it still says "higher than the manual path's ≥v2.14 / CRD v1.3.0 baseline").

Acceptance check (must return zero gate-framed hits):

grep -rni "ships with and requires\|version gate\|prerequisites (v3.4.0" skills/eks-ingress-migration/ misc/website/docs/

M2 — Hand path still installs Gateway API CRDs v1.3.0.
references/migration-plan.md:19 (+ mirror): kubectl apply -f .../v1.3.0/standard-install.yaml — while this PR moves the CRD baseline to v1.5.0 everywhere else, including the Phase-2 callout 27 lines below in the same file (:46). An assessor following the hand path installs CRDs the v3.4.0 controller isn't built for. One-line URL bump, both copies.

Acceptance check:

grep -rn "v1.3.0" skills/eks-ingress-migration/ misc/website/docs/

Zero Gateway-API hits expected.

M3 — Step 2's dry-run apply is a cluster write under a read-only label.
lbc-migrate-toolkit.md:74 (+ mirror): Step 2's header says "generating/inspecting the plan is read-only", then the second bullet instructs "Apply the generated manifests — they carry gateway.k8s.aws/dry-run: \"true\" … without creating an ALB". Applying them creates real Gateway CRs in the customer cluster (the step's own rollback bullet says "delete the dry-run Gateway") — which the banner at :5 itself defines as operator-only, yet the banner's operator enumeration omits this apply. A literal assessor routed mid-file applies manifests to a customer cluster believing it safe.

To be fair: our round-1 fix wording ("Step 1 translate + dry-run inspection are assessor-runnable") didn't call out this bullet — the prescription was under-specified on our side. But it needs closing.

Fix: mark the dry-run apply bullet OPERATOR (or reword: "cluster owner applies; assessor inspects the resulting dry-run annotation/diff — read-only") and add it to the banner's operator enumeration. Both copies.

Should-fixes (non-blocking)

S1SKILL.md:18 says "≥ v2.13" where every other surface says v2.13.3 (bare v2.13 wrongly admits 2.13.0–2 for L4). Pre-existing, but this PR touched all the sibling figures.
S2 — "this shipped 2026-07-20" in a heading: that's the blog date, not the v3.4.0 release (2026-06-03); date-in-headings also pollute the TOC (carried from round 1).
S3 — still no below-gate negative eval case (carried; id:4/id:5 are otherwise deterministic and the tier language is fully purged from them — nice).
S4 — round-1 S10 carry: report-generation's Phase-2 step has no inline prerequisite note and no "upgrade LBC to unlock automation" option.

Round-1 nits N1–N5 remain open — fold in or note as deferred.

Per-item report request

With the fixup, please include a table — one row per item (M1, M2, M3, S1–S4), status DONE / SKIPPED (+reason), file:line(s) edited in both copies — plus the pasted output of the two grep checks above. Both rounds so far lost items to the old value surviving on a sibling surface; the greps make "swept to zero" checkable rather than trust-based.

Verified clean this round (no need to re-touch)

Upstream fact table at v3.4.0 (all figures match); fence at all 5 round-1 mutating sites; S1/S2/S3/S5/S6/S8/S9 from round 1 all landed as described (pinned clone, sensitive-data caveat, Known-Differences bullet, traffic-shift wording, capture-group Tier-A retention + eval fix, atx-guide pointer, dual-ALB cost + direct-DNS callouts in the main flow); repo gates green; test-merge with #153 clean in both orders.

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.

2 participants