@infoxchange/make-it-so 2.18.0 → 2.18.1-internal-testing-add-tag-setup-6f9bc82.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -0
- package/dist/deployConfig.d.ts +4 -0
- package/dist/deployConfig.d.ts.map +1 -1
- package/dist/deployConfig.js +3 -0
- package/dist/lib/tags/ConditionalTags.d.ts +11 -0
- package/dist/lib/tags/ConditionalTags.d.ts.map +1 -0
- package/dist/lib/tags/ConditionalTags.js +12 -0
- package/dist/lib/tags/index.d.ts +3 -0
- package/dist/lib/tags/index.d.ts.map +1 -0
- package/dist/lib/tags/index.js +2 -0
- package/dist/lib/tags/setupTags.d.ts +18 -0
- package/dist/lib/tags/setupTags.d.ts.map +1 -0
- package/dist/lib/tags/setupTags.js +33 -0
- package/package.json +3 -2
- package/src/deployConfig.ts +3 -0
- package/src/lib/tags/ConditionalTags.ts +16 -0
- package/src/lib/tags/index.ts +2 -0
- package/src/lib/tags/setupTags.ts +55 -0
package/README.md
CHANGED
|
@@ -232,6 +232,70 @@ const domainCert = new IxCertificate(scope, "ExampleDotComCertificate", {
|
|
|
232
232
|
|
|
233
233
|
</details>
|
|
234
234
|
|
|
235
|
+
<details>
|
|
236
|
+
<summary><strong>IxCloudWatchAlarm</strong> - Creates a CloudWatch alarm with IX-specific defaults.</summary>
|
|
237
|
+
|
|
238
|
+
IxCloudWatchAlarm extends AWS CDK's CloudWatch Alarm functionality with IX-specific defaults and special handling for CloudFront alarms (which must be created in us-east-1). If no actions are specified, the alarm will automatically use the IX alarm SNS topic.
|
|
239
|
+
|
|
240
|
+
The construct also supports a `toNotify` property that allows you to specify email addresses or other notification identifiers, which will be added to the alarm description for IX's monitoring system.
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import { IxCloudWatchAlarm } from "@infoxchange/make-it-so/cdk-constructs";
|
|
244
|
+
|
|
245
|
+
new IxCloudWatchAlarm(scope, "ApiErrorAlarm", {
|
|
246
|
+
alarmName: "high-error-rate",
|
|
247
|
+
metric: {
|
|
248
|
+
namespace: "AWS/ApiGateway",
|
|
249
|
+
metricName: "5XXError",
|
|
250
|
+
dimensionsMap: {
|
|
251
|
+
ApiName: "my-api",
|
|
252
|
+
},
|
|
253
|
+
period: (Duration) => Duration.minutes(5),
|
|
254
|
+
statistic: (Stats) => Stats.AVERAGE,
|
|
255
|
+
},
|
|
256
|
+
threshold: 10,
|
|
257
|
+
evaluationPeriods: 2,
|
|
258
|
+
comparisonOperator: (ComparisonOperator) =>
|
|
259
|
+
ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
260
|
+
toNotify: ["team@example.com"],
|
|
261
|
+
alarmDescription: "Alert when API error rate is too high",
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
#### Options:
|
|
266
|
+
|
|
267
|
+
| Prop | Type | Description |
|
|
268
|
+
| -------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
269
|
+
| metric | object | Metric configuration |
|
|
270
|
+
| metric.namespace | string | The namespace of the metric (e.g., "AWS/ApiGateway") |
|
|
271
|
+
| metric.metricName | string | The name of the metric |
|
|
272
|
+
| metric.dimensionsMap | Record<string, string> | (optional) Dimensions for the metric |
|
|
273
|
+
| metric.period | Duration \| ((Duration) => Duration) | (optional) The period over which the statistic is applied. Can be a function for easier access to CDK Duration helpers |
|
|
274
|
+
| metric.statistic | string \| ((Stats) => string) | (optional) The statistic to apply (e.g., "Average", "Sum"). Can be a function for easier access to CloudWatch.Stats helpers |
|
|
275
|
+
| comparisonOperator | ComparisonOperator \| ((ComparisonOperator) => ComparisonOperator) | How to compare the metric to the threshold. Can be a function for easier access to CloudWatch.ComparisonOperator helpers |
|
|
276
|
+
| threshold | number | The value to compare the metric against |
|
|
277
|
+
| evaluationPeriods | number | The number of periods over which data is compared to the threshold |
|
|
278
|
+
| treatMissingData | TreatMissingData \| ((TreatMissingData) => TreatMissingData) | (optional) How to treat missing data points. Can be a function for easier access to CloudWatch.TreatMissingData helpers |
|
|
279
|
+
| alarmName | string | (optional) Name of the alarm |
|
|
280
|
+
| alarmDescription | string | (optional) Description of the alarm |
|
|
281
|
+
| toNotify | string[] | (optional) List of email addresses or notification identifiers to be notified when the alarm triggers. This will be added to the alarm description |
|
|
282
|
+
| actions | object | (optional) Actions to take when alarm state changes. If not provided, defaults to IX alarm SNS topic |
|
|
283
|
+
| actions.onOk | (string \| IAlarmAction)[] | (optional) Actions to take when alarm goes to OK state |
|
|
284
|
+
| actions.onAlarm | (string \| IAlarmAction)[] | (optional) Actions to take when alarm goes to ALARM state |
|
|
285
|
+
| actions.onInsufficientData | (string \| IAlarmAction)[] | (optional) Actions to take when alarm goes to INSUFFICIENT_DATA state |
|
|
286
|
+
| [...CloudWatch.AlarmProps] | | Any other props accepted by [CloudWatch.Alarm](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudwatch.Alarm.html) |
|
|
287
|
+
|
|
288
|
+
#### Static Properties:
|
|
289
|
+
|
|
290
|
+
IxCloudWatchAlarm provides convenient static access to CloudWatch constants:
|
|
291
|
+
|
|
292
|
+
- `IxCloudWatchAlarm.Stats` - CloudWatch.Stats for metric statistics
|
|
293
|
+
- `IxCloudWatchAlarm.Duration` - CDK.Duration for time periods
|
|
294
|
+
- `IxCloudWatchAlarm.TreatMissingData` - CloudWatch.TreatMissingData for handling missing data
|
|
295
|
+
- `IxCloudWatchAlarm.ComparisonOperator` - CloudWatch.ComparisonOperator for comparison operations
|
|
296
|
+
|
|
297
|
+
</details>
|
|
298
|
+
|
|
235
299
|
<details>
|
|
236
300
|
<summary><strong>IxDnsRecord</strong> - Creates a DNS record for a domain managed by IX.</summary>
|
|
237
301
|
|
package/dist/deployConfig.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ declare const _default: {
|
|
|
16
16
|
clamAVUrl: string;
|
|
17
17
|
vpcHttpProxy: string;
|
|
18
18
|
alarmSnsTopic: string;
|
|
19
|
+
tags: Record<string, string>;
|
|
19
20
|
} | {
|
|
20
21
|
isIxDeploy: false;
|
|
21
22
|
appName: string;
|
|
@@ -32,6 +33,7 @@ declare const _default: {
|
|
|
32
33
|
clamAVUrl: string;
|
|
33
34
|
vpcHttpProxy: string;
|
|
34
35
|
alarmSnsTopic: string;
|
|
36
|
+
tags: Record<string, string>;
|
|
35
37
|
isInternalApp?: boolean | undefined;
|
|
36
38
|
smtpPort?: number | undefined;
|
|
37
39
|
};
|
|
@@ -54,6 +56,7 @@ export declare const getDeployConfig: () => {
|
|
|
54
56
|
clamAVUrl: string;
|
|
55
57
|
vpcHttpProxy: string;
|
|
56
58
|
alarmSnsTopic: string;
|
|
59
|
+
tags: Record<string, string>;
|
|
57
60
|
} | {
|
|
58
61
|
isIxDeploy: false;
|
|
59
62
|
appName: string;
|
|
@@ -70,6 +73,7 @@ export declare const getDeployConfig: () => {
|
|
|
70
73
|
clamAVUrl: string;
|
|
71
74
|
vpcHttpProxy: string;
|
|
72
75
|
alarmSnsTopic: string;
|
|
76
|
+
tags: Record<string, string>;
|
|
73
77
|
isInternalApp?: boolean | undefined;
|
|
74
78
|
smtpPort?: number | undefined;
|
|
75
79
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployConfig.d.ts","sourceRoot":"","sources":["../src/deployConfig.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deployConfig.d.ts","sourceRoot":"","sources":["../src/deployConfig.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyFA,wBAA0C;AAG1C,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAmC,CAAC"}
|
package/dist/deployConfig.js
CHANGED
|
@@ -17,6 +17,7 @@ const getEnvVars = () => ({
|
|
|
17
17
|
clamAVUrl: process.env.CLAMAV_URL ?? "",
|
|
18
18
|
vpcHttpProxy: process.env.VPC_HTTP_PROXY ?? "",
|
|
19
19
|
alarmSnsTopic: process.env.IX_ALARM_SNS_TOPIC ?? "",
|
|
20
|
+
tags: JSON.parse(process.env.IX_TAGS ?? "{}"),
|
|
20
21
|
});
|
|
21
22
|
const ixDeployConfigSchema = z
|
|
22
23
|
.object({
|
|
@@ -41,6 +42,7 @@ const ixDeployConfigSchema = z
|
|
|
41
42
|
clamAVUrl: z.string().url(),
|
|
42
43
|
vpcHttpProxy: z.string().url(),
|
|
43
44
|
alarmSnsTopic: z.string().min(1),
|
|
45
|
+
tags: z.record(z.string(), z.string()),
|
|
44
46
|
})
|
|
45
47
|
.strip();
|
|
46
48
|
const nonIxDeployConfigSchema = z
|
|
@@ -70,6 +72,7 @@ const nonIxDeployConfigSchema = z
|
|
|
70
72
|
clamAVUrl: z.string(),
|
|
71
73
|
vpcHttpProxy: z.string(),
|
|
72
74
|
alarmSnsTopic: z.string(),
|
|
75
|
+
tags: z.record(z.string(), z.string()),
|
|
73
76
|
})
|
|
74
77
|
.strip();
|
|
75
78
|
const schema = z.discriminatedUnion("isIxDeploy", [
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IAspect } from "aws-cdk-lib";
|
|
2
|
+
import { IConstruct } from "constructs";
|
|
3
|
+
export declare class ConditionalTags implements IAspect {
|
|
4
|
+
private getTags;
|
|
5
|
+
constructor(getTags: (node: IConstruct) => Array<{
|
|
6
|
+
key: string;
|
|
7
|
+
value: string;
|
|
8
|
+
}> | undefined | null);
|
|
9
|
+
visit(node: IConstruct): void;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=ConditionalTags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConditionalTags.d.ts","sourceRoot":"","sources":["../../../src/lib/tags/ConditionalTags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAQ,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,qBAAa,eAAgB,YAAW,OAAO;IAE3C,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,CACf,IAAI,EAAE,UAAU,KACb,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,GAAG,IAAI;IAG/D,KAAK,CAAC,IAAI,EAAE,UAAU;CAKvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/tags/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IConstruct } from "constructs";
|
|
2
|
+
export type ModifyTagsProps = {
|
|
3
|
+
node: IConstruct;
|
|
4
|
+
isLeafNode: boolean;
|
|
5
|
+
isRootNode: boolean;
|
|
6
|
+
currentTags: Array<{
|
|
7
|
+
key: string;
|
|
8
|
+
value: string;
|
|
9
|
+
}>;
|
|
10
|
+
};
|
|
11
|
+
export type SetupTagsOptions = {
|
|
12
|
+
modifyTags?: (props: ModifyTagsProps) => Array<{
|
|
13
|
+
key: string;
|
|
14
|
+
value: string;
|
|
15
|
+
}>;
|
|
16
|
+
};
|
|
17
|
+
export declare function setupTags(scope: IConstruct, { modifyTags }?: SetupTagsOptions): void;
|
|
18
|
+
//# sourceMappingURL=setupTags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupTags.d.ts","sourceRoot":"","sources":["../../../src/lib/tags/setupTags.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKxC,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,CAAC,EAAE,CACX,KAAK,EAAE,eAAe,KACnB,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5C,CAAC;AAEF,wBAAgB,SAAS,CACvB,KAAK,EAAE,UAAU,EACjB,EAAE,UAAU,EAAE,GAAE,gBAAqB,QAiCtC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Aspects } from "aws-cdk-lib";
|
|
2
|
+
import { Function } from "sst/constructs";
|
|
3
|
+
import { ConditionalTags } from "./ConditionalTags.js";
|
|
4
|
+
import deployConfig from "../../deployConfig.js";
|
|
5
|
+
export function setupTags(scope, { modifyTags } = {}) {
|
|
6
|
+
const conditionalTags = new ConditionalTags((node) => {
|
|
7
|
+
let tags = [];
|
|
8
|
+
const isLeafNode = node.node.children.length === 0;
|
|
9
|
+
const isRootNode = node === scope;
|
|
10
|
+
// Add tags from deploy config to all constructs
|
|
11
|
+
if (isRootNode) {
|
|
12
|
+
Object.entries(deployConfig.tags).forEach(([key, value]) => {
|
|
13
|
+
tags.push({ key, value });
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
// SST v2's live lambda feature means that the local machine that `sst dev` is run on may use AWS creds that were
|
|
17
|
+
// setup for a lambda. This triggers a false positive in GuardDuty, so we suppress that finding for any lambda that
|
|
18
|
+
// has live dev enabled.
|
|
19
|
+
if (node instanceof Function && node._isLiveDevEnabled) {
|
|
20
|
+
tags.push({ key: "guardduty-suppress", value: "true" });
|
|
21
|
+
}
|
|
22
|
+
tags = modifyTags
|
|
23
|
+
? modifyTags({
|
|
24
|
+
node,
|
|
25
|
+
isLeafNode,
|
|
26
|
+
isRootNode,
|
|
27
|
+
currentTags: tags,
|
|
28
|
+
})
|
|
29
|
+
: tags;
|
|
30
|
+
return tags;
|
|
31
|
+
});
|
|
32
|
+
Aspects.of(scope).add(conditionalTags);
|
|
33
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infoxchange/make-it-so",
|
|
3
|
-
"version": "2.18.
|
|
3
|
+
"version": "2.18.1-internal-testing-add-tag-setup-6f9bc82.1",
|
|
4
4
|
"description": "Makes deploying services to IX infra easy",
|
|
5
5
|
"repository": "github:infoxchange/make-it-so",
|
|
6
6
|
"publishConfig": {
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"./cdk-constructs": "./dist/cdk-constructs/index.js",
|
|
22
22
|
"./deployConfig": "./dist/deployConfig.js",
|
|
23
23
|
"./auth": "./dist/lib/auth/index.js",
|
|
24
|
-
"./proxy": "./dist/lib/proxy/index.js"
|
|
24
|
+
"./proxy": "./dist/lib/proxy/index.js",
|
|
25
|
+
"./tags": "./dist/lib/tags/index.js"
|
|
25
26
|
},
|
|
26
27
|
"lint-staged": {
|
|
27
28
|
"**/*": [
|
package/src/deployConfig.ts
CHANGED
|
@@ -19,6 +19,7 @@ const getEnvVars = () =>
|
|
|
19
19
|
clamAVUrl: process.env.CLAMAV_URL ?? "",
|
|
20
20
|
vpcHttpProxy: process.env.VPC_HTTP_PROXY ?? "",
|
|
21
21
|
alarmSnsTopic: process.env.IX_ALARM_SNS_TOPIC ?? "",
|
|
22
|
+
tags: JSON.parse(process.env.IX_TAGS ?? "{}"),
|
|
22
23
|
}) satisfies Record<string, string | boolean>;
|
|
23
24
|
|
|
24
25
|
const ixDeployConfigSchema = z
|
|
@@ -44,6 +45,7 @@ const ixDeployConfigSchema = z
|
|
|
44
45
|
clamAVUrl: z.string().url(),
|
|
45
46
|
vpcHttpProxy: z.string().url(),
|
|
46
47
|
alarmSnsTopic: z.string().min(1),
|
|
48
|
+
tags: z.record(z.string(), z.string()),
|
|
47
49
|
} satisfies Record<keyof ReturnType<typeof getEnvVars>, unknown>)
|
|
48
50
|
.strip();
|
|
49
51
|
|
|
@@ -76,6 +78,7 @@ const nonIxDeployConfigSchema = z
|
|
|
76
78
|
clamAVUrl: z.string(),
|
|
77
79
|
vpcHttpProxy: z.string(),
|
|
78
80
|
alarmSnsTopic: z.string(),
|
|
81
|
+
tags: z.record(z.string(), z.string()),
|
|
79
82
|
} satisfies Record<keyof ReturnType<typeof getEnvVars>, unknown>)
|
|
80
83
|
.strip();
|
|
81
84
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IAspect, Tags } from "aws-cdk-lib";
|
|
2
|
+
import { IConstruct } from "constructs";
|
|
3
|
+
|
|
4
|
+
export class ConditionalTags implements IAspect {
|
|
5
|
+
constructor(
|
|
6
|
+
private getTags: (
|
|
7
|
+
node: IConstruct,
|
|
8
|
+
) => Array<{ key: string; value: string }> | undefined | null,
|
|
9
|
+
) {}
|
|
10
|
+
|
|
11
|
+
visit(node: IConstruct) {
|
|
12
|
+
this.getTags(node)?.forEach(({ key, value }) => {
|
|
13
|
+
Tags.of(node).add(key, value);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Aspects } from "aws-cdk-lib";
|
|
2
|
+
import { IConstruct } from "constructs";
|
|
3
|
+
import { Function } from "sst/constructs";
|
|
4
|
+
import { ConditionalTags } from "./ConditionalTags.js";
|
|
5
|
+
import deployConfig from "../../deployConfig.js";
|
|
6
|
+
|
|
7
|
+
export type ModifyTagsProps = {
|
|
8
|
+
node: IConstruct;
|
|
9
|
+
isLeafNode: boolean;
|
|
10
|
+
isRootNode: boolean;
|
|
11
|
+
currentTags: Array<{ key: string; value: string }>;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type SetupTagsOptions = {
|
|
15
|
+
modifyTags?: (
|
|
16
|
+
props: ModifyTagsProps,
|
|
17
|
+
) => Array<{ key: string; value: string }>;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function setupTags(
|
|
21
|
+
scope: IConstruct,
|
|
22
|
+
{ modifyTags }: SetupTagsOptions = {},
|
|
23
|
+
) {
|
|
24
|
+
const conditionalTags = new ConditionalTags((node) => {
|
|
25
|
+
let tags = [];
|
|
26
|
+
const isLeafNode = node.node.children.length === 0;
|
|
27
|
+
const isRootNode = node === scope;
|
|
28
|
+
|
|
29
|
+
// Add tags from deploy config to all constructs
|
|
30
|
+
if (isRootNode) {
|
|
31
|
+
Object.entries(deployConfig.tags).forEach(([key, value]) => {
|
|
32
|
+
tags.push({ key, value });
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// SST v2's live lambda feature means that the local machine that `sst dev` is run on may use AWS creds that were
|
|
37
|
+
// setup for a lambda. This triggers a false positive in GuardDuty, so we suppress that finding for any lambda that
|
|
38
|
+
// has live dev enabled.
|
|
39
|
+
if (node instanceof Function && node._isLiveDevEnabled) {
|
|
40
|
+
tags.push({ key: "guardduty-suppress", value: "true" });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
tags = modifyTags
|
|
44
|
+
? modifyTags({
|
|
45
|
+
node,
|
|
46
|
+
isLeafNode,
|
|
47
|
+
isRootNode,
|
|
48
|
+
currentTags: tags,
|
|
49
|
+
})
|
|
50
|
+
: tags;
|
|
51
|
+
return tags;
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
Aspects.of(scope).add(conditionalTags);
|
|
55
|
+
}
|