@linzjs/cdk-tags 1.15.0 → 1.16.0
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
CHANGED
|
@@ -29,7 +29,9 @@ applyTags(bucket, {
|
|
|
29
29
|
});
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
> Set `backup.multiRegionCopy: true` to declare
|
|
32
|
+
> Set `backup.multiRegionCopy: true` to declare that the backups have to be available in second region. (tag applied: `linz.backup.multiRegionCopy`, default: `false`).
|
|
33
|
+
|
|
34
|
+
> Set `backup.multiAccountCopy: true` to declare that the backups have to be available in a logically air-gapped (LAG) vault shared by the central audit account. Backups stored in the LAG vault cannot be deleted prior to the completion of the retention period, hence the retention period cannot be more than 30 days, and backup schedule must be daily or less.
|
|
33
35
|
|
|
34
36
|
To apply the common set of tags for multiple constructs:
|
|
35
37
|
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
3
7
|
const node_test_1 = require("node:test");
|
|
4
8
|
const backup_js_1 = require("../backup.js");
|
|
5
9
|
const security_js_1 = require("../security.js");
|
|
@@ -15,7 +19,7 @@ const tags_js_1 = require("../tags.js");
|
|
|
15
19
|
data: { isMaster: true, isPublic: true, role: 'archive' },
|
|
16
20
|
impact: 'moderate',
|
|
17
21
|
backup: {
|
|
18
|
-
retention:
|
|
22
|
+
retention: 30,
|
|
19
23
|
schedule: backup_js_1.BackupSchedule.WEEKLY,
|
|
20
24
|
multiRegionCopy: true,
|
|
21
25
|
multiAccountCopy: true,
|
|
@@ -25,5 +29,71 @@ const tags_js_1 = require("../tags.js");
|
|
|
25
29
|
},
|
|
26
30
|
});
|
|
27
31
|
});
|
|
32
|
+
(0, node_test_1.it)('should throw error if retention period is negative', () => {
|
|
33
|
+
node_assert_1.default.throws(() => {
|
|
34
|
+
(0, tags_js_1.applyTags)({}, {
|
|
35
|
+
application: 'basemaps',
|
|
36
|
+
environment: 'prod',
|
|
37
|
+
group: 'li',
|
|
38
|
+
classification: security_js_1.SecurityClassification.Unclassified,
|
|
39
|
+
impact: 'moderate',
|
|
40
|
+
backup: {
|
|
41
|
+
retention: -1,
|
|
42
|
+
schedule: backup_js_1.BackupSchedule.WEEKLY,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}, (error) => {
|
|
46
|
+
return error.message.includes('Backup retention must be a positive number');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
(0, node_test_1.it)('should throw error if retention period is 365 days when multi-account copy is enabled', () => {
|
|
50
|
+
node_assert_1.default.throws(() => {
|
|
51
|
+
(0, tags_js_1.applyTags)({}, {
|
|
52
|
+
application: 'basemaps',
|
|
53
|
+
environment: 'prod',
|
|
54
|
+
group: 'li',
|
|
55
|
+
classification: security_js_1.SecurityClassification.Unclassified,
|
|
56
|
+
impact: 'moderate',
|
|
57
|
+
backup: {
|
|
58
|
+
retention: 365,
|
|
59
|
+
schedule: backup_js_1.BackupSchedule.WEEKLY,
|
|
60
|
+
multiAccountCopy: true,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}, (error) => {
|
|
64
|
+
return error.message.includes('Backup retention must be 30 days or less when using multi-account copy');
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
(0, node_test_1.it)('should throw error if backup schedule is hourly when multi-account copy is enabled', () => {
|
|
68
|
+
node_assert_1.default.throws(() => {
|
|
69
|
+
(0, tags_js_1.applyTags)({}, {
|
|
70
|
+
application: 'basemaps',
|
|
71
|
+
environment: 'prod',
|
|
72
|
+
group: 'li',
|
|
73
|
+
classification: security_js_1.SecurityClassification.Unclassified,
|
|
74
|
+
impact: 'moderate',
|
|
75
|
+
backup: {
|
|
76
|
+
retention: 30,
|
|
77
|
+
schedule: backup_js_1.BackupSchedule.HOURLY,
|
|
78
|
+
multiAccountCopy: true,
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
}, (error) => {
|
|
82
|
+
return error.message.includes('Backup schedule must be one of');
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
(0, node_test_1.it)('should apply tags if tagging hourly backup for 365 days, when multi-account copy is not enabled', () => {
|
|
86
|
+
(0, tags_js_1.applyTags)({}, {
|
|
87
|
+
application: 'basemaps',
|
|
88
|
+
environment: 'prod',
|
|
89
|
+
group: 'li',
|
|
90
|
+
classification: security_js_1.SecurityClassification.Unclassified,
|
|
91
|
+
impact: 'moderate',
|
|
92
|
+
backup: {
|
|
93
|
+
retention: 365,
|
|
94
|
+
schedule: backup_js_1.BackupSchedule.HOURLY,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
});
|
|
28
98
|
});
|
|
29
99
|
//# sourceMappingURL=tags.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags.test.js","sourceRoot":"","sources":["../../../src/__test__/tags.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tags.test.js","sourceRoot":"","sources":["../../../src/__test__/tags.test.ts"],"names":[],"mappings":"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"}
|
package/build/src/backup.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface Backup {
|
|
|
21
21
|
multiRegionCopy?: boolean;
|
|
22
22
|
/**
|
|
23
23
|
* Should this resource be copied to a central backup vault shared by other accounts
|
|
24
|
+
*
|
|
25
|
+
* Note that the central backup vault is logically air-gapped, so the backup copies cannot be deleted prior to the completion of the retention period.
|
|
24
26
|
* @defaultValue false
|
|
25
27
|
*/
|
|
26
28
|
multiAccountCopy?: boolean;
|
package/build/src/tags.js
CHANGED
|
@@ -6,10 +6,15 @@ exports.applyTagsData = applyTagsData;
|
|
|
6
6
|
exports.applyTagsBackup = applyTagsBackup;
|
|
7
7
|
exports.applyTagsLogStreaming = applyTagsLogStreaming;
|
|
8
8
|
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
9
|
+
const backup_js_1 = require("./backup.js");
|
|
9
10
|
const build_js_1 = require("./build.js");
|
|
10
11
|
const constants_js_1 = require("./constants.js");
|
|
11
12
|
const security_js_1 = require("./security.js");
|
|
12
13
|
exports.Impacts = ['significant', 'moderate', 'minor'];
|
|
14
|
+
const DefaultBackupRetentionDays = 30;
|
|
15
|
+
const DefaultBackupSchedule = backup_js_1.BackupSchedule.DAILY;
|
|
16
|
+
const CentralLagVaultMaxRetentionDays = 30;
|
|
17
|
+
const CentralLagVaultAllowedBackupSchedules = [backup_js_1.BackupSchedule.DAILY, backup_js_1.BackupSchedule.WEEKLY];
|
|
13
18
|
// Apply a tag but skip application of tag if the value is undefined or empty
|
|
14
19
|
function tag(construct, key, value) {
|
|
15
20
|
if (value == null)
|
|
@@ -18,6 +23,19 @@ function tag(construct, key, value) {
|
|
|
18
23
|
return;
|
|
19
24
|
aws_cdk_lib_1.Tags.of(construct).add(key, value);
|
|
20
25
|
}
|
|
26
|
+
function validateBackupTags(tags) {
|
|
27
|
+
if (tags.retention !== undefined && tags.retention < 0) {
|
|
28
|
+
throw new Error('Backup retention must be a positive number');
|
|
29
|
+
}
|
|
30
|
+
if (tags.multiAccountCopy === true) {
|
|
31
|
+
if ((tags.retention ?? DefaultBackupRetentionDays) > CentralLagVaultMaxRetentionDays) {
|
|
32
|
+
throw new Error(`Backup retention must be ${CentralLagVaultMaxRetentionDays} days or less when using multi-account copy`);
|
|
33
|
+
}
|
|
34
|
+
if (!CentralLagVaultAllowedBackupSchedules.includes(tags.schedule ?? DefaultBackupSchedule)) {
|
|
35
|
+
throw new Error(`Backup schedule must be one of ${CentralLagVaultAllowedBackupSchedules.join(', ')} when using multi-account copy`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
21
39
|
function applyTags(construct, ctx) {
|
|
22
40
|
// TODO is this check valid here?
|
|
23
41
|
if (ctx.data?.isPublic && ctx.classification !== security_js_1.SecurityClassification.Unclassified) {
|
|
@@ -61,11 +79,16 @@ function applyTagsData(construct, tags) {
|
|
|
61
79
|
}
|
|
62
80
|
// Backup tags
|
|
63
81
|
function applyTagsBackup(construct, tags) {
|
|
82
|
+
validateBackupTags(tags);
|
|
64
83
|
tag(construct, constants_js_1.TagKeys.BACKUP_ENABLED, String(true));
|
|
65
|
-
tag(construct, constants_js_1.TagKeys.BACKUP_RETENTION, String(tags.retention ??
|
|
66
|
-
tag(construct, constants_js_1.TagKeys.BACKUP_SCHEDULE, String(tags.schedule ??
|
|
67
|
-
|
|
68
|
-
|
|
84
|
+
tag(construct, constants_js_1.TagKeys.BACKUP_RETENTION, String(tags.retention ?? DefaultBackupRetentionDays));
|
|
85
|
+
tag(construct, constants_js_1.TagKeys.BACKUP_SCHEDULE, String(tags.schedule ?? DefaultBackupSchedule));
|
|
86
|
+
if (tags.multiRegionCopy !== undefined) {
|
|
87
|
+
tag(construct, constants_js_1.TagKeys.BACKUP_MULTIREGION, String(tags.multiRegionCopy));
|
|
88
|
+
}
|
|
89
|
+
if (tags.multiAccountCopy !== undefined) {
|
|
90
|
+
tag(construct, constants_js_1.TagKeys.BACKUP_MULTIACCOUNT, String(tags.multiAccountCopy));
|
|
91
|
+
}
|
|
69
92
|
}
|
|
70
93
|
// Streaming logs
|
|
71
94
|
function applyTagsLogStreaming(construct, tags) {
|
package/build/src/tags.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/tags.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/tags.ts"],"names":[],"mappings":"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"}
|