From 5eac79915285ce3b849b0563ccbfe6d5e609f854 Mon Sep 17 00:00:00 2001 From: Rafael Leite <2132564+leite08@users.noreply.github.com> Date: Mon, 18 Dec 2023 12:28:37 -0600 Subject: [PATCH] build: add DB/RDS ACU alarm Ref: metriport/metriport-internal#1040 --- infra/lib/fhir-server-stack.ts | 127 ++++++++++--------- infra/package-lock.json | 224 ++++++++++++++++++++++++++++----- infra/package.json | 4 +- 3 files changed, 260 insertions(+), 95 deletions(-) diff --git a/infra/lib/fhir-server-stack.ts b/infra/lib/fhir-server-stack.ts index bb0655f01a5..de346e81100 100644 --- a/infra/lib/fhir-server-stack.ts +++ b/infra/lib/fhir-server-stack.ts @@ -318,74 +318,73 @@ export class FHIRServerStack extends Stack { dbClusterName: string, alarmAction?: SnsAction ) { - const memoryMetric = dbCluster.metricFreeableMemory(); - const memoryAlarm = memoryMetric.createAlarm( - this, - `${dbClusterName}FreeableMemoryAlarm`, - { - threshold: mbToBytes(150), - evaluationPeriods: 1, - comparisonOperator: - cloudwatch.ComparisonOperator.LESS_THAN_OR_EQUAL_TO_THRESHOLD, - treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING, - } - ); - alarmAction && memoryAlarm.addAlarmAction(alarmAction); - alarmAction && memoryAlarm.addOkAction(alarmAction); + const createAlarm = ({ + name, + metric, + threshold, + evaluationPeriods, + comparisonOperator, + treatMissingData, + }: { + name: string; + metric: cloudwatch.Metric; + threshold: number; + evaluationPeriods: number; + comparisonOperator?: cloudwatch.ComparisonOperator; + treatMissingData?: cloudwatch.TreatMissingData; + }) => { + const alarm = metric.createAlarm(this, `${dbClusterName}${name}`, { + threshold, + evaluationPeriods, + comparisonOperator, + treatMissingData, + }); + alarmAction && alarm.addAlarmAction(alarmAction); + alarmAction && alarm.addOkAction(alarmAction); + return alarm; + }; - const storageMetric = dbCluster.metricFreeLocalStorage(); - const storageAlarm = storageMetric.createAlarm( - this, - `${dbClusterName}FreeLocalStorageAlarm`, - { - threshold: mbToBytes(250), - evaluationPeriods: 1, - comparisonOperator: - cloudwatch.ComparisonOperator.LESS_THAN_OR_EQUAL_TO_THRESHOLD, - treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING, - } - ); - alarmAction && storageAlarm.addAlarmAction(alarmAction); - alarmAction && storageAlarm.addOkAction(alarmAction); + createAlarm({ + metric: dbCluster.metricFreeableMemory(), + name: "FreeableMemoryAlarm", + threshold: mbToBytes(150), + evaluationPeriods: 1, + comparisonOperator: + cloudwatch.ComparisonOperator.LESS_THAN_OR_EQUAL_TO_THRESHOLD, + treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING, + }); - const cpuMetric = dbCluster.metricCPUUtilization(); - const cpuAlarm = cpuMetric.createAlarm( - this, - `${dbClusterName}CPUUtilizationAlarm`, - { - threshold: 90, // percentage - evaluationPeriods: 1, - treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING, - } - ); - alarmAction && cpuAlarm.addAlarmAction(alarmAction); - alarmAction && cpuAlarm.addOkAction(alarmAction); + createAlarm({ + metric: dbCluster.metricCPUUtilization(), + name: "CPUUtilizationAlarm", + threshold: 90, // percentage + evaluationPeriods: 1, + treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING, + }); - const readIOPsMetric = dbCluster.metricVolumeReadIOPs(); - const readAlarm = readIOPsMetric.createAlarm( - this, - `${dbClusterName}VolumeReadIOPsAlarm`, - { - threshold: 300_000, // IOPS - evaluationPeriods: 1, - treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING, - } - ); - alarmAction && readAlarm.addAlarmAction(alarmAction); - alarmAction && readAlarm.addOkAction(alarmAction); + createAlarm({ + metric: dbCluster.metricVolumeReadIOPs(), + name: "VolumeReadIOPsAlarm", + threshold: 300_000, // IOPS + evaluationPeriods: 1, + treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING, + }); - const writeIOPsMetric = dbCluster.metricVolumeWriteIOPs(); - const writeAlarm = writeIOPsMetric.createAlarm( - this, - `${dbClusterName}VolumeWriteIOPsAlarm`, - { - threshold: 300_000, // IOPS - evaluationPeriods: 1, - treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING, - } - ); - alarmAction && writeAlarm.addAlarmAction(alarmAction); - alarmAction && writeAlarm.addOkAction(alarmAction); + createAlarm({ + metric: dbCluster.metricVolumeWriteIOPs(), + name: "VolumeWriteIOPsAlarm", + threshold: 300_000, // IOPS + evaluationPeriods: 1, + treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING, + }); + + createAlarm({ + metric: dbCluster.metricACUUtilization(), + name: "ACUUtilizationAlarm", + threshold: 80, // pct + evaluationPeriods: 1, + treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING, + }); } } diff --git a/infra/package-lock.json b/infra/package-lock.json index 6e0ab8c20fb..0a155510515 100644 --- a/infra/package-lock.json +++ b/infra/package-lock.json @@ -8,7 +8,7 @@ "name": "infrastructure", "version": "0.1.0", "dependencies": { - "aws-cdk-lib": "2.49.0", + "aws-cdk-lib": "2.87.0", "constructs": "^10.1.144", "source-map-support": "^0.5.21" }, @@ -22,7 +22,7 @@ "@types/prettier": "2.7.1", "@typescript-eslint/eslint-plugin": "^5.48.2", "@typescript-eslint/parser": "^5.48.2", - "aws-cdk": "2.49.0", + "aws-cdk": "2.87.0", "esbuild": "^0.15.12", "eslint": "^8.32.0", "eslint-config-prettier": "^8.6.0", @@ -46,6 +46,21 @@ "node": ">=6.0.0" } }, + "node_modules/@aws-cdk/asset-awscli-v1": { + "version": "2.2.201", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.201.tgz", + "integrity": "sha512-INZqcwDinNaIdb5CtW3ez5s943nX5stGBQS6VOP2JDlOFP81hM3fds/9NDknipqfUkZM43dx+HgVvkXYXXARCQ==" + }, + "node_modules/@aws-cdk/asset-kubectl-v20": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.2.tgz", + "integrity": "sha512-3M2tELJOxQv0apCIiuKQ4pAbncz9GuLwnKFqxifWfe77wuMxyTRPmxssYHs42ePqzap1LT6GDcPygGs+hHstLg==" + }, + "node_modules/@aws-cdk/asset-node-proxy-agent-v5": { + "version": "2.0.166", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v5/-/asset-node-proxy-agent-v5-2.0.166.tgz", + "integrity": "sha512-j0xnccpUQHXJKPgCwQcGGNu4lRiC1PptYfdxBIH1L4dRK91iBxtSQHESRQX+yB47oGLaF/WfNN/aF3WXwlhikg==" + }, "node_modules/@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", @@ -1725,9 +1740,9 @@ } }, "node_modules/aws-cdk": { - "version": "2.49.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.49.0.tgz", - "integrity": "sha512-C+/B8mO85wlKv+/pDtm1OlObIRVaj/XSpWOR31Q6TgxVxJeLnH2K4B/aik+l7yZK45arpUpK2Ka0fvSfTDJvqQ==", + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.87.0.tgz", + "integrity": "sha512-dBm74nl3dMUxoAzgjcfKnzJyoVNIV//B1sqDN11cC3LXEflYapcBxPxZHAyGcRXg5dW3m14dMdKVQfmt4N970g==", "dev": true, "bin": { "cdk": "bin/cdk" @@ -1740,9 +1755,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.49.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.49.0.tgz", - "integrity": "sha512-HMrV41VaYVLFhm5i35bXuxiiib8IXPwuspDF7W3LJ4WVwxQZWx4eGcvRAdaXuNM7dDwM52cF5BNl8lYa/xCt5Q==", + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.87.0.tgz", + "integrity": "sha512-9kirXX7L7OP/yGmCbaYlkt5OAtowGiGw0AYFIQvSwvx/UU3aJO5XuDwAgDsvToDkRpBi0yX0bNwqa0DItu+C6A==", "bundleDependencies": [ "@balena/dockerignore", "case", @@ -1752,17 +1767,22 @@ "minimatch", "punycode", "semver", + "table", "yaml" ], "dependencies": { + "@aws-cdk/asset-awscli-v1": "^2.2.177", + "@aws-cdk/asset-kubectl-v20": "^2.1.1", + "@aws-cdk/asset-node-proxy-agent-v5": "^2.0.148", "@balena/dockerignore": "^1.0.2", "case": "1.6.3", - "fs-extra": "^9.1.0", - "ignore": "^5.2.0", + "fs-extra": "^11.1.1", + "ignore": "^5.2.4", "jsonschema": "^1.4.1", "minimatch": "^3.1.2", - "punycode": "^2.1.1", - "semver": "^7.3.8", + "punycode": "^2.3.0", + "semver": "^7.5.1", + "table": "^6.8.1", "yaml": "1.10.2" }, "engines": { @@ -1777,12 +1797,49 @@ "inBundle": true, "license": "Apache-2.0" }, - "node_modules/aws-cdk-lib/node_modules/at-least-node": { - "version": "1.0.0", + "node_modules/aws-cdk-lib/node_modules/ajv": { + "version": "8.12.0", "inBundle": true, - "license": "ISC", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/aws-cdk-lib/node_modules/ansi-regex": { + "version": "5.0.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/ansi-styles": { + "version": "4.3.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">= 4.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aws-cdk-lib/node_modules/astral-regex": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, "node_modules/aws-cdk-lib/node_modules/balanced-match": { @@ -1807,38 +1864,76 @@ "node": ">= 0.8.0" } }, + "node_modules/aws-cdk-lib/node_modules/color-convert": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/color-name": { + "version": "1.1.4", + "inBundle": true, + "license": "MIT" + }, "node_modules/aws-cdk-lib/node_modules/concat-map": { "version": "0.0.1", "inBundle": true, "license": "MIT" }, + "node_modules/aws-cdk-lib/node_modules/emoji-regex": { + "version": "8.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/fast-deep-equal": { + "version": "3.1.3", + "inBundle": true, + "license": "MIT" + }, "node_modules/aws-cdk-lib/node_modules/fs-extra": { - "version": "9.1.0", + "version": "11.1.1", "inBundle": true, "license": "MIT", "dependencies": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=14.14" } }, "node_modules/aws-cdk-lib/node_modules/graceful-fs": { - "version": "4.2.10", + "version": "4.2.11", "inBundle": true, "license": "ISC" }, "node_modules/aws-cdk-lib/node_modules/ignore": { - "version": "5.2.0", + "version": "5.2.4", "inBundle": true, "license": "MIT", "engines": { "node": ">= 4" } }, + "node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT" + }, "node_modules/aws-cdk-lib/node_modules/jsonfile": { "version": "6.1.0", "inBundle": true, @@ -1858,6 +1953,11 @@ "node": "*" } }, + "node_modules/aws-cdk-lib/node_modules/lodash.truncate": { + "version": "4.4.2", + "inBundle": true, + "license": "MIT" + }, "node_modules/aws-cdk-lib/node_modules/lru-cache": { "version": "6.0.0", "inBundle": true, @@ -1881,15 +1981,23 @@ } }, "node_modules/aws-cdk-lib/node_modules/punycode": { - "version": "2.1.1", + "version": "2.3.0", "inBundle": true, "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/aws-cdk-lib/node_modules/require-from-string": { + "version": "2.0.2", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/aws-cdk-lib/node_modules/semver": { - "version": "7.3.8", + "version": "7.5.2", "inBundle": true, "license": "ISC", "dependencies": { @@ -1902,6 +2010,61 @@ "node": ">=10" } }, + "node_modules/aws-cdk-lib/node_modules/slice-ansi": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/aws-cdk-lib/node_modules/string-width": { + "version": "4.2.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/strip-ansi": { + "version": "6.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/table": { + "version": "6.8.1", + "inBundle": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/aws-cdk-lib/node_modules/universalify": { "version": "2.0.0", "inBundle": true, @@ -1910,6 +2073,14 @@ "node": ">= 10.0.0" } }, + "node_modules/aws-cdk-lib/node_modules/uri-js": { + "version": "4.4.1", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/aws-cdk-lib/node_modules/yallist": { "version": "4.0.0", "inBundle": true, @@ -3348,7 +3519,6 @@ "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, "engines": { "node": ">= 4" } @@ -4741,7 +4911,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, "engines": { "node": ">=6" } @@ -4901,7 +5070,6 @@ "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -4916,7 +5084,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -4927,8 +5094,7 @@ "node_modules/semver/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/shebang-command": { "version": "2.0.0", diff --git a/infra/package.json b/infra/package.json index 6e6ec39a5f0..4ab458e50ef 100644 --- a/infra/package.json +++ b/infra/package.json @@ -19,7 +19,7 @@ "@types/prettier": "2.7.1", "@typescript-eslint/eslint-plugin": "^5.48.2", "@typescript-eslint/parser": "^5.48.2", - "aws-cdk": "2.49.0", + "aws-cdk": "2.87.0", "esbuild": "^0.15.12", "eslint": "^8.32.0", "eslint-config-prettier": "^8.6.0", @@ -30,7 +30,7 @@ "typescript": "~4.8.4" }, "dependencies": { - "aws-cdk-lib": "2.49.0", + "aws-cdk-lib": "2.87.0", "constructs": "^10.1.144", "source-map-support": "^0.5.21" }