Skip to content

Commit eee005f

Browse files
authored
fix(codedeploy): unable to remove alarms from deployment group (#23308)
---- Closes #23307. Disables CodeDeploy deployment group alarm configuration when alarms are removed from the deployment group. Also allows user to disable an alarm configuration even if alarms are associated with the group. ### All Submissions: * [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [X] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [X] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent de097ee commit eee005f

23 files changed

+509
-65
lines changed

packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-group.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as ecs from '@aws-cdk/aws-ecs';
33
import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2';
44
import * as iam from '@aws-cdk/aws-iam';
55
import * as cdk from '@aws-cdk/core';
6+
import { CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP } from '@aws-cdk/cx-api';
67
import { Construct } from 'constructs';
78
import { CfnDeploymentGroup } from '../codedeploy.generated';
89
import { ImportedDeploymentGroupBase, DeploymentGroupBase } from '../private/base-deployment-group';
@@ -240,6 +241,8 @@ export class EcsDeploymentGroup extends DeploymentGroupBase implements IEcsDeplo
240241
}
241242
}
242243

244+
const removeAlarmsFromDeploymentGroup = cdk.FeatureFlags.of(this).isEnabled(CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP);
245+
243246
const resource = new CfnDeploymentGroup(this, 'Resource', {
244247
applicationName: this.application.applicationName,
245248
serviceRoleArn: this.role.roleArn,
@@ -257,7 +260,9 @@ export class EcsDeploymentGroup extends DeploymentGroupBase implements IEcsDeplo
257260
produce: () => this.renderBlueGreenDeploymentConfiguration(props.blueGreenDeploymentConfig),
258261
}),
259262
loadBalancerInfo: cdk.Lazy.any({ produce: () => this.renderLoadBalancerInfo(props.blueGreenDeploymentConfig) }),
260-
alarmConfiguration: cdk.Lazy.any({ produce: () => renderAlarmConfiguration(this.alarms, props.ignorePollAlarmsFailure) }),
263+
alarmConfiguration: cdk.Lazy.any({
264+
produce: () => renderAlarmConfiguration(this.alarms, props.ignorePollAlarmsFailure, removeAlarmsFromDeploymentGroup),
265+
}),
261266
autoRollbackConfiguration: cdk.Lazy.any({ produce: () => renderAutoRollbackConfiguration(this.alarms, props.autoRollback) }),
262267
});
263268

packages/@aws-cdk/aws-codedeploy/lib/lambda/deployment-group.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
22
import * as iam from '@aws-cdk/aws-iam';
33
import * as lambda from '@aws-cdk/aws-lambda';
44
import * as cdk from '@aws-cdk/core';
5+
import { CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP } from '@aws-cdk/cx-api';
56
import { Construct } from 'constructs';
67
import { CfnDeploymentGroup } from '../codedeploy.generated';
78
import { ImportedDeploymentGroupBase, DeploymentGroupBase } from '../private/base-deployment-group';
@@ -164,6 +165,8 @@ export class LambdaDeploymentGroup extends DeploymentGroupBase implements ILambd
164165
this.role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSCodeDeployRoleForLambdaLimited'));
165166
this.deploymentConfig = this._bindDeploymentConfig(props.deploymentConfig || LambdaDeploymentConfig.CANARY_10PERCENT_5MINUTES);
166167

168+
const removeAlarmsFromDeploymentGroup = cdk.FeatureFlags.of(this).isEnabled(CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP);
169+
167170
const resource = new CfnDeploymentGroup(this, 'Resource', {
168171
applicationName: this.application.applicationName,
169172
serviceRoleArn: this.role.roleArn,
@@ -173,7 +176,9 @@ export class LambdaDeploymentGroup extends DeploymentGroupBase implements ILambd
173176
deploymentType: 'BLUE_GREEN',
174177
deploymentOption: 'WITH_TRAFFIC_CONTROL',
175178
},
176-
alarmConfiguration: cdk.Lazy.any({ produce: () => renderAlarmConfiguration(this.alarms, props.ignorePollAlarmsFailure) }),
179+
alarmConfiguration: cdk.Lazy.any({
180+
produce: () => renderAlarmConfiguration(this.alarms, props.ignorePollAlarmsFailure, removeAlarmsFromDeploymentGroup),
181+
}),
177182
autoRollbackConfiguration: cdk.Lazy.any({ produce: () => renderAutoRollbackConfiguration(this.alarms, props.autoRollback) }),
178183
});
179184

packages/@aws-cdk/aws-codedeploy/lib/private/utils.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,16 @@ export function arnForDeploymentConfig(name: string, resource?: IResource): stri
3131
});
3232
}
3333

34-
export function renderAlarmConfiguration(alarms: cloudwatch.IAlarm[], ignorePollAlarmFailure?: boolean):
34+
export function renderAlarmConfiguration(alarms: cloudwatch.IAlarm[], ignorePollAlarmFailure: boolean | undefined, removeAlarms = true):
3535
CfnDeploymentGroup.AlarmConfigurationProperty | undefined {
36+
if (removeAlarms) {
37+
return {
38+
alarms: alarms.length > 0 ? alarms.map(a => ({ name: a.alarmName })) : undefined,
39+
enabled: alarms.length > 0,
40+
ignorePollAlarmFailure,
41+
};
42+
}
43+
3644
return alarms.length === 0
3745
? undefined
3846
: {
@@ -114,4 +122,4 @@ export function validateName(type: 'Application' | 'Deployment group' | 'Deploym
114122
}
115123

116124
return ret;
117-
}
125+
}

packages/@aws-cdk/aws-codedeploy/lib/server/deployment-group.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as ec2 from '@aws-cdk/aws-ec2';
44
import * as iam from '@aws-cdk/aws-iam';
55
import * as s3 from '@aws-cdk/aws-s3';
66
import * as cdk from '@aws-cdk/core';
7+
import { CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP } from '@aws-cdk/cx-api';
78
import { Construct } from 'constructs';
89
import { CfnDeploymentGroup } from '../codedeploy.generated';
910
import { ImportedDeploymentGroupBase, DeploymentGroupBase } from '../private/base-deployment-group';
@@ -267,6 +268,8 @@ export class ServerDeploymentGroup extends DeploymentGroupBase implements IServe
267268

268269
this.alarms = props.alarms || [];
269270

271+
const removeAlarmsFromDeploymentGroup = cdk.FeatureFlags.of(this).isEnabled(CODEDEPLOY_REMOVE_ALARMS_FROM_DEPLOYMENT_GROUP);
272+
270273
const resource = new CfnDeploymentGroup(this, 'Resource', {
271274
applicationName: this.application.applicationName,
272275
deploymentGroupName: this.physicalName,
@@ -282,7 +285,9 @@ export class ServerDeploymentGroup extends DeploymentGroupBase implements IServe
282285
},
283286
ec2TagSet: this.ec2TagSet(props.ec2InstanceTags),
284287
onPremisesTagSet: this.onPremiseTagSet(props.onPremiseInstanceTags),
285-
alarmConfiguration: cdk.Lazy.any({ produce: () => renderAlarmConfiguration(this.alarms, props.ignorePollAlarmsFailure) }),
288+
alarmConfiguration: cdk.Lazy.any({
289+
produce: () => renderAlarmConfiguration(this.alarms, props.ignorePollAlarmsFailure, removeAlarmsFromDeploymentGroup),
290+
}),
286291
autoRollbackConfiguration: cdk.Lazy.any({ produce: () => renderAutoRollbackConfiguration(this.alarms, props.autoRollback) }),
287292
});
288293

packages/@aws-cdk/aws-codedeploy/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
"@aws-cdk/aws-s3": "0.0.0",
105105
"@aws-cdk/core": "0.0.0",
106106
"@aws-cdk/custom-resources": "0.0.0",
107+
"@aws-cdk/cx-api": "0.0.0",
107108
"constructs": "^10.0.0"
108109
},
109110
"homepage": "https://github.com/aws/aws-cdk",

packages/@aws-cdk/aws-codedeploy/test/ecs/deployment-group.test.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Template } from '@aws-cdk/assertions';
1+
import { Match, Template } from '@aws-cdk/assertions';
22
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
33
import * as ec2 from '@aws-cdk/aws-ec2';
44
import * as ecs from '@aws-cdk/aws-ecs';
@@ -51,6 +51,7 @@ describe('CodeDeploy ECS DeploymentGroup', () => {
5151

5252
test('can be created with default configuration', () => {
5353
const stack = new cdk.Stack();
54+
stack.node.setContext('@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup', true);
5455

5556
new codedeploy.EcsDeploymentGroup(stack, 'MyDG', {
5657
service: mockEcsService(stack),
@@ -73,6 +74,10 @@ describe('CodeDeploy ECS DeploymentGroup', () => {
7374
'Arn',
7475
],
7576
},
77+
AlarmConfiguration: {
78+
Enabled: false,
79+
Alarms: Match.absent(),
80+
},
7681
AutoRollbackConfiguration: {
7782
Enabled: true,
7883
Events: [

packages/@aws-cdk/aws-codedeploy/test/lambda/deployment-group.test.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Template } from '@aws-cdk/assertions';
1+
import { Match, Template } from '@aws-cdk/assertions';
22
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
33
import * as iam from '@aws-cdk/aws-iam';
44
import * as lambda from '@aws-cdk/aws-lambda';
@@ -26,6 +26,7 @@ function mockAlias(stack: cdk.Stack) {
2626
describe('CodeDeploy Lambda DeploymentGroup', () => {
2727
test('can be created with default AllAtOnce IN_PLACE configuration', () => {
2828
const stack = new cdk.Stack();
29+
stack.node.setContext('@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup', true);
2930
const application = new codedeploy.LambdaApplication(stack, 'MyApp');
3031
const alias = mockAlias(stack);
3132
new codedeploy.LambdaDeploymentGroup(stack, 'MyDG', {
@@ -44,6 +45,10 @@ describe('CodeDeploy Lambda DeploymentGroup', () => {
4445
'Arn',
4546
],
4647
},
48+
AlarmConfiguration: {
49+
Enabled: false,
50+
Alarms: Match.absent(),
51+
},
4752
AutoRollbackConfiguration: {
4853
Enabled: true,
4954
Events: [

packages/@aws-cdk/aws-codedeploy/test/lambda/integ.deployment-group.js.snapshot/aws-cdk-codedeploy-lambda.assets.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "21.0.0",
2+
"version": "22.0.0",
33
"files": {
44
"edb7466707eb899fbaee22c1e67f9443e9edcc2eeda0b58d8448f7c4157746b3": {
55
"source": {
@@ -40,15 +40,15 @@
4040
}
4141
}
4242
},
43-
"f2bf64943c8612dfbd52471095c4b141d6c458592f9416621609658bc7935827": {
43+
"209ced6e70ec9b3c3a5387896ca7c4942afced90ed5eb6045cc8f392776ae7ce": {
4444
"source": {
4545
"path": "aws-cdk-codedeploy-lambda.template.json",
4646
"packaging": "file"
4747
},
4848
"destinations": {
4949
"current_account-current_region": {
5050
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
51-
"objectKey": "f2bf64943c8612dfbd52471095c4b141d6c458592f9416621609658bc7935827.json",
51+
"objectKey": "209ced6e70ec9b3c3a5387896ca7c4942afced90ed5eb6045cc8f392776ae7ce.json",
5252
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
5353
}
5454
}

packages/@aws-cdk/aws-codedeploy/test/lambda/integ.deployment-group.js.snapshot/aws-cdk-codedeploy-lambda.template.json

+96-6
Original file line numberDiff line numberDiff line change
@@ -328,12 +328,6 @@
328328
"Threshold": 1
329329
}
330330
},
331-
"BlueGreenDeploymentApplication36C892C0": {
332-
"Type": "AWS::CodeDeploy::Application",
333-
"Properties": {
334-
"ComputePlatform": "Lambda"
335-
}
336-
},
337331
"BlueGreenDeploymentServiceRole225851FB": {
338332
"Type": "AWS::IAM::Role",
339333
"Properties": {
@@ -427,6 +421,12 @@
427421
]
428422
}
429423
},
424+
"BlueGreenDeploymentApplication36C892C0": {
425+
"Type": "AWS::CodeDeploy::Application",
426+
"Properties": {
427+
"ComputePlatform": "Lambda"
428+
}
429+
},
430430
"BlueGreenDeployment5C188134": {
431431
"Type": "AWS::CodeDeploy::DeploymentGroup",
432432
"Properties": {
@@ -462,6 +462,96 @@
462462
"DeploymentType": "BLUE_GREEN"
463463
}
464464
}
465+
},
466+
"SecondAlias33D63566": {
467+
"Type": "AWS::Lambda::Alias",
468+
"Properties": {
469+
"FunctionName": {
470+
"Ref": "Handler886CB40B"
471+
},
472+
"FunctionVersion": {
473+
"Fn::GetAtt": [
474+
"HandlerCurrentVersion93FB80BF4a6a6623436a0664df4549c4c809c243",
475+
"Version"
476+
]
477+
},
478+
"Name": "secondAlias"
479+
},
480+
"UpdatePolicy": {
481+
"CodeDeployLambdaAliasUpdate": {
482+
"ApplicationName": {
483+
"Ref": "SecondDeploymentApplication1F8C51FE"
484+
},
485+
"DeploymentGroupName": {
486+
"Ref": "SecondDeploymentC270A23D"
487+
}
488+
}
489+
}
490+
},
491+
"SecondDeploymentServiceRoleAFF1ECD5": {
492+
"Type": "AWS::IAM::Role",
493+
"Properties": {
494+
"AssumeRolePolicyDocument": {
495+
"Statement": [
496+
{
497+
"Action": "sts:AssumeRole",
498+
"Effect": "Allow",
499+
"Principal": {
500+
"Service": "codedeploy.amazonaws.com"
501+
}
502+
}
503+
],
504+
"Version": "2012-10-17"
505+
},
506+
"ManagedPolicyArns": [
507+
{
508+
"Fn::Join": [
509+
"",
510+
[
511+
"arn:",
512+
{
513+
"Ref": "AWS::Partition"
514+
},
515+
":iam::aws:policy/service-role/AWSCodeDeployRoleForLambdaLimited"
516+
]
517+
]
518+
}
519+
]
520+
}
521+
},
522+
"SecondDeploymentApplication1F8C51FE": {
523+
"Type": "AWS::CodeDeploy::Application",
524+
"Properties": {
525+
"ComputePlatform": "Lambda"
526+
}
527+
},
528+
"SecondDeploymentC270A23D": {
529+
"Type": "AWS::CodeDeploy::DeploymentGroup",
530+
"Properties": {
531+
"ApplicationName": {
532+
"Ref": "SecondDeploymentApplication1F8C51FE"
533+
},
534+
"ServiceRoleArn": {
535+
"Fn::GetAtt": [
536+
"SecondDeploymentServiceRoleAFF1ECD5",
537+
"Arn"
538+
]
539+
},
540+
"AlarmConfiguration": {
541+
"Enabled": false
542+
},
543+
"AutoRollbackConfiguration": {
544+
"Enabled": true,
545+
"Events": [
546+
"DEPLOYMENT_FAILURE"
547+
]
548+
},
549+
"DeploymentConfigName": "CodeDeployDefault.LambdaCanary10Percent5Minutes",
550+
"DeploymentStyle": {
551+
"DeploymentOption": "WITH_TRAFFIC_CONTROL",
552+
"DeploymentType": "BLUE_GREEN"
553+
}
554+
}
465555
}
466556
},
467557
"Parameters": {
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"version":"21.0.0"}
1+
{"version":"22.0.0"}

packages/@aws-cdk/aws-codedeploy/test/lambda/integ.deployment-group.js.snapshot/integ.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "21.0.0",
2+
"version": "22.0.0",
33
"testCases": {
44
"integ.deployment-group": {
55
"stacks": [

packages/@aws-cdk/aws-codedeploy/test/lambda/integ.deployment-group.js.snapshot/manifest.json

+32-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "21.0.0",
2+
"version": "22.0.0",
33
"artifacts": {
44
"aws-cdk-codedeploy-lambda.assets": {
55
"type": "cdk:asset-manifest",
@@ -17,7 +17,7 @@
1717
"validateOnSynth": false,
1818
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
1919
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
20-
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/f2bf64943c8612dfbd52471095c4b141d6c458592f9416621609658bc7935827.json",
20+
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/209ced6e70ec9b3c3a5387896ca7c4942afced90ed5eb6045cc8f392776ae7ce.json",
2121
"requiresBootstrapStackVersion": 6,
2222
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
2323
"additionalDependencies": [
@@ -99,12 +99,6 @@
9999
"data": "BlueGreenErrors60C27452"
100100
}
101101
],
102-
"/aws-cdk-codedeploy-lambda/BlueGreenDeployment/Application/Resource": [
103-
{
104-
"type": "aws:cdk:logicalId",
105-
"data": "BlueGreenDeploymentApplication36C892C0"
106-
}
107-
],
108102
"/aws-cdk-codedeploy-lambda/BlueGreenDeployment/ServiceRole/Resource": [
109103
{
110104
"type": "aws:cdk:logicalId",
@@ -117,12 +111,42 @@
117111
"data": "BlueGreenDeploymentServiceRoleDefaultPolicy7008FB0A"
118112
}
119113
],
114+
"/aws-cdk-codedeploy-lambda/BlueGreenDeployment/Application/Resource": [
115+
{
116+
"type": "aws:cdk:logicalId",
117+
"data": "BlueGreenDeploymentApplication36C892C0"
118+
}
119+
],
120120
"/aws-cdk-codedeploy-lambda/BlueGreenDeployment/Resource": [
121121
{
122122
"type": "aws:cdk:logicalId",
123123
"data": "BlueGreenDeployment5C188134"
124124
}
125125
],
126+
"/aws-cdk-codedeploy-lambda/SecondAlias/Resource": [
127+
{
128+
"type": "aws:cdk:logicalId",
129+
"data": "SecondAlias33D63566"
130+
}
131+
],
132+
"/aws-cdk-codedeploy-lambda/SecondDeployment/ServiceRole/Resource": [
133+
{
134+
"type": "aws:cdk:logicalId",
135+
"data": "SecondDeploymentServiceRoleAFF1ECD5"
136+
}
137+
],
138+
"/aws-cdk-codedeploy-lambda/SecondDeployment/Application/Resource": [
139+
{
140+
"type": "aws:cdk:logicalId",
141+
"data": "SecondDeploymentApplication1F8C51FE"
142+
}
143+
],
144+
"/aws-cdk-codedeploy-lambda/SecondDeployment/Resource": [
145+
{
146+
"type": "aws:cdk:logicalId",
147+
"data": "SecondDeploymentC270A23D"
148+
}
149+
],
126150
"/aws-cdk-codedeploy-lambda/BootstrapVersion": [
127151
{
128152
"type": "aws:cdk:logicalId",

0 commit comments

Comments
 (0)