1import * as ec2 from "@distilled.cloud/aws/ec2";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as Binding from "../../Binding.ts";
5import { isBindingHost } from "../Lambda/Function.ts";
6import { DescribeInstance } from "./DescribeInstance.ts";
7import { isInstance, type Instance } from "./Instance.ts";
8
9// Bespoke (not the shared scaffold): `describeInstances` nests results under
10// Reservations[].Instances[] and the client unwraps the single bound
11// instance.
12export const DescribeInstanceHttp = Layer.effect(
13 DescribeInstance,
14 Effect.gen(function* () {
15 const describe = yield* ec2.describeInstances;
16
17 return Effect.fn(function* (instance: Instance) {
18 const instanceId = yield* instance.instanceId;
19 if (!globalThis.__ALCHEMY_RUNTIME__) {
20 const host = yield* Binding.Host;
21 if (isBindingHost(host) || isInstance(host)) {
22 yield* host.bind`Allow(${host}, AWS.EC2.DescribeInstance(${instance}))`(
23 {
24 policyStatements: [
25 {
26 Effect: "Allow",
27 Action: ["ec2:DescribeInstances"],
28 Resource: ["*"],
29 },
30 ],
31 },
32 );
33 }
34 }
35 return Effect.fn(`AWS.EC2.DescribeInstance(${instance.LogicalId})`)(
36 function* () {
37 const result = yield* describe({
38 InstanceIds: [yield* instanceId],
39 });
40 return result.Reservations?.[0]?.Instances?.[0];
41 },
42 );
43 });
44 }),
45);