Skip to content
Source
Sign inSign up

alchemy.run.ts

83 lines2.5 KB

1import * as AWS from "@alchemy.run/aws";
2import * as Alchemy from "alchemy";
3import * as Output from "alchemy/Output";
4import * as Effect from "effect/Effect";
5import JobFunction from "./src/JobFunction.ts";
6​
7// AWS.providers() already provides AWSEnvironment from the SSO profile
8// named by $AWS_PROFILE (defaults to "default"). To pin a different
9// profile per stage, wrap with `Layer.provide(AWS.makeEnvironment({...}))`.
10const aws = AWS.providers();
11const dashboardRegion = process.env.AWS_REGION ?? "us-west-2";
12​
13export default Alchemy.Stack(
14 "JobLambda",
15 {
16 providers: aws,
17 state: Alchemy.localState(),
18 },
19 Effect.gen(function* () {
20 const func = yield* JobFunction;
21 const dashboard = yield* AWS.CloudWatch.Dashboard("JobDashboard", {
22 DashboardBody: func.functionName.pipe(
23 Output.map((functionName) => ({
24 widgets: [
25 {
26 type: "metric",
27 x: 0,
28 y: 0,
29 width: 12,
30 height: 6,
31 properties: {
32 title: "Lambda Invocations and Errors",
33 region: dashboardRegion,
34 stat: "Sum",
35 period: 300,
36 metrics: [
37 ["AWS/Lambda", "Invocations", "FunctionName", functionName],
38 ["AWS/Lambda", "Errors", "FunctionName", functionName],
39 ],
40 },
41 },
42 {
43 type: "metric",
44 x: 12,
45 y: 0,
46 width: 12,
47 height: 6,
48 properties: {
49 title: "Lambda Duration",
50 region: dashboardRegion,
51 stat: "Average",
52 period: 300,
53 metrics: [["AWS/Lambda", "Duration", "FunctionName", functionName]],
54 },
55 },
56 ],
57 })),
58 ),
59 });
60 const alarm = yield* AWS.CloudWatch.Alarm("JobFunctionErrorsAlarm", {
61 AlarmDescription: "Alerts when the example Lambda function reports errors.",
62 MetricName: "Errors",
63 Namespace: "AWS/Lambda",
64 Statistic: "Sum",
65 Period: 300,
66 EvaluationPeriods: 1,
67 Threshold: 1,
68 ComparisonOperator: "GreaterThanOrEqualToThreshold",
69 TreatMissingData: "notBreaching",
70 Dimensions: [
71 {
72 Name: "FunctionName",
73 Value: func.functionName,
74 },
75 ],
76 });
77 return {
78 url: Output.interpolate`${func.functionUrl}?jobId=foo`,
79 dashboardName: dashboard.dashboardName,
80 alarmName: alarm.alarmName,
81 };
82 }),
83);