Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(appconfig): add CfnMonitorsProperty as a supported type for moni… #27667

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 47 additions & 9 deletions packages/@aws-cdk/aws-appconfig-alpha/lib/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,10 @@ export class Environment extends EnvironmentBase {
description: this.description,
monitors: this.monitors?.map((monitor, index) => {
return {
alarmArn: monitor.alarm.alarmArn,
alarmRoleArn: monitor.alarmRole?.roleArn || this.createAlarmRole(monitor.alarm.alarmArn, index).roleArn,
alarmArn: monitor.alarmArn,
...(monitor.monitorType === MonitorType.CLOUDWATCH
? { alarmRoleArn: monitor.alarmRoleArn || this.createAlarmRole(monitor.alarmArn, index).roleArn }
: { alarmRoleArn: monitor.alarmRoleArn }),
};
}),
});
Expand Down Expand Up @@ -276,21 +278,57 @@ export class Environment extends EnvironmentBase {
}
}

export enum MonitorType {
CLOUDWATCH,
CFN_MONITORS_PROPERTY,
}

/**
* Defines monitors that will be associated with an AWS AppConfig environment.
*/
export interface Monitor {
export abstract class Monitor {
/**
* The Amazon CloudWatch alarm.
* The alarm ARN for AWS AppConfig to monitor.
*/
readonly alarm: cloudwatch.IAlarm;
public abstract readonly alarmArn: string;

/**
* The IAM role for AWS AppConfig to view the alarm state.
*
* @default - A role is generated.
* The IAM role ARN for AWS AppConfig to view the alarm state.
*/
readonly alarmRole?: iam.IRole;
public abstract readonly alarmRoleArn?: string;

/**
* The type of monitor.
*/
public abstract readonly monitorType: MonitorType;

/**
* Creates a Monitor from a CloudWatch alarm. If the alarm role is not specified, a role will
* be generated.
*
* @param alarm The Amazon CloudWatch alarm.
* @param alarmRole The IAM role for AWS AppConfig to view the alarm state.
*/
public static fromCloudWatchAlarm(alarm: cloudwatch.IAlarm, alarmRole?: iam.IRole): Monitor {
return {
alarmArn: alarm.alarmArn,
alarmRoleArn: alarmRole?.roleArn,
monitorType: MonitorType.CLOUDWATCH,
};
}

/**
* Creates a Monitor from a CfnEnvironment.MonitorsProperty construct.
*
* @param monitorsProperty The monitors property.
*/
public static fromCfnMonitorsProperty(monitorsProperty: CfnEnvironment.MonitorsProperty): Monitor {
return {
alarmArn: monitorsProperty.alarmArn!,
alarmRoleArn: monitorsProperty.alarmRoleArn,
monitorType: MonitorType.CFN_MONITORS_PROPERTY,
};
}
}

export interface IEnvironment extends IResource {
Expand Down
141 changes: 96 additions & 45 deletions packages/@aws-cdk/aws-appconfig-alpha/test/environment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { App } from 'aws-cdk-lib';
import { Template } from 'aws-cdk-lib/assertions';
import { Alarm, Metric } from 'aws-cdk-lib/aws-cloudwatch';
import * as iam from 'aws-cdk-lib/aws-iam';
import { Application, Environment } from '../lib';
import { Application, Environment, Monitor } from '../lib';

describe('environment', () => {
test('default environment', () => {
Expand Down Expand Up @@ -58,26 +58,23 @@ describe('environment', () => {
test('environment with monitors with alarm and alarmRole', () => {
const stack = new cdk.Stack();
const app = new Application(stack, 'MyAppConfig');
const alarm = new Alarm(stack, 'Alarm', {
threshold: 5,
evaluationPeriods: 5,
metric: new Metric(
{
namespace: 'aws',
metricName: 'myMetric',
},
),
});
const alarmRole = new iam.Role(stack, 'Role', {
assumedBy: new iam.ServicePrincipal('appconfig.amazonaws.com'),
});
const env = new Environment(stack, 'MyEnvironment', {
name: 'TestEnv',
application: app,
monitors: [
{
alarm: new Alarm(stack, 'Alarm', {
threshold: 5,
evaluationPeriods: 5,
metric: new Metric(
{
namespace: 'aws',
metricName: 'myMetric',
},
),
}),
alarmRole: new iam.Role(stack, 'Role', {
assumedBy: new iam.ServicePrincipal('appconfig.amazonaws.com'),
}),
},
],
monitors: [Monitor.fromCloudWatchAlarm(alarm, alarmRole)],
});

Template.fromStack(stack).resourceCountIs('AWS::CloudWatch::Alarm', 1);
Expand Down Expand Up @@ -123,11 +120,7 @@ describe('environment', () => {
const env = new Environment(stack, 'MyEnvironment', {
name: 'TestEnv',
application: app,
monitors: [
{
alarm,
},
],
monitors: [Monitor.fromCloudWatchAlarm(alarm)],
});

expect(env).toBeDefined();
Expand Down Expand Up @@ -177,39 +170,97 @@ describe('environment', () => {
});
});

test('environment with monitors with two alarms', () => {
test('environment with CfnMonitorsProperty monitor', () => {
const stack = new cdk.Stack();
const app = new Application(stack, 'MyAppConfig');
new Environment(stack, 'MyEnvironment', {
const env = new Environment(stack, 'MyEnvironment', {
name: 'TestEnv',
application: app,
monitors: [
Monitor.fromCfnMonitorsProperty({
alarmArn: 'thisismyalarm',
}),
],
});

expect(env).toBeDefined();
Template.fromStack(stack).resourceCountIs('AWS::CloudWatch::Alarm', 0);
Template.fromStack(stack).resourceCountIs('AWS::IAM::Role', 0);
Template.fromStack(stack).hasResourceProperties('AWS::AppConfig::Environment', {
Name: 'TestEnv',
ApplicationId: {
Ref: 'MyAppConfigB4B63E75',
},
Monitors: [
{
alarm: new Alarm(stack, 'Alarm1', {
threshold: 5,
evaluationPeriods: 5,
metric: new Metric(
{
namespace: 'aws',
metricName: 'myMetric',
},
),
}),
AlarmArn: 'thisismyalarm',
},
],
});
});

test('environment with CfnMonitorsProperty monitor with roleArn', () => {
const stack = new cdk.Stack();
const app = new Application(stack, 'MyAppConfig');
const env = new Environment(stack, 'MyEnvironment', {
name: 'TestEnv',
application: app,
monitors: [
Monitor.fromCfnMonitorsProperty({
alarmArn: 'thisismyalarm',
alarmRoleArn: 'thisismyalarmrolearn'
}),
],
});

expect(env).toBeDefined();
Template.fromStack(stack).resourceCountIs('AWS::CloudWatch::Alarm', 0);
Template.fromStack(stack).resourceCountIs('AWS::IAM::Role', 0);
Template.fromStack(stack).hasResourceProperties('AWS::AppConfig::Environment', {
Name: 'TestEnv',
ApplicationId: {
Ref: 'MyAppConfigB4B63E75',
},
Monitors: [
{
alarm: new Alarm(stack, 'Alarm2', {
threshold: 5,
evaluationPeriods: 5,
metric: new Metric(
{
namespace: 'aws',
metricName: 'myMetric',
},
),
}),
AlarmArn: 'thisismyalarm',
AlarmRoleArn: 'thisismyalarmrolearn',
},
],
});
});

test('environment with monitors with two alarms', () => {
const stack = new cdk.Stack();
const app = new Application(stack, 'MyAppConfig');
const alarm1 = new Alarm(stack, 'Alarm1', {
threshold: 5,
evaluationPeriods: 5,
metric: new Metric(
{
namespace: 'aws',
metricName: 'myMetric',
},
),
});
const alarm2 = new Alarm(stack, 'Alarm2', {
threshold: 5,
evaluationPeriods: 5,
metric: new Metric(
{
namespace: 'aws',
metricName: 'myMetric',
},
),
});
new Environment(stack, 'MyEnvironment', {
name: 'TestEnv',
application: app,
monitors: [
Monitor.fromCloudWatchAlarm(alarm1),
Monitor.fromCloudWatchAlarm(alarm2),
],
});

Template.fromStack(stack).resourceCountIs('AWS::CloudWatch::Alarm', 2);
Template.fromStack(stack).resourceCountIs('AWS::IAM::Role', 2);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IntegTest } from '@aws-cdk/integ-tests-alpha';
import { App, Stack } from 'aws-cdk-lib';
import { Application, Environment } from '../lib';
import { Application, Environment, Monitor } from '../lib';
import { Alarm, Metric } from 'aws-cdk-lib/aws-cloudwatch';

const app = new App();
Expand All @@ -24,11 +24,7 @@ const alarm = new Alarm(stack, 'MyAlarm', {
new Environment(stack, 'MyEnvironment', {
application: appForEnv,
description: 'This is the environment for integ testing',
monitors: [
{
alarm,
},
],
monitors: [Monitor.fromCloudWatchAlarm(alarm)],
});

new IntegTest(app, 'appconfig-environment', {
Expand Down
Loading