Skip to content

Commit cc37778

Browse files
authored
fix(cloudwatch): cloudwatch ec2 alarm action with multiple dimension results in error (#29364)
### Issue # (if applicable) Closes #29331 ### Reason for this change While trying to create a Custom Metric with multiple dimension, and adding EC2 action, the CDK synth fails. ### Description of changes As long as there's instance id in dimension, we should accept it instead of raising exception. ### Description of how you validated changes new tests and existing tests pass. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent bc9d0b4 commit cc37778

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

packages/aws-cdk-lib/aws-cloudwatch/lib/alarm.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ export class Alarm extends AlarmBase {
267267
if (ec2ActionsRegexp.test(actionArn)) {
268268
// Check per-instance metric
269269
const metricConfig = this.metric.toMetricConfig();
270-
if (metricConfig.metricStat?.dimensions?.length != 1 || metricConfig.metricStat?.dimensions![0].name != 'InstanceId') {
270+
if (metricConfig.metricStat?.dimensions?.length != 1 || !metricConfig.metricStat?.dimensions?.some(dimension => dimension.name === 'InstanceId')) {
271271
throw new Error(`EC2 alarm actions requires an EC2 Per-Instance Metric. (${JSON.stringify(metricConfig)} does not have an 'InstanceId' dimension)`);
272272
}
273273
}

packages/aws-cdk-lib/aws-cloudwatch/test/alarm.test.ts

+62-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { Construct } from 'constructs';
22
import { Match, Template, Annotations } from '../../assertions';
3-
import { Duration, Stack } from '../../core';
3+
import { Ec2Action, Ec2InstanceAction } from '../../aws-cloudwatch-actions/lib';
4+
import { Duration, Stack, App } from '../../core';
5+
import { ENABLE_PARTITION_LITERALS } from '../../cx-api';
46
import { Alarm, IAlarm, IAlarmAction, Metric, MathExpression, IMetric, Stats } from '../lib';
57

68
const testMetric = new Metric({
@@ -232,6 +234,65 @@ describe('Alarm', () => {
232234
});
233235
});
234236

237+
test('EC2 alarm actions with InstanceId dimension', () => {
238+
// GIVEN
239+
const app = new App({ context: { [ ENABLE_PARTITION_LITERALS]: true } });
240+
const stack = new Stack(app, 'EC2AlarmStack', { env: { region: 'us-west-2', account: '123456789012' } });
241+
242+
// WHEN
243+
const metric = new Metric({
244+
namespace: 'CWAgent',
245+
metricName: 'disk_used_percent',
246+
dimensionsMap: {
247+
InstanceId: 'instance-id',
248+
},
249+
period: Duration.minutes(5),
250+
statistic: 'Average',
251+
});
252+
253+
const sev3Alarm = new Alarm(stack, 'DISK_USED_PERCENT_SEV3', {
254+
alarmName: 'DISK_USED_PERCENT_SEV3',
255+
actionsEnabled: true,
256+
metric: metric,
257+
threshold: 1,
258+
evaluationPeriods: 1,
259+
});
260+
261+
expect(() => {
262+
sev3Alarm.addAlarmAction(new Ec2Action(Ec2InstanceAction.REBOOT));
263+
}).not.toThrow();
264+
});
265+
266+
test('EC2 alarm actions without InstanceId dimension', () => {
267+
// GIVEN
268+
const app = new App({ context: { [ ENABLE_PARTITION_LITERALS]: true } });
269+
const stack = new Stack(app, 'EC2AlarmStack', { env: { region: 'us-west-2', account: '123456789012' } });
270+
271+
// WHEN
272+
const metric = new Metric({
273+
namespace: 'CWAgent',
274+
metricName: 'disk_used_percent',
275+
dimensionsMap: {
276+
ImageId: 'image-id',
277+
InstanceType: 't2.micro',
278+
},
279+
period: Duration.minutes(5),
280+
statistic: 'Average',
281+
});
282+
283+
const sev3Alarm = new Alarm(stack, 'DISK_USED_PERCENT_SEV3', {
284+
alarmName: 'DISK_USED_PERCENT_SEV3',
285+
actionsEnabled: true,
286+
metric: metric,
287+
threshold: 1,
288+
evaluationPeriods: 1,
289+
});
290+
291+
expect(() => {
292+
sev3Alarm.addAlarmAction(new Ec2Action(Ec2InstanceAction.REBOOT));
293+
}).toThrow(/EC2 alarm actions requires an EC2 Per-Instance Metric/);
294+
});
295+
235296
test('can use percentile string to make alarm', () => {
236297
// GIVEN
237298
const stack = new Stack();

0 commit comments

Comments
 (0)