Skip to content

Commit

Permalink
feat(cloudwatch-actions): add ssm opsitem action for cloudwatch alarm (
Browse files Browse the repository at this point in the history
…#16923)

This small PR will add SSM OpsItem action to cloudwatch alarm.
The arn format was taken from the alarm UI (in view source) and with all the parameters (severity and category)

closes #16861 

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
vportascarta authored Feb 1, 2022
1 parent a2eb092 commit 9380885
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 1 deletion.
15 changes: 14 additions & 1 deletion packages/@aws-cdk/aws-cloudwatch-actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

This library contains a set of classes which can be used as CloudWatch Alarm actions.

The currently implemented actions are: EC2 Actions, SNS Actions, Autoscaling Actions and Aplication Autoscaling Actions
The currently implemented actions are: EC2 Actions, SNS Actions, SSM OpsCenter Actions, Autoscaling Actions and Application Autoscaling Actions


## EC2 Action Example
Expand All @@ -25,4 +25,17 @@ alarm.addAlarmAction(
);
```

## SSM OpsCenter Action Example

```ts
declare const alarm: cloudwatch.Alarm;
// Create an OpsItem with specific severity and category when alarm triggers
alarm.addAlarmAction(
new actions.SsmAction(
actions.OpsItemSeverity.CRITICAL,
actions.OpsItemCategory.PERFORMANCE // category is optional
)
);
```

See `@aws-cdk/aws-cloudwatch` for more information.
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-cloudwatch-actions/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './appscaling';
export * from './autoscaling';
export * from './sns';
export * from './ec2';
export * from './ssm';
79 changes: 79 additions & 0 deletions packages/@aws-cdk/aws-cloudwatch-actions/lib/ssm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
import { Stack } from '@aws-cdk/core';

// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
// eslint-disable-next-line no-duplicate-imports, import/order
import { Construct } from '@aws-cdk/core';

/**
* Types of OpsItem severity available
*/
export enum OpsItemSeverity {
/**
* Set the severity to critical
*/
CRITICAL = '1',
/**
* Set the severity to high
*/
HIGH = '2',
/**
* Set the severity to medium
*/
MEDIUM = '3',
/**
* Set the severity to low
*/
LOW = '4'
}

/**
* Types of OpsItem category available
*/
export enum OpsItemCategory {
/**
* Set the category to availability
*/
AVAILABILITY = 'Availability',
/**
* Set the category to cost
*/
COST = 'Cost',
/**
* Set the category to performance
*/
PERFORMANCE = 'Performance',
/**
* Set the category to recovery
*/
RECOVERY = 'Recovery',
/**
* Set the category to security
*/
SECURITY = 'Security'
}

/**
* Use an SSM OpsItem action as an Alarm action
*/
export class SsmAction implements cloudwatch.IAlarmAction {
private severity: OpsItemSeverity;
private category?: OpsItemCategory;

constructor(severity: OpsItemSeverity, category?: OpsItemCategory) {
this.severity = severity;
this.category = category;
}

/**
* Returns an alarm action configuration to use an SSM OpsItem action as an alarm action
*/
bind(_scope: Construct, _alarm: cloudwatch.IAlarm): cloudwatch.AlarmActionConfig {
if (this.category === undefined) {
return { alarmActionArn: `arn:aws:ssm:${Stack.of(_scope).region}:${Stack.of(_scope).account}:opsitem:${this.severity}` };
} else {
return { alarmActionArn: `arn:aws:ssm:${Stack.of(_scope).region}:${Stack.of(_scope).account}:opsitem:${this.severity}#CATEGORY=${this.category}` };
}
}
}

82 changes: 82 additions & 0 deletions packages/@aws-cdk/aws-cloudwatch-actions/test/ssm.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { Template } from '@aws-cdk/assertions';
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
import { Stack } from '@aws-cdk/core';
import * as actions from '../lib';

test('can use ssm with critical severity and performance category as alarm action', () => {
// GIVEN
const stack = new Stack();
const alarm = new cloudwatch.Alarm(stack, 'Alarm', {
metric: new cloudwatch.Metric({
namespace: 'AWS',
metricName: 'Test',
}),
evaluationPeriods: 3,
threshold: 100,
});

// WHEN
alarm.addAlarmAction(new actions.SsmAction(actions.OpsItemSeverity.CRITICAL, actions.OpsItemCategory.PERFORMANCE));

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', {
AlarmActions: [
{
'Fn::Join': [
'',
[
'arn:aws:ssm:',
{
Ref: 'AWS::Region',
},
':',
{
Ref: 'AWS::AccountId',
},
':opsitem:1#CATEGORY=Performance',
],
],
},
],
});
});


test('can use ssm with meduim severity and no category as alarm action', () => {
// GIVEN
const stack = new Stack();
const alarm = new cloudwatch.Alarm(stack, 'Alarm', {
metric: new cloudwatch.Metric({
namespace: 'AWS',
metricName: 'Test',
}),
evaluationPeriods: 3,
threshold: 100,
});

// WHEN
alarm.addAlarmAction(new actions.SsmAction(actions.OpsItemSeverity.MEDIUM));

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', {
AlarmActions: [
{
'Fn::Join': [
'',
[
'arn:aws:ssm:',
{
Ref: 'AWS::Region',
},
':',
{
Ref: 'AWS::AccountId',
},
':opsitem:3',
],
],
},
],
});
});

0 comments on commit 9380885

Please sign in to comment.