diff --git a/packages/@aws-cdk/aws-appconfig-alpha/lib/environment.ts b/packages/@aws-cdk/aws-appconfig-alpha/lib/environment.ts index fdcd7a29d92b6..fa39c078449e9 100644 --- a/packages/@aws-cdk/aws-appconfig-alpha/lib/environment.ts +++ b/packages/@aws-cdk/aws-appconfig-alpha/lib/environment.ts @@ -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 }), }; }), }); @@ -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 { diff --git a/packages/@aws-cdk/aws-appconfig-alpha/test/environment.test.ts b/packages/@aws-cdk/aws-appconfig-alpha/test/environment.test.ts index ffb8c092fa820..cf11a44047732 100644 --- a/packages/@aws-cdk/aws-appconfig-alpha/test/environment.test.ts +++ b/packages/@aws-cdk/aws-appconfig-alpha/test/environment.test.ts @@ -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', () => { @@ -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); @@ -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(); @@ -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); diff --git a/packages/@aws-cdk/aws-appconfig-alpha/test/integ.environment.ts b/packages/@aws-cdk/aws-appconfig-alpha/test/integ.environment.ts index 2d19953e3d59c..44077513d91a5 100644 --- a/packages/@aws-cdk/aws-appconfig-alpha/test/integ.environment.ts +++ b/packages/@aws-cdk/aws-appconfig-alpha/test/integ.environment.ts @@ -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(); @@ -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', {