UNPKG

cdk-nag

Version:

Check CDK v2 applications for best practices using a combination on available rule packs.

94 lines 14.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ const path_1 = require("path"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const aws_applicationautoscaling_1 = require("aws-cdk-lib/aws-applicationautoscaling"); const aws_dynamodb_1 = require("aws-cdk-lib/aws-dynamodb"); const nag_rules_1 = require("../../nag-rules"); /** * Provisioned capacity DynamoDB tables have auto-scaling enabled on their indexes * @param node the CfnResource to check */ exports.default = Object.defineProperty((node) => { if (node instanceof aws_dynamodb_1.CfnTable) { if (nag_rules_1.NagRules.resolveResourceFromInstrinsic(node, node.billingMode) !== aws_dynamodb_1.BillingMode.PAY_PER_REQUEST) { const indexWriteMatches = ['']; const indexReadMatches = ['']; const tableLogicalId = nag_rules_1.NagRules.resolveResourceFromInstrinsic(node, node.ref); const tableName = aws_cdk_lib_1.Stack.of(node).resolve(node.tableName); const globalSecondaryIndexes = aws_cdk_lib_1.Stack.of(node).resolve(node.globalSecondaryIndexes); if (Array.isArray(globalSecondaryIndexes)) { globalSecondaryIndexes.forEach((gsi) => { const resolvedGsi = aws_cdk_lib_1.Stack.of(node).resolve(gsi); indexWriteMatches.push(resolvedGsi.indexName); indexReadMatches.push(resolvedGsi.indexName); }); } for (const child of aws_cdk_lib_1.Stack.of(node).node.findAll()) { if (child instanceof aws_applicationautoscaling_1.CfnScalableTarget) { const writeMatchIndex = isMatchingScalableTarget(child, 'WriteCapacityUnits', tableLogicalId, tableName, indexWriteMatches); if (writeMatchIndex !== -1) { indexWriteMatches.splice(writeMatchIndex, 1); continue; } const readMatchIndex = isMatchingScalableTarget(child, 'ReadCapacityUnits', tableLogicalId, tableName, indexReadMatches); if (readMatchIndex !== -1) { indexReadMatches.splice(readMatchIndex, 1); } } } if (indexWriteMatches.length != 0 || indexReadMatches.length != 0) { return nag_rules_1.NagRuleCompliance.NON_COMPLIANT; } } return nag_rules_1.NagRuleCompliance.COMPLIANT; } else { return nag_rules_1.NagRuleCompliance.NOT_APPLICABLE; } }, 'name', { value: path_1.parse(__filename).name }); /** * Helper function to check whether the CfnScalableTarget is related to the given Table index * @param node the CfnScalableTarget to check * @param dimension the dimension of the CfnScalableTarget to check * @param tableLogicalId the Cfn Logical ID of the table * @param tableName the name of the table * @param indexNames the names of the indexes to check against * returns the location in the indexNames array of the matching index or -1 if no match is found */ function isMatchingScalableTarget(node, dimension, tableLogicalId, tableName, indexNames) { if (node.serviceNamespace === 'dynamodb') { let scalableDimension = ''; const resourceId = JSON.stringify(aws_cdk_lib_1.Stack.of(node).resolve(node.resourceId)); for (let i = 0; i < indexNames.length; i++) { const regexes = Array(); const indexName = indexNames[i]; if (indexName === '') { regexes.push(`${tableLogicalId}.*`); if (tableName !== undefined) { regexes.push(`${tableName}.*`); } scalableDimension = `dynamodb:table:${dimension}`; } else { regexes.push(`${tableLogicalId}.*index\/${indexName}(?![\\w\\-_\\.])`); if (tableName !== undefined) { regexes.push(`${tableName}.*index\/${indexName}(?![\\w\\-_\\.])`); } scalableDimension = `dynamodb:index:${dimension}`; } const regex = new RegExp(regexes.join('|'), 'gm'); if (node.scalableDimension === scalableDimension && regex.test(resourceId)) { return i; } } } return -1; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRHluYW1vREJBdXRvU2NhbGluZ0VuYWJsZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcnVsZXMvZHluYW1vZGIvRHluYW1vREJBdXRvU2NhbGluZ0VuYWJsZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQTs7O0VBR0U7QUFDRiwrQkFBNkI7QUFDN0IsNkNBQWlEO0FBQ2pELHVGQUEyRTtBQUMzRSwyREFBaUU7QUFDakUsK0NBQThEO0FBRTlEOzs7R0FHRztBQUVILGtCQUFlLE1BQU0sQ0FBQyxjQUFjLENBQ2xDLENBQUMsSUFBaUIsRUFBcUIsRUFBRTtJQUN2QyxJQUFJLElBQUksWUFBWSx1QkFBUSxFQUFFO1FBQzVCLElBQ0Usb0JBQVEsQ0FBQyw2QkFBNkIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQztZQUM5RCwwQkFBVyxDQUFDLGVBQWUsRUFDM0I7WUFDQSxNQUFNLGlCQUFpQixHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDL0IsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzlCLE1BQU0sY0FBYyxHQUFHLG9CQUFRLENBQUMsNkJBQTZCLENBQzNELElBQUksRUFDSixJQUFJLENBQUMsR0FBRyxDQUNULENBQUM7WUFDRixNQUFNLFNBQVMsR0FBRyxtQkFBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3pELE1BQU0sc0JBQXNCLEdBQUcsbUJBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUNuRCxJQUFJLENBQUMsc0JBQXNCLENBQzVCLENBQUM7WUFDRixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsc0JBQXNCLENBQUMsRUFBRTtnQkFDekMsc0JBQXNCLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7b0JBQ3JDLE1BQU0sV0FBVyxH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LElBQUksQ0FBQyxHQUFHLFNBQVMsWUFBWSxTQUFTLGtCQUFrQixDQUFDLENBQUM7aUJBQ25FO2dCQUNELGlCQUFpQixHQUFHLGtCQUFrQixTQUFTLEVBQUUsQ0FBQzthQUNuRDtZQUNELE1BQU0sS0FBSyxHQUFHLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDbEQsSUFDRSxJQUFJLENBQUMsaUJBQWlCLEtBQUssaUJBQWlCO2dCQUM1QyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUN0QjtnQkFDQSxPQUFPLENBQUMsQ0FBQzthQUNWO1NBQ0Y7S0FDRjtJQUNELE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDWixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbiovXG5pbXBvcnQgeyBwYXJzZSB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQ2ZuUmVzb3VyY2UsIFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQ2ZuU2NhbGFibGVUYXJnZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtYXBwbGljYXRpb25hdXRvc2NhbGluZyc7XG5pbXBvcnQgeyBDZm5UYWJsZSwgQmlsbGluZ01vZGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZHluYW1vZGInO1xuaW1wb3J0IHsgTmFnUnVsZUNvbXBsaWFuY2UsIE5hZ1J1bGVzIH0gZnJvbSAnLi4vLi4vbmFnLXJ1bGVzJztcblxuLyoqXG4gKiBQcm92aXNpb25lZCBjYXBhY2l0eSBEeW5hbW9EQiB0YWJsZXMgaGF2ZSBhdXRvLXNjYWxpbmcgZW5hYmxlZCBvbiB0aGVpciBpbmRleGVzXG4gKiBAcGFyYW0gbm9kZSB0aGUgQ2ZuUmVzb3VyY2UgdG8gY2hlY2tcbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBPYmplY3QuZGVmaW5lUHJvcGVydHkoXG4gIChub2RlOiBDZm5SZXNvdXJjZSk6IE5hZ1J1bGVDb21wbGlhbmNlID0+IHtcbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIENmblRhYmxlKSB7XG4gICAgICBpZiAoXG4gICAgICAgIE5hZ1J1bGVzLnJlc29sdmVSZXNvdXJjZUZyb21JbnN0cmluc2ljKG5vZGUsIG5vZGUuYmlsbGluZ01vZGUpICE9PVxuICAgICAgICBCaWxsaW5nTW9kZS5QQVlfUEVSX1JFUVVFU1RcbiAgICAgICkge1xuICAgICAgICBjb25zdCBpbmRleFdyaXRlTWF0Y2hlcyA9IFsnJ107XG4gICAgICAgIGNvbnN0IGluZGV4UmVhZE1hdGNoZXMgPSBbJyddO1xuICAgICAgICBjb25zdCB0YWJsZUxvZ2ljYWxJZCA9IE5hZ1J1bGVzLnJlc29sdmVSZXNvdXJjZUZyb21JbnN0cmluc2ljKFxuICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgbm9kZS5yZWZcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgdGFibGVOYW1lID0gU3RhY2sub2Yobm9kZSkucmVzb2x2ZShub2RlLnRhYmxlTmFtZSk7XG4gICAgICAgIGNvbnN0IGdsb2JhbFNlY29uZGFyeUluZGV4ZXMgPSBTdGFjay5vZihub2RlKS5yZXNvbHZlKFxuICAgICAgICAgIG5vZGUuZ2xvYmFsU2Vjb25kYXJ5SW5kZXhlc1xuICAgICAgICApO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShnbG9iYWxTZWNvbmRhcnlJbmRleGVzKSkge1xuICAgICAgICAgIGdsb2JhbFNlY29uZGFyeUluZGV4ZXMuZm9yRWFjaCgoZ3NpKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlZEdzaSA9IFN0YWNrLm9mKG5vZGUpLnJlc29sdmUoZ3NpKTtcbiAgICAgICAgICAgIGluZGV4V3JpdGVNYXRjaGVzLnB1c2gocmVzb2x2ZWRHc2kuaW5kZXhOYW1lKTtcbiAgICAgICAgICAgIGluZGV4UmVhZE1hdGNoZXMucHVzaChyZXNvbHZlZEdzaS5pbmRleE5hbWUpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgU3RhY2sub2Yobm9kZSkubm9kZS5maW5kQWxsKCkpIHtcbiAgICAgICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBDZm5TY2FsYWJsZVRhcmdldCkge1xuICAgICAgICAgICAgY29uc3Qgd3JpdGVNYXRjaEluZGV4ID0gaXNNYXRjaGluZ1NjYWxhYmxlVGFyZ2V0KFxuICAgICAgICAgICAgICBjaGlsZCxcbiAgICAgICAgICAgICAgJ1dyaXRlQ2FwYWNpdHlVbml0cycsXG4gICAgICAgICAgICAgIHRhYmxlTG9naWNhbElkLFxuICAgICAgICAgICAgICB0YWJsZU5hbWUsXG4gICAgICAgICAgICAgIGluZGV4V3JpdGVNYXRjaGVzXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHdyaXRlTWF0Y2hJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgaW5kZXhXcml0ZU1hdGNoZXMuc3BsaWNlKHdyaXRlTWF0Y2hJbmRleCwgMSk7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmVhZE1hdGNoSW5kZXggPSBpc01hdGNoaW5nU2NhbGFibGVUYXJnZXQoXG4gICAgICAgICAgICAgIGNoaWxkLFxuICAgICAgICAgICAgICAnUmVhZENhcGFjaXR5VW5pdHMnLFxuICAgICAgICAgICAgICB0YWJsZUxvZ2ljYWxJZCxcbiAgICAgICAgICAgICAgdGFibGVOYW1lLFxuICAgICAgICAgICAgICBpbmRleFJlYWRNYXRjaGVzXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHJlYWRNYXRjaEluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICBpbmRleFJlYWRNYXRjaGVzLnNwbGljZShyZWFkTWF0Y2hJbmRleCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpbmRleFdyaXRlTWF0Y2hlcy5sZW5ndGggIT0gMCB8fCBpbmRleFJlYWRNYXRjaGVzLmxlbmd0aCAhPSAwKSB7XG4gICAgICAgICAgcmV0dXJuIE5hZ1J1bGVDb21wbGlhbmNlLk5PTl9DT01QTElBTlQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBOYWdSdWxlQ29tcGxpYW5jZS5DT01QTElBTlQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBOYWdSdWxlQ29tcGxpYW5jZS5OT1RfQVBQTElDQUJMRTtcbiAgICB9XG4gIH0sXG4gICduYW1lJyxcbiAgeyB2YWx1ZTogcGFyc2UoX19maWxlbmFtZSkubmFtZSB9XG4pO1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBjaGVjayB3aGV0aGVyIHRoZSBDZm5TY2FsYWJsZVRhcmdldCBpcyByZWxhdGVkIHRvIHRoZSBnaXZlbiBUYWJsZSBpbmRleFxuICogQHBhcmFtIG5vZGUgdGhlIENmblNjYWxhYmxlVGFyZ2V0IHRvIGNoZWNrXG4gKiBAcGFyYW0gZGltZW5zaW9uIHRoZSBkaW1lbnNpb24gb2YgdGhlIENmblNjYWxhYmxlVGFyZ2V0IHRvIGNoZWNrXG4gKiBAcGFyYW0gdGFibGVMb2dpY2FsSWQgdGhlIENmbiBMb2dpY2FsIElEIG9mIHRoZSB0YWJsZVxuICogQHBhcmFtIHRhYmxlTmFtZSB0aGUgbmFtZSBvZiB0aGUgdGFibGVcbiAqIEBwYXJhbSBpbmRleE5hbWVzIHRoZSBuYW1lcyBvZiB0aGUgaW5kZXhlcyB0byBjaGVjayBhZ2FpbnN0XG4gKiByZXR1cm5zIHRoZSBsb2NhdGlvbiBpbiB0aGUgaW5kZXhOYW1lcyBhcnJheSBvZiB0aGUgbWF0Y2hpbmcgaW5kZXggb3IgLTEgaWYgbm8gbWF0Y2ggaXMgZm91bmRcbiAqL1xuZnVuY3Rpb24gaXNNYXRjaGluZ1NjYWxhYmxlVGFyZ2V0KFxuICBub2RlOiBDZm5TY2FsYWJsZVRhcmdldCxcbiAgZGltZW5zaW9uOiBzdHJpbmcsXG4gIHRhYmxlTG9naWNhbElkOiBzdHJpbmcsXG4gIHRhYmxlTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICBpbmRleE5hbWVzOiBzdHJpbmdbXVxuKTogbnVtYmVyIHtcbiAgaWYgKG5vZGUuc2VydmljZU5hbWVzcGFjZSA9PT0gJ2R5bmFtb2RiJykge1xuICAgIGxldCBzY2FsYWJsZURpbWVuc2lvbiA9ICcnO1xuICAgIGNvbnN0IHJlc291cmNlSWQgPSBKU09OLnN0cmluZ2lmeShTdGFjay5vZihub2RlKS5yZXNvbHZlKG5vZGUucmVzb3VyY2VJZCkpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kZXhOYW1lcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcmVnZXhlcyA9IEFycmF5PHN0cmluZz4oKTtcbiAgICAgIGNvbnN0IGluZGV4TmFtZSA9IGluZGV4TmFtZXNbaV07XG4gICAgICBpZiAoaW5kZXhOYW1lID09PSAnJykge1xuICAgICAgICByZWdleGVzLnB1c2goYCR7dGFibGVMb2dpY2FsSWR9LipgKTtcbiAgICAgICAgaWYgKHRhYmxlTmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmVnZXhlcy5wdXNoKGAke3RhYmxlTmFtZX0uKmApO1xuICAgICAgICB9XG4gICAgICAgIHNjYWxhYmxlRGltZW5zaW9uID0gYGR5bmFtb2RiOnRhYmxlOiR7ZGltZW5zaW9ufWA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZWdleGVzLnB1c2goYCR7dGFibGVMb2dpY2FsSWR9LippbmRleFxcLyR7aW5kZXhOYW1lfSg/IVtcXFxcd1xcXFwtX1xcXFwuXSlgKTtcbiAgICAgICAgaWYgKHRhYmxlTmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmVnZXhlcy5wdXNoKGAke3RhYmxlTmFtZX0uKmluZGV4XFwvJHtpbmRleE5hbWV9KD8hW1xcXFx3XFxcXC1fXFxcXC5dKWApO1xuICAgICAgICB9XG4gICAgICAgIHNjYWxhYmxlRGltZW5zaW9uID0gYGR5bmFtb2RiOmluZGV4OiR7ZGltZW5zaW9ufWA7XG4gICAgICB9XG4gICAgICBjb25zdCByZWdleCA9IG5ldyBSZWdFeHAocmVnZXhlcy5qb2luKCd8JyksICdnbScpO1xuICAgICAgaWYgKFxuICAgICAgICBub2RlLnNjYWxhYmxlRGltZW5zaW9uID09PSBzY2FsYWJsZURpbWVuc2lvbiAmJlxuICAgICAgICByZWdleC50ZXN0KHJlc291cmNlSWQpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cbiJdfQ==