1import * as AWS from "@/AWS";
2import * as Kubernetes from "@/Kubernetes";
3import * as Effect from "effect/Effect";
4import { HttpServerRequest } from "effect/http/HttpServerRequest";
5import * as HttpServerResponse from "effect/http/HttpServerResponse";
6
7/**
8 * End-to-end fixture for `Kubernetes.Deployment` on EKS: an Effect HTTP
9 * server deployed as a Kubernetes Deployment + LoadBalancer Service.
10 *
11 * - The target cluster is deployed by the test's phase-1 program and referenced
12 * here via `AWS.EKS.Cluster.ref("EksHostCluster")` (props are an Effect).
13 * Refs resolve from stack state, giving the Deployment the cluster's
14 * `connection` — the reconciler applies the Deployment/Service via
15 * server-side apply against it through the `aws-eks` cluster adapter.
16 * - The DynamoDB `Table` is yielded inline (a plain Resource, safe to nest) and
17 * bound via `PutItem`. The binding lands `dynamodb:PutItem` IAM on the
18 * generated pod-identity role and injects the table name into the pod. At
19 * runtime the pod resolves credentials through the EKS Pod Identity
20 * container-credentials chain (`Credentials.fromChain()` in the bootstrap).
21 * - `/put?id=x` writes an item so the test can prove the binding worked by
22 * reading it back out-of-band; `/health` gates readiness.
23 */
24export default class EksHostApi extends Kubernetes.Deployment<EksHostApi>()(
25 "EksHostApi",
26 Effect.gen(function* () {
27 const cluster = yield* AWS.EKS.Cluster.ref("EksHostCluster");
28 return {
29 main: import.meta.url,
30 cluster,
31 port: 3000,
32 serviceType: "LoadBalancer" as const,
33 };
34 }),
35 Effect.gen(function* () {
36 const table = yield* AWS.DynamoDB.Table("EksHostTable", {
37 partitionKey: "pk",
38 attributes: { pk: "S" },
39 });
40 const putItem = yield* AWS.DynamoDB.PutItem(table);
41 const TableName = yield* table.tableName;
42
43 return {
44 fetch: Effect.gen(function* () {
45 const request = yield* HttpServerRequest;
46 const url = new URL(request.url, "http://eks-host");
47 if (url.pathname === "/health") {
48 return yield* HttpServerResponse.json({ ok: true });
49 }
50 if (url.pathname === "/put") {
51 const id = url.searchParams.get("id") ?? "default";
52 yield* putItem({ Item: { pk: { S: id } } });
53 return yield* HttpServerResponse.json({
54 written: id,
55 table: yield* TableName,
56 });
57 }
58 return HttpServerResponse.text("kubernetes deployment");
59 }).pipe(Effect.orDie),
60 };
61 }).pipe(Effect.provide(AWS.DynamoDB.PutItemHttp)),
62) {}