From 5f2065801e68251b518b55cb235c2849c63b3c22 Mon Sep 17 00:00:00 2001 From: Chinedum Echeta <60179183+cecheta@users.noreply.github.com> Date: Tue, 14 Feb 2023 07:55:24 +0000 Subject: [PATCH] Add feature flag --- .../lib/ecs/deployment-group.ts | 7 +++++- .../lib/lambda/deployment-group.ts | 7 +++++- .../aws-codedeploy/lib/private/utils.ts | 24 +++++++++++++------ .../lib/server/deployment-group.ts | 7 +++++- packages/@aws-cdk/aws-codedeploy/package.json | 1 + .../test/ecs/deployment-group.test.ts | 7 +++++- .../test/lambda/deployment-group.test.ts | 1 + .../test/server/deployment-group.test.ts | 19 ++++++++++++++- packages/@aws-cdk/cx-api/FEATURE_FLAGS.md | 19 ++++++++++++++- packages/@aws-cdk/cx-api/lib/features.ts | 14 +++++++++++ 10 files changed, 93 insertions(+), 13 deletions(-) diff --git a/packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-group.ts index 7b549e79d173c..836ce6069ced7 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-group.ts @@ -3,6 +3,7 @@ import * as ecs from '@aws-cdk/aws-ecs'; import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2'; import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; +import { CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP } from '@aws-cdk/cx-api'; import { Construct } from 'constructs'; import { CfnDeploymentGroup } from '../codedeploy.generated'; import { ImportedDeploymentGroupBase, DeploymentGroupBase } from '../private/base-deployment-group'; @@ -240,6 +241,8 @@ export class EcsDeploymentGroup extends DeploymentGroupBase implements IEcsDeplo } } + const removeAlarmsFromDeploymentGroup = cdk.FeatureFlags.of(this).isEnabled(CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP); + const resource = new CfnDeploymentGroup(this, 'Resource', { applicationName: this.application.applicationName, serviceRoleArn: this.role.roleArn, @@ -257,7 +260,9 @@ export class EcsDeploymentGroup extends DeploymentGroupBase implements IEcsDeplo produce: () => this.renderBlueGreenDeploymentConfiguration(props.blueGreenDeploymentConfig), }), loadBalancerInfo: cdk.Lazy.any({ produce: () => this.renderLoadBalancerInfo(props.blueGreenDeploymentConfig) }), - alarmConfiguration: cdk.Lazy.any({ produce: () => renderAlarmConfiguration(this.alarms, props.ignorePollAlarmsFailure) }), + alarmConfiguration: cdk.Lazy.any({ + produce: () => renderAlarmConfiguration(this.alarms, props.ignorePollAlarmsFailure, removeAlarmsFromDeploymentGroup), + }), autoRollbackConfiguration: cdk.Lazy.any({ produce: () => renderAutoRollbackConfiguration(this.alarms, props.autoRollback) }), }); diff --git a/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts index ea61370f9a140..ba7ec471172e3 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts @@ -2,6 +2,7 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import * as cdk from '@aws-cdk/core'; +import { CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP } from '@aws-cdk/cx-api'; import { Construct } from 'constructs'; import { CfnDeploymentGroup } from '../codedeploy.generated'; import { ImportedDeploymentGroupBase, DeploymentGroupBase } from '../private/base-deployment-group'; @@ -164,6 +165,8 @@ export class LambdaDeploymentGroup extends DeploymentGroupBase implements ILambd this.role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSCodeDeployRoleForLambdaLimited')); this.deploymentConfig = this._bindDeploymentConfig(props.deploymentConfig || LambdaDeploymentConfig.CANARY_10PERCENT_5MINUTES); + const removeAlarmsFromDeploymentGroup = cdk.FeatureFlags.of(this).isEnabled(CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP); + const resource = new CfnDeploymentGroup(this, 'Resource', { applicationName: this.application.applicationName, serviceRoleArn: this.role.roleArn, @@ -173,7 +176,9 @@ export class LambdaDeploymentGroup extends DeploymentGroupBase implements ILambd deploymentType: 'BLUE_GREEN', deploymentOption: 'WITH_TRAFFIC_CONTROL', }, - alarmConfiguration: cdk.Lazy.any({ produce: () => renderAlarmConfiguration(this.alarms, props.ignorePollAlarmsFailure) }), + alarmConfiguration: cdk.Lazy.any({ + produce: () => renderAlarmConfiguration(this.alarms, props.ignorePollAlarmsFailure, removeAlarmsFromDeploymentGroup), + }), autoRollbackConfiguration: cdk.Lazy.any({ produce: () => renderAutoRollbackConfiguration(this.alarms, props.autoRollback) }), }); diff --git a/packages/@aws-cdk/aws-codedeploy/lib/private/utils.ts b/packages/@aws-cdk/aws-codedeploy/lib/private/utils.ts index ce108f6165f69..83aabb2f6d50e 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/private/utils.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/private/utils.ts @@ -31,13 +31,23 @@ export function arnForDeploymentConfig(name: string, resource?: IResource): stri }); } -export function renderAlarmConfiguration(alarms: cloudwatch.IAlarm[], ignorePollAlarmFailure?: boolean): -CfnDeploymentGroup.AlarmConfigurationProperty { - return { - alarms: alarms.length > 0 ? alarms.map(a => ({ name: a.alarmName })) : undefined, - enabled: alarms.length > 0, - ignorePollAlarmFailure, - }; +export function renderAlarmConfiguration(alarms: cloudwatch.IAlarm[], ignorePollAlarmFailure: boolean | undefined, removeAlarms = true): +CfnDeploymentGroup.AlarmConfigurationProperty | undefined { + if (removeAlarms) { + return { + alarms: alarms.length > 0 ? alarms.map(a => ({ name: a.alarmName })) : undefined, + enabled: alarms.length > 0, + ignorePollAlarmFailure, + }; + } + + return alarms.length === 0 + ? undefined + : { + alarms: alarms.map(a => ({ name: a.alarmName })), + enabled: true, + ignorePollAlarmFailure, + }; } export function deploymentConfig(name: string): IBaseDeploymentConfig & IPredefinedDeploymentConfig { diff --git a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts index b78bc0179af67..72087c1481aaa 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts @@ -4,6 +4,7 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as s3 from '@aws-cdk/aws-s3'; import * as cdk from '@aws-cdk/core'; +import { CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP } from '@aws-cdk/cx-api'; import { Construct } from 'constructs'; import { CfnDeploymentGroup } from '../codedeploy.generated'; import { ImportedDeploymentGroupBase, DeploymentGroupBase } from '../private/base-deployment-group'; @@ -267,6 +268,8 @@ export class ServerDeploymentGroup extends DeploymentGroupBase implements IServe this.alarms = props.alarms || []; + const removeAlarmsFromDeploymentGroup = cdk.FeatureFlags.of(this).isEnabled(CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP); + const resource = new CfnDeploymentGroup(this, 'Resource', { applicationName: this.application.applicationName, deploymentGroupName: this.physicalName, @@ -282,7 +285,9 @@ export class ServerDeploymentGroup extends DeploymentGroupBase implements IServe }, ec2TagSet: this.ec2TagSet(props.ec2InstanceTags), onPremisesTagSet: this.onPremiseTagSet(props.onPremiseInstanceTags), - alarmConfiguration: cdk.Lazy.any({ produce: () => renderAlarmConfiguration(this.alarms, props.ignorePollAlarmsFailure) }), + alarmConfiguration: cdk.Lazy.any({ + produce: () => renderAlarmConfiguration(this.alarms, props.ignorePollAlarmsFailure, removeAlarmsFromDeploymentGroup), + }), autoRollbackConfiguration: cdk.Lazy.any({ produce: () => renderAutoRollbackConfiguration(this.alarms, props.autoRollback) }), }); diff --git a/packages/@aws-cdk/aws-codedeploy/package.json b/packages/@aws-cdk/aws-codedeploy/package.json index ad4f31f642035..5a329a0d0919c 100644 --- a/packages/@aws-cdk/aws-codedeploy/package.json +++ b/packages/@aws-cdk/aws-codedeploy/package.json @@ -104,6 +104,7 @@ "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/custom-resources": "0.0.0", + "@aws-cdk/cx-api": "0.0.0", "constructs": "^10.0.0" }, "homepage": "https://github.com/aws/aws-cdk", diff --git a/packages/@aws-cdk/aws-codedeploy/test/ecs/deployment-group.test.ts b/packages/@aws-cdk/aws-codedeploy/test/ecs/deployment-group.test.ts index 0b6a6ee653baa..7051f9e793318 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/ecs/deployment-group.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/ecs/deployment-group.test.ts @@ -1,4 +1,4 @@ -import { Template } from '@aws-cdk/assertions'; +import { Match, Template } from '@aws-cdk/assertions'; import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as ecs from '@aws-cdk/aws-ecs'; @@ -51,6 +51,7 @@ describe('CodeDeploy ECS DeploymentGroup', () => { test('can be created with default configuration', () => { const stack = new cdk.Stack(); + stack.node.setContext('@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup', true); new codedeploy.EcsDeploymentGroup(stack, 'MyDG', { service: mockEcsService(stack), @@ -73,6 +74,10 @@ describe('CodeDeploy ECS DeploymentGroup', () => { 'Arn', ], }, + AlarmConfiguration: { + Enabled: false, + Alarms: Match.absent(), + }, AutoRollbackConfiguration: { Enabled: true, Events: [ diff --git a/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts b/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts index 669e3e91ce4ac..33dadeb60dd61 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts @@ -26,6 +26,7 @@ function mockAlias(stack: cdk.Stack) { describe('CodeDeploy Lambda DeploymentGroup', () => { test('can be created with default AllAtOnce IN_PLACE configuration', () => { const stack = new cdk.Stack(); + stack.node.setContext('@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup', true); const application = new codedeploy.LambdaApplication(stack, 'MyApp'); const alias = mockAlias(stack); new codedeploy.LambdaDeploymentGroup(stack, 'MyDG', { diff --git a/packages/@aws-cdk/aws-codedeploy/test/server/deployment-group.test.ts b/packages/@aws-cdk/aws-codedeploy/test/server/deployment-group.test.ts index 02d76400d3120..7787af144c0ba 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/server/deployment-group.test.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/server/deployment-group.test.ts @@ -1,4 +1,4 @@ -import { Template } from '@aws-cdk/assertions'; +import { Match, Template } from '@aws-cdk/assertions'; import * as autoscaling from '@aws-cdk/aws-autoscaling'; import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; @@ -24,6 +24,23 @@ describe('CodeDeploy Server Deployment Group', () => { }); }); + test('can create a deployment group with no alarms', () => { + const stack = new cdk.Stack(); + stack.node.setContext('@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup', true); + + const application = new codedeploy.ServerApplication(stack, 'MyApp'); + new codedeploy.ServerDeploymentGroup(stack, 'MyDG', { + application, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CodeDeploy::DeploymentGroup', { + AlarmConfiguration: { + Enabled: false, + Alarms: Match.absent(), + }, + }); + }); + test('creating an application with physical name if needed', () => { const stack = new cdk.Stack(undefined, undefined, { env: { account: '12345', region: 'us-test-1' } }); const stack2 = new cdk.Stack(undefined, undefined, { env: { account: '12346', region: 'us-test-2' } }); diff --git a/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md b/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md index a355164da0f5e..f8111a0022ce9 100644 --- a/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md +++ b/packages/@aws-cdk/cx-api/FEATURE_FLAGS.md @@ -43,6 +43,7 @@ Flags come in three types: | [@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy](#aws-cdkaws-s3serveraccesslogsusebucketpolicy) | Use S3 Bucket Policy instead of ACLs for Server Access Logging | 2.59.0 | (fix) | | [@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName](#aws-cdkaws-iamimportedrolestacksafedefaultpolicyname) | Enable this feature to by default create default policy names for imported roles that depend on the stack the role is in. | 2.60.0 | (fix) | | [@aws-cdk/customresources:installLatestAwsSdkDefault](#aws-cdkcustomresourcesinstalllatestawssdkdefault) | Whether to install the latest SDK by default in AwsCustomResource | 2.60.0 | (default) | +| [@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup](#aws-cdkaws-codedeployremovealarmsfromdeploymentgroup) | Remove CloudWatch alarms from deployment group | V2NEXT | (fix) | | [@aws-cdk/aws-rds:databaseProxyUniqueResourceName](#aws-cdkaws-rdsdatabaseproxyuniqueresourcename) | Use unique resource name for Database Proxy | V2NEXT | (fix) | @@ -78,7 +79,8 @@ The following json shows the current recommended set of flags, as `cdk init` wou "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, "@aws-cdk/aws-route53-patters:useCertificate": true, "@aws-cdk/customresources:installLatestAwsSdkDefault": false, - "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true } } ``` @@ -780,6 +782,21 @@ flag on a resource-by-resource basis to enable it if necessary. **Compatibility with old behavior:** Set installLatestAwsSdk: true on all resources that need it. +### @aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup + +*Remove CloudWatch alarms from deployment group* (fix) + +Enable this flag to be able to remove all CloudWatch alarms from a deployment group by removing +the alarms from the construct. If this flag is not set, removing all alarms from the construct +will still leave the alarms configured for the deployment group. + + +| Since | Default | Recommended | +| ----- | ----- | ----- | +| (not in v1) | | | +| V2NEXT | `false` | `true` | + + ### @aws-cdk/aws-rds:databaseProxyUniqueResourceName *Use unique resource name for Database Proxy* (fix) diff --git a/packages/@aws-cdk/cx-api/lib/features.ts b/packages/@aws-cdk/cx-api/lib/features.ts index 49c9643c92e37..469bcdcd2d93d 100644 --- a/packages/@aws-cdk/cx-api/lib/features.ts +++ b/packages/@aws-cdk/cx-api/lib/features.ts @@ -79,6 +79,7 @@ export const S3_SERVER_ACCESS_LOGS_USE_BUCKET_POLICY = '@aws-cdk/aws-s3:serverAc export const ROUTE53_PATTERNS_USE_CERTIFICATE = '@aws-cdk/aws-route53-patters:useCertificate'; export const AWS_CUSTOM_RESOURCE_LATEST_SDK_DEFAULT = '@aws-cdk/customresources:installLatestAwsSdkDefault'; export const DATABASE_PROXY_UNIQUE_RESOURCE_NAME = '@aws-cdk/aws-rds:databaseProxyUniqueResourceName'; +export const CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP = '@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup'; export const FLAGS: Record = { ////////////////////////////////////////////////////////////////////// @@ -645,6 +646,19 @@ export const FLAGS: Record = { introducedIn: { v2: 'V2NEXT' }, recommendedValue: true, }, + + ////////////////////////////////////////////////////////////////////// + [CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP]: { + type: FlagType.BugFix, + summary: 'Remove CloudWatch alarms from deployment group', + detailsMd: ` + Enable this flag to be able to remove all CloudWatch alarms from a deployment group by removing + the alarms from the construct. If this flag is not set, removing all alarms from the construct + will still leave the alarms configured for the deployment group. + `, + introducedIn: { v2: 'V2NEXT' }, + recommendedValue: true, + }, }; const CURRENT_MV = 'v2';