UNPKG

aws-delivlib

Version:

A fabulous library for defining continuous pipelines for building, testing and releasing code libraries.

94 lines 11.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PipelineWatcher = void 0; const path = __importStar(require("path")); const aws_cdk_lib_1 = require("aws-cdk-lib"); const constructs_1 = require("constructs"); /** * Construct which watches a Code Pipeline for failed stages and raises an alarm * if there are any failed stages. * * A function runs every minute and calls GetPipelineState for the provided pipeline's * name, counts the number of failed stages and emits a JSON log { failedCount: <number> }. * A metric filter is then configured to track this value as a CloudWatch metric, and * a corresponding alarm is set to fire when the maximim value of a single 5-minute interval * is >= 1. */ class PipelineWatcher extends constructs_1.Construct { constructor(parent, name, props) { super(parent, name); const pipelineWatcher = new aws_cdk_lib_1.aws_lambda.Function(this, 'Poller', { handler: 'watcher-handler.handler', runtime: aws_cdk_lib_1.aws_lambda.Runtime.NODEJS_20_X, code: aws_cdk_lib_1.aws_lambda.Code.fromAsset(path.join(__dirname, 'handler')), environment: { METRIC_NAMESPACE: props.metricNamespace, METRIC_NAME: props.failureMetricName, }, }); pipelineWatcher.addToRolePolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({ resources: ['*'], actions: ['cloudwatch:PutMetricData'], conditions: { StringEquals: { 'cloudwatch:namespace': props.metricNamespace, }, }, })); new aws_cdk_lib_1.aws_events.Rule(this, 'Trigger', { eventPattern: { source: ['aws.codepipeline'], resources: [props.pipeline.pipelineArn], detailType: [ 'CodePipeline Action Execution State Change', 'CodePipeline Pipeline Execution State Change', ], detail: { state: ['FAILED', 'SUCCEEDED'], }, }, targets: [new aws_cdk_lib_1.aws_events_targets.LambdaFunction(pipelineWatcher)], }); this.alarm = new aws_cdk_lib_1.aws_cloudwatch.Alarm(this, 'Alarm', { alarmDescription: `Pipeline ${props.title || props.pipeline.pipelineName} has failed stages`, metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({ metricName: props.failureMetricName, namespace: props.metricNamespace, statistic: aws_cdk_lib_1.aws_cloudwatch.Statistic.MAXIMUM, dimensionsMap: { Pipeline: props.pipeline.pipelineName, }, }), threshold: 1, comparisonOperator: aws_cdk_lib_1.aws_cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD, evaluationPeriods: 1, // IGNORE missing data, so the alarm stays in its current state, until the next data point. treatMissingData: aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.IGNORE, }); } } exports.PipelineWatcher = PipelineWatcher; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F0Y2hlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndhdGNoZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBNkI7QUFDN0IsNkNBT3FCO0FBQ3JCLDJDQUF1QztBQTRCdkM7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBYSxlQUFnQixTQUFRLHNCQUFTO0lBRzVDLFlBQVksTUFBaUIsRUFBRSxJQUFZLEVBQUUsS0FBMkI7UUFDdEUsS0FBSyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUVwQixNQUFNLGVBQWUsR0FBRyxJQUFJLHdCQUFNLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUU7WUFDMUQsT0FBTyxFQUFFLHlCQUF5QjtZQUNsQyxPQUFPLEVBQUUsd0JBQU0sQ0FBQyxPQUFPLENBQUMsV0FBVztZQUNuQyxJQUFJLEVBQUUsd0JBQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQzVELFdBQVcsRUFBRTtnQkFDWCxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsZUFBZTtnQkFDdkMsV0FBVyxFQUFFLEtBQUssQ0FBQyxpQkFBaUI7YUFDckM7U0FDRixDQUFDLENBQUM7UUFFSCxlQUFlLENBQUMsZUFBZSxDQUFDLElBQUkscUJBQUcsQ0FBQyxlQUFlLENBQUM7WUFDdEQsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO1lBQ2hCLE9BQU8sRUFBRSxDQUFDLDBCQUEwQixDQUFDO1lBQ3JDLFVBQVUsRUFBRTtnQkFDVixZQUFZLEVBQUU7b0JBQ1osc0JBQXNCLEVBQUUsS0FBSyxDQUFDLGVBQWU7aUJBQzlDO2FBQ0Y7U0FDRixDQUFDLENBQUMsQ0FBQztRQUVKLElBQUksd0JBQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRTtZQUMvQixZQUFZLEVBQUU7Z0JBQ1osTUFBTSxFQUFFLENBQUMsa0JBQWtCLENBQUM7Z0JBQzVCLFNBQVMsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDO2dCQUN2QyxVQUFVLEVBQUU7b0JBQ1YsNENBQTRDO29CQUM1Qyw4Q0FBOEM7aUJBQy9DO2dCQUNELE1BQU0sRUFBRTtvQkFDTixLQUFLLEVBQUUsQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDO2lCQUMvQjthQUNGO1lBQ0QsT0FBTyxFQUFFLENBQUMsSUFBSSxnQ0FBYyxDQUFDLGNBQWMsQ0FBQyxlQUFlLENBQUMsQ0FBQztTQUM5RCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksNEJBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRTtZQUMvQyxnQkFBZ0IsRUFBRSxZQUFZLEtBQUssQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxZQUFZLG9CQUFvQjtZQUM1RixNQUFNLEVBQUUsSUFBSSw0QkFBVSxDQUFDLE1BQU0sQ0FBQztnQkFDNUIsVUFBVSxFQUFFLEtBQUssQ0FBQyxpQkFBaUI7Z0JBQ25DLFNBQVMsRUFBRSxLQUFLLENBQUMsZUFBZTtnQkFDaEMsU0FBUyxFQUFFLDRCQUFVLENBQUMsU0FBUyxDQUFDLE9BQU87Z0JBQ3ZDLGFBQWEsRUFBRTtvQkFDYixRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxZQUFZO2lCQUN0QzthQUNGLENBQUM7WUFDRixTQUFTLEVBQUUsQ0FBQztZQUNaLGtCQUFrQixFQUFFLDRCQUFVLENBQUMsa0JBQWtCLENBQUMsa0NBQWtDO1lBQ3BGLGlCQUFpQixFQUFFLENBQUM7WUFDcEIsMkZBQTJGO1lBQzNGLGdCQUFnQixFQUFFLDRCQUFVLENBQUMsZ0JBQWdCLENBQUMsTUFBTTtTQUNyRCxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUExREQsMENBMERDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7XG4gIGF3c19jbG91ZHdhdGNoIGFzIGNsb3Vkd2F0Y2gsXG4gIGF3c19jb2RlcGlwZWxpbmUgYXMgY3BpcGVsaW5lLFxuICBhd3NfZXZlbnRzIGFzIGV2ZW50cyxcbiAgYXdzX2V2ZW50c190YXJnZXRzIGFzIGV2ZW50c190YXJnZXRzLFxuICBhd3NfaWFtIGFzIGlhbSxcbiAgYXdzX2xhbWJkYSBhcyBsYW1iZGEsXG59IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBpcGVsaW5lV2F0Y2hlclByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBDbG91ZFdhdGNoIG1ldHJpYyBuYW1lc3BhY2UgdG8gd2hpY2ggbWV0cmljcyBzaG91bGQgYmUgc2VudFxuICAgKi9cbiAgbWV0cmljTmFtZXNwYWNlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBDbG91ZFdhdGNoIG1ldHJpYyBuYW1lIGZvciBmYWlsdXJlcy5cbiAgICovXG4gIGZhaWx1cmVNZXRyaWNOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENvZGUgUGlwZWxpbmUgdG8gbW9uaXRvciBmb3IgZmFpbGVkIHN0YWdlc1xuICAgKi9cbiAgcGlwZWxpbmU6IGNwaXBlbGluZS5JUGlwZWxpbmU7XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgcGlwZWxpbmVOYW1lIG9mIHRoZSBhbGFybSBkZXNjcmlwdGlvbi5cbiAgICpcbiAgICogRGVzY3JpcHRpb24gaXMgc2V0IHRvICdQaXBlbGluZSA8dGl0bGU+IGhhcyBmYWlsZWQgc3RhZ2VzJ1xuICAgKlxuICAgKiBAZGVmYXVsdCBwaXBlbGluZSdzIG5hbWVcbiAgICovXG4gIHRpdGxlPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdCB3aGljaCB3YXRjaGVzIGEgQ29kZSBQaXBlbGluZSBmb3IgZmFpbGVkIHN0YWdlcyBhbmQgcmFpc2VzIGFuIGFsYXJtXG4gKiBpZiB0aGVyZSBhcmUgYW55IGZhaWxlZCBzdGFnZXMuXG4gKlxuICogQSBmdW5jdGlvbiBydW5zIGV2ZXJ5IG1pbnV0ZSBhbmQgY2FsbHMgR2V0UGlwZWxpbmVTdGF0ZSBmb3IgdGhlIHByb3ZpZGVkIHBpcGVsaW5lJ3NcbiAqIG5hbWUsIGNvdW50cyB0aGUgbnVtYmVyIG9mIGZhaWxlZCBzdGFnZXMgYW5kIGVtaXRzIGEgSlNPTiBsb2cgeyBmYWlsZWRDb3VudDogPG51bWJlcj4gfS5cbiAqIEEgbWV0cmljIGZpbHRlciBpcyB0aGVuIGNvbmZpZ3VyZWQgdG8gdHJhY2sgdGhpcyB2YWx1ZSBhcyBhIENsb3VkV2F0Y2ggbWV0cmljLCBhbmRcbiAqIGEgY29ycmVzcG9uZGluZyBhbGFybSBpcyBzZXQgdG8gZmlyZSB3aGVuIHRoZSBtYXhpbWltIHZhbHVlIG9mIGEgc2luZ2xlIDUtbWludXRlIGludGVydmFsXG4gKiBpcyA+PSAxLlxuICovXG5leHBvcnQgY2xhc3MgUGlwZWxpbmVXYXRjaGVyIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgcHVibGljIHJlYWRvbmx5IGFsYXJtOiBjbG91ZHdhdGNoLkFsYXJtO1xuXG4gIGNvbnN0cnVjdG9yKHBhcmVudDogQ29uc3RydWN0LCBuYW1lOiBzdHJpbmcsIHByb3BzOiBQaXBlbGluZVdhdGNoZXJQcm9wcykge1xuICAgIHN1cGVyKHBhcmVudCwgbmFtZSk7XG5cbiAgICBjb25zdCBwaXBlbGluZVdhdGNoZXIgPSBuZXcgbGFtYmRhLkZ1bmN0aW9uKHRoaXMsICdQb2xsZXInLCB7XG4gICAgICBoYW5kbGVyOiAnd2F0Y2hlci1oYW5kbGVyLmhhbmRsZXInLFxuICAgICAgcnVudGltZTogbGFtYmRhLlJ1bnRpbWUuTk9ERUpTXzIwX1gsXG4gICAgICBjb2RlOiBsYW1iZGEuQ29kZS5mcm9tQXNzZXQocGF0aC5qb2luKF9fZGlybmFtZSwgJ2hhbmRsZXInKSksXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBNRVRSSUNfTkFNRVNQQUNFOiBwcm9wcy5tZXRyaWNOYW1lc3BhY2UsXG4gICAgICAgIE1FVFJJQ19OQU1FOiBwcm9wcy5mYWlsdXJlTWV0cmljTmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBwaXBlbGluZVdhdGNoZXIuYWRkVG9Sb2xlUG9saWN5KG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgICBhY3Rpb25zOiBbJ2Nsb3Vkd2F0Y2g6UHV0TWV0cmljRGF0YSddLFxuICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICBTdHJpbmdFcXVhbHM6IHtcbiAgICAgICAgICAnY2xvdWR3YXRjaDpuYW1lc3BhY2UnOiBwcm9wcy5tZXRyaWNOYW1lc3BhY2UsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pKTtcblxuICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCAnVHJpZ2dlcicsIHtcbiAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICBzb3VyY2U6IFsnYXdzLmNvZGVwaXBlbGluZSddLFxuICAgICAgICByZXNvdXJjZXM6IFtwcm9wcy5waXBlbGluZS5waXBlbGluZUFybl0sXG4gICAgICAgIGRldGFpbFR5cGU6IFtcbiAgICAgICAgICAnQ29kZVBpcGVsaW5lIEFjdGlvbiBFeGVjdXRpb24gU3RhdGUgQ2hhbmdlJyxcbiAgICAgICAgICAnQ29kZVBpcGVsaW5lIFBpcGVsaW5lIEV4ZWN1dGlvbiBTdGF0ZSBDaGFuZ2UnLFxuICAgICAgICBdLFxuICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICBzdGF0ZTogWydGQUlMRUQnLCAnU1VDQ0VFREVEJ10sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgdGFyZ2V0czogW25ldyBldmVudHNfdGFyZ2V0cy5MYW1iZGFGdW5jdGlvbihwaXBlbGluZVdhdGNoZXIpXSxcbiAgICB9KTtcblxuICAgIHRoaXMuYWxhcm0gPSBuZXcgY2xvdWR3YXRjaC5BbGFybSh0aGlzLCAnQWxhcm0nLCB7XG4gICAgICBhbGFybURlc2NyaXB0aW9uOiBgUGlwZWxpbmUgJHtwcm9wcy50aXRsZSB8fCBwcm9wcy5waXBlbGluZS5waXBlbGluZU5hbWV9IGhhcyBmYWlsZWQgc3RhZ2VzYCxcbiAgICAgIG1ldHJpYzogbmV3IGNsb3Vkd2F0Y2guTWV0cmljKHtcbiAgICAgICAgbWV0cmljTmFtZTogcHJvcHMuZmFpbHVyZU1ldHJpY05hbWUsXG4gICAgICAgIG5hbWVzcGFjZTogcHJvcHMubWV0cmljTmFtZXNwYWNlLFxuICAgICAgICBzdGF0aXN0aWM6IGNsb3Vkd2F0Y2guU3RhdGlzdGljLk1BWElNVU0sXG4gICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICBQaXBlbGluZTogcHJvcHMucGlwZWxpbmUucGlwZWxpbmVOYW1lLFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgICB0aHJlc2hvbGQ6IDEsXG4gICAgICBjb21wYXJpc29uT3BlcmF0b3I6IGNsb3Vkd2F0Y2guQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9PUl9FUVVBTF9UT19USFJFU0hPTEQsXG4gICAgICBldmFsdWF0aW9uUGVyaW9kczogMSxcbiAgICAgIC8vIElHTk9SRSBtaXNzaW5nIGRhdGEsIHNvIHRoZSBhbGFybSBzdGF5cyBpbiBpdHMgY3VycmVudCBzdGF0ZSwgdW50aWwgdGhlIG5leHQgZGF0YSBwb2ludC5cbiAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5JR05PUkUsXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==