1# AWS EKS Example
2
3A "guestbook" app on EKS Auto Mode, fully TypeScript-driven — no YAML, no
4`kubectl apply`, no Helm.
5
6- [`src/infra.ts`](./src/infra.ts) — the shared infrastructure: a VPC, an
7 `AWS.EKS.Cluster` with `compute: "auto"` (the provider creates and owns the
8 cluster + node IAM roles and enables managed compute, storage, and load
9 balancing), a DynamoDB table, and a namespace applied as a raw manifest via
10 `Kubernetes.Manifest`.
11- [`src/Api.ts`](./src/Api.ts) — an effectful `Kubernetes.Deployment` in the
12 tagged form (`Api.make(props, impl)`): an Effect HTTP server bundled into a
13 generated image, exposed through an internet-facing NLB, with DynamoDB
14 bindings that land IAM on the pod-identity role and inject the table name
15 into the pod. Includes the typed `podTemplate` escape hatch.
16- [`src/SeedJob.ts`](./src/SeedJob.ts) — an inline-effect one-shot
17 `Kubernetes.Job` (`{ run }`) that seeds the guestbook table when the Job is
18 applied on deploy.
19- [`alchemy.run.ts`](./alchemy.run.ts) — thin composition: yields the shared
20 infra, the tagged `Api` (via `Effect.provide(ApiLive)`), an EXTERNAL
21 nginx `Kubernetes.Deployment` (registry `image:` source), and the `SeedJob`.
22
23## Commands
24
25```sh
26bun install
27bun run --filter aws-eks-example deploy
28bun run --filter aws-eks-example destroy
29```
30
31The cluster control plane takes ~15 minutes to provision.
32
33## Try it
34
35```sh
36# outputs: apiUrl (note the :3000 — the NLB listens on the Service port), webUrl
37curl "$apiUrl/entries" # seeded by SeedJob
38curl -X POST "$apiUrl/entries?author=you&message=hello"
39curl "$apiUrl/entries/ada"
40curl "$webUrl" # external nginx deployment
41```
42
43## Optional Inspection
44
45To inspect the cluster manually after deploy:
46
47```sh
48aws eks update-kubeconfig --name <clusterName output> --region "$AWS_REGION"
49kubectl get pods -n guestbook
50```