1import * as autoscaling from "@distilled.cloud/aws/auto-scaling";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as Binding from "../../Binding.ts";
5import { isInstance } from "../EC2/Instance.ts";
6import { isBindingHost } from "../Lambda/Function.ts";
7import type { AutoScalingGroup } from "./AutoScalingGroup.ts";
8import {
9 InstanceRefresh,
10 type CancelInstanceRefreshRequest,
11 type DescribeInstanceRefreshesRequest,
12 type StartInstanceRefreshRequest,
13} from "./InstanceRefresh.ts";
14
15// Bespoke (not the shared scaffold): a multi-operation client over the four
16// instance refresh operations behind one two-statement IAM grant (the write
17// actions are group-scoped, Describe* only supports `*`).
18export const InstanceRefreshHttp = Layer.effect(
19 InstanceRefresh,
20 Effect.gen(function* () {
21 const start = yield* autoscaling.startInstanceRefresh;
22 const cancel = yield* autoscaling.cancelInstanceRefresh;
23 const rollback = yield* autoscaling.rollbackInstanceRefresh;
24 const describe = yield* autoscaling.describeInstanceRefreshes;
25
26 return Effect.fn(function* (group: AutoScalingGroup) {
27 const AutoScalingGroupName = yield* group.autoScalingGroupName;
28 if (!globalThis.__ALCHEMY_RUNTIME__) {
29 const host = yield* Binding.Host;
30 if (isBindingHost(host) || isInstance(host)) {
31 yield* host.bind`Allow(${host}, AWS.AutoScaling.InstanceRefresh(${group}))`(
32 {
33 policyStatements: [
34 {
35 Effect: "Allow",
36 Action: [
37 "autoscaling:StartInstanceRefresh",
38 "autoscaling:CancelInstanceRefresh",
39 "autoscaling:RollbackInstanceRefresh",
40 ],
41 Resource: [group.autoScalingGroupArn],
42 },
43 {
44 Effect: "Allow",
45 Action: ["autoscaling:DescribeInstanceRefreshes"],
46 Resource: ["*"],
47 },
48 ],
49 },
50 );
51 }
52 }
53 return {
54 start: Effect.fn(
55 `AWS.AutoScaling.StartInstanceRefresh(${group.LogicalId})`,
56 )(function* (request?: StartInstanceRefreshRequest) {
57 return yield* start({
58 ...request,
59 AutoScalingGroupName: yield* AutoScalingGroupName,
60 });
61 }),
62 cancel: Effect.fn(
63 `AWS.AutoScaling.CancelInstanceRefresh(${group.LogicalId})`,
64 )(function* (request?: CancelInstanceRefreshRequest) {
65 return yield* cancel({
66 ...request,
67 AutoScalingGroupName: yield* AutoScalingGroupName,
68 });
69 }),
70 rollback: Effect.fn(
71 `AWS.AutoScaling.RollbackInstanceRefresh(${group.LogicalId})`,
72 )(function* () {
73 return yield* rollback({
74 AutoScalingGroupName: yield* AutoScalingGroupName,
75 });
76 }),
77 describe: Effect.fn(
78 `AWS.AutoScaling.DescribeInstanceRefreshes(${group.LogicalId})`,
79 )(function* (request?: DescribeInstanceRefreshesRequest) {
80 return yield* describe({
81 ...request,
82 AutoScalingGroupName: yield* AutoScalingGroupName,
83 });
84 }),
85 };
86 });
87 }),
88);