in lib/pipeline-watcher/watcher.ts [51:105]
constructor(parent: Construct, name: string, props: PipelineWatcherProps) {
super(parent, name);
const pipelineWatcher = new lambda.Function(this, 'Poller', {
handler: 'watcher-handler.handler',
runtime: lambda.Runtime.NODEJS_12_X,
code: lambda.Code.fromAsset(path.join(__dirname, 'handler')),
environment: {
METRIC_NAMESPACE: props.metricNamespace,
METRIC_NAME: props.failureMetricName,
},
});
pipelineWatcher.addToRolePolicy(new iam.PolicyStatement({
resources: ['*'],
actions: ['cloudwatch:PutMetricData'],
conditions: {
StringEquals: {
'cloudwatch:namespace': props.metricNamespace,
},
},
}));
new 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 events_targets.LambdaFunction(pipelineWatcher)],
});
this.alarm = new cloudwatch.Alarm(this, 'Alarm', {
alarmDescription: `Pipeline ${props.title || props.pipeline.pipelineName} has failed stages`,
metric: new cloudwatch.Metric({
metricName: props.failureMetricName,
namespace: props.metricNamespace,
statistic: cloudwatch.Statistic.MAXIMUM,
dimensions: {
Pipeline: props.pipeline.pipelineName,
},
}),
threshold: 1,
comparisonOperator: 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: cloudwatch.TreatMissingData.IGNORE,
});
}