1import * as GCP from "@/GCP";
2import * as Kubernetes from "@/Kubernetes";
3import * as Effect from "effect/Effect";
4import { SMOKE_REGION } from "../../zones.ts";
5
6/**
7 * Shared infrastructure for the GKE smoke. Resources are memoized by
8 * logical id, so the stack program and the workloads' props/init effects
9 * converge on the same instances.
10 */
11
12/** The Kubernetes namespace every smoke workload runs in. */
13export const SMOKE_NAMESPACE = "gke-smoke";
14
15/** The object the one-shot Job writes through its binding. */
16export const JOB_MARKER_KEY = "job/marker.txt";
17export const JOB_MARKER_BODY = "written by the GKE smoke job";
18
19/**
20 * Autopilot: Google provisions nodes from the pods' resource requests.
21 * Autopilot clusters are always regional.
22 */
23export const SmokeCluster = GCP.Container.Cluster("GkeSmokeCluster", {
24 location: SMOKE_REGION,
25 autopilot: true,
26 releaseChannel: "REGULAR",
27});
28
29/** The bucket both workloads reach through Workload Identity. */
30export const SmokeBucket = GCP.Storage.Bucket("GkeSmokeBucket", {
31 location: SMOKE_REGION.toUpperCase(),
32 uniformBucketLevelAccess: true,
33 forceDestroy: true,
34});
35
36/** The namespace, applied as a raw manifest. */
37export const SmokeNamespace = Effect.gen(function* () {
38 const cluster = yield* SmokeCluster;
39 return yield* Kubernetes.Manifest("GkeSmokeNamespace", {
40 cluster,
41 manifest: {
42 apiVersion: "v1",
43 kind: "Namespace",
44 metadata: { name: SMOKE_NAMESPACE },
45 },
46 });
47});
48
49/** Autopilot pins limits to requests; keep both small and equal. */
50export const smokeResources = {
51 requests: { cpu: "250m", memory: "512Mi" },
52 limits: { cpu: "250m", memory: "512Mi" },
53};