cdk-nag
Version:
Check CDK v2 applications for best practices using a combination on available rule packs.
94 lines • 14.5 kB
JavaScript
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==
;