aws-samples / aws-samples/appmod-blueprints
feat(exposure): implement AppExposure RGD + shared CloudFront/ALB edge
- Dominant language
- Shell
- Stars
- 105
- Forks
- 62
- Avg merge
- 11h 17m
- Merged PRs (30d)
- 76
Description
## Context
The `kind-kro-ack` bootstrap (PR #642) is functional end-to-end:
- Hub EKS created via ACK/KRO from Kind ✅
- ArgoCD Capability (IDC integrated) ✅
- Spoke-dev EKS created via KRO/ACK on hub (GitOps) ✅
- 37+ addons synced/healthy ✅
## Blocking Issue
**Multiple apps are Degraded because they use `ingressClassName: nginx` which does not exist.** We removed ingress-nginx (deprecated) but the replacement exposure layer is not yet implemented.
Affected apps: `argo-workflows-hub`, `gitlab-hub`, `kargo-hub`, `grafana-dashboards-hub`, `keycloak-hub`, `backstage-hub`, `devlake-hub`
## What Needs to Be Done
Implement the architecture from PR #660 (`docs/exposure-architecture.md`):
### Phase 0 — Shared Edge (Taskfile)
Already partially done in PR #642:
- `task hub:ingress` creates ALB with fixed name (`hub-ingress`)
- `task hub:cloudfront` creates CloudFront → ALB origin
- CloudFront domain stored in cluster secret annotation `ingress_domain_name`
**Missing**: the ALB needs a default Listener (HTTP:80, default action 404) created by the Taskfile so that ListenerRules can attach to it.
### Phase 1 — Per-App Exposure (GitOps)
Replace `Ingress` resources in addon charts with `AppExposure` CRD instances (or at minimum, fix the Ingress to use `ingressClassName: platform` with `alb.ingress.kubernetes.io/load-balancer-name` annotation).
**Quick fix** (unblocks everything without full AppExposure RGD):
1. Change all addon charts from `ingressClassName: nginx` → `ingressClassName: platform`
2. Add `alb.ingress.kubernetes.io/load-balancer-name: {{ .Values.ingress_name }}` annotation
3. Add `alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80}]'` (CloudFront terminates TLS)
4. Remove `ssl-redirect` annotations
Charts to update:
- `gitops/addons/charts/argo-workflows/templates/ingress.yaml` (partially done)
- `gitops/addons/charts/keycloak/templates/ingress.yaml` (partially done)
- `gitops/addons/charts/gitlab/` (uses nginx)
- `gitops/addons/charts/kargo/` (uses nginx)
- `gitops/addons/charts/grafana-dashboards/` or grafana-operator (uses nginx)
- `gitops/addons/charts/backstage/` (uses nginx)
- `gitops/addons/charts/devlake/` (uses nginx)
- `gitops/addons/charts/jupyterhub/` (uses nginx)
### Full AppExposure RGD (Phase 2)
As documented in PR #660:
- RGD creates: ACK ELBv2 TargetGroup → ListenerRule → AWS LBC TargetGroupBinding
- No Ingress resource needed
- ACK ELBv2 CRDs are already available on the hub (Capability ACK includes them)
## Available Infrastructure
- ACK ELBv2 CRDs on hub: `targetgroups`, `rules`, `listeners`, `loadbalancers` ✅
- `TargetGroupBinding` CRD (AWS LBC) ✅
- CloudFront distribution: `d2jpudacp2clwx.cloudfront.net` (previous account, will be recreated)
- ALB created by Taskfile with fixed name
## Branch
All work is on `feature/platform-cluster-kro-ack` (PR #642, target: `feature/agent-platform`)
## Priority
**HIGH** — this blocks all user-facing apps (Backstage, GitLab, Keycloak, ArgoCD Workflows, Grafana, Kargo, DevLake, JupyterHub) from being accessible.
Contributor guide
Research direction
Start by reading docs/exposure-architecture.md and the shared-edge steps in the Taskfile, then inspect the listed addon ingress templates, including gitops/addons/charts/argo-workflows/templates/ingress.yaml and the GitLab, Kargo, Grafana, Backstage, DevLake, and JupyterHub charts. Verify the existing ALB and ACK ELBv2 resources on the hub before choosing the quick fix or full AppExposure path. Done means the shared listener and per-app exposure are deployed, and the affected applications are no longer blocked by the missing nginx ingress class.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, helm, kubernetes, shell
- Domain
- cloud, devops, infrastructure
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100