(elbv2): metrics.(httpCodeElb|httpCodeTarget) doesn't work with GraphWidget
modosc opened this issue · comments
Describe the bug
when i deploy a dashboard with this code:
const alb5xxCountMetric =
loadBalancedService.loadBalancer.metrics.httpCodeElb(
HttpCodeElb.HTTP_5XX_COUNT,
)
const targetGroup5xxCountMetric =
loadBalancedService.targetGroup.metrics.httpCodeTarget(
HttpCodeElb.TARGET_5XX_COUNT,
)
// ...
this.dashboard.addWidgets(
new GraphWidget({
left: [alb5xxCountMetric],
width: 6,
title: "LB 5xx Response Count",
leftYAxis: {
min: 0,
},
}),
new GraphWidget({
left: [targetGroup5xxCountMetric],
width: 6,
title: "Target Group 5xx Response Count",
leftYAxis: {
min: 0,
},
}),
i get the following errors:
❌ Deployment failed: Error: The stack named Foobar failed to deploy: UPDATE_ROLLBACK_COMPLETE: Resource handler returned message: "The dashboard body is invalid, there are 2 validation errors:
{
"dataPath": "/widgets/5/properties/metrics/0",
"message": "Should NOT have more than 3 items"
},
{
"dataPath": "/widgets/16/properties/metrics/0",
"message": "Should NOT have more than 3 items"
},
Expected Behavior
this should work out of the box like these (similar) api calls:
// these all work
const albRequestCountMetric =
loadBalancedService.loadBalancer.metrics.requestCount({
period: Duration.minutes(1),
label: "LB Request Count",
})
const targetGroupRequestCountMetric =
loadBalancedService.targetGroup.metrics.requestCount({
period: Duration.minutes(1),
label: "Target Group Request Count",
})
// ...
this.dashboard.addWidgets(
new GraphWidget({
left: [albRequestCountMetric],
width: 6,
title: "LB Request Count",
leftYAxis: {
min: 0,
},
}),
new GraphWidget({
left: [targetGroupRequestCountMetric],
width: 6,
title: "Target Group Request Count",
leftYAxis: {
min: 0,
},
}),
)
Current Behavior
❌ Deployment failed: Error: The stack named Foobar failed to deploy: UPDATE_ROLLBACK_COMPLETE: Resource handler returned message: "The dashboard body is invalid, there are 2 validation errors:
{
"dataPath": "/widgets/5/properties/metrics/0",
"message": "Should NOT have more than 3 items"
},
{
"dataPath": "/widgets/16/properties/metrics/0",
"message": "Should NOT have more than 3 items"
},
Reproduction Steps
i'm unsure how concisely i can reproduce this, and the failure happens at deploy time, not compile time.
loadBalancedService
is an ApplicationLoadBalancedFargateService
so the minimal reproducible steps would be:
import ecsPatterns from "aws-cdk-lib/aws-ecs-patterns"
import {
Dashboard,
TextWidget,
GraphWidget,
Statistic,
Metric,
Stats,
Unit,
} from "aws-cdk-lib/aws-cloudwatch"
import { HttpCodeElb } from "aws-cdk-lib/aws-elasticloadbalancingv2"
const loadBalancedService = new ecsPatterns.ApplicationLoadBalancedFargateService() // with whatever the minimum required values are
const dashboard = new Dashboard(this, "my dashboard")
const alb5xxCountMetric =
loadBalancedService.loadBalancer.metrics.httpCodeElb(
HttpCodeElb.HTTP_5XX_COUNT,
)
const targetGroup5xxCountMetric =
loadBalancedService.targetGroup.metrics.httpCodeTarget(
HttpCodeElb.TARGET_5XX_COUNT,
)
dashboard.addWidgets(
new GraphWidget({
left: [alb5xxCountMetric],
width: 6,
title: "LB 5xx Response Count",
leftYAxis: {
min: 0,
},
}),
new GraphWidget({
left: [targetGroup5xxCountMetric],
width: 6,
title: "Target Group 5xx Response Count",
leftYAxis: {
min: 0,
},
}),
)
Possible Solution
No response
Additional Information/Context
No response
CDK CLI Version
2.136.0 (build 94fd33b)
Framework Version
No response
Node.js Version
v18.18.2
OS
Darwin 23.6.0 Darwin Kernel Version 23.6.0: Mon Jul 29 21:13:04 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6020 arm64
Language
TypeScript
Language Version
No response
Other information
No response
Issue not reproducible using code below, without using ECS patterns (used aws-cdk-lib
version 2.151.0
):
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as cdk from 'aws-cdk-lib';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
export class CdktestStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const cloudwatchDashboard = new cloudwatch.Dashboard(this, 'myDashboard', {
dashboardName: 'MyCloudWatchDashboard'
});
const defaultVpc = ec2.Vpc.fromLookup(this, 'MyDefaultVpc', {
isDefault: true
});
const loadBalancer = new elbv2.ApplicationLoadBalancer(this, 'MyALB', {
vpc: defaultVpc
});
const listener = loadBalancer.addListener('Listener', { port: 80 });
const targetGroup = listener.addTargets('Fleet', { port: 80 });
const alb5xxCountMetric = loadBalancer.metrics.httpCodeElb(elbv2.HttpCodeElb.ELB_5XX_COUNT);
const targetGroup5xxCountMetric = targetGroup.metrics.httpCodeTarget(elbv2.HttpCodeTarget.TARGET_5XX_COUNT);
cloudwatchDashboard.addWidgets(
new cloudwatch.GraphWidget({
left: [alb5xxCountMetric],
width: 6,
title: "LB 5xx Response Count",
leftYAxis: {
min: 0,
}
}),
new cloudwatch.GraphWidget({
left: [targetGroup5xxCountMetric],
width: 6,
title: "Target Group 5xx Response Count",
leftYAxis: {
min: 0,
}
})
);
}
}
The CloudFormation deployment is successful:
[Warning at /CdktestStack/MyALB/Listener/FleetGroup] When creating an empty TargetGroup, you should specify a 'targetType' (this warning may become an error in the future). [ack: @aws-cdk/aws-elbv2:targetGroupSpecifyTargetTypeForEmptyTargetGroup]
✨ Synthesis time: 4.41s
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:
Security Group Changes
┌───┬────────────────────────────────┬─────┬─────────────┬────────────────────┐
│ │ Group │ Dir │ Protocol │ Peer │
├───┼────────────────────────────────┼─────┼─────────────┼────────────────────┤
│ + │ ${MyALB/SecurityGroup.GroupId} │ In │ TCP 80 │ Everyone (IPv4) │
│ + │ ${MyALB/SecurityGroup.GroupId} │ Out │ ICMP 252-86 │ 255.255.255.255/32 │
└───┴────────────────────────────────┴─────┴─────────────┴────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
Do you wish to deploy these changes (y/n)? y
CdktestStack: deploying... [1/1]
CdktestStack: creating CloudFormation changeset...
✅ CdktestStack
✨ Deployment time: 176.24s
Stack ARN:
arn:aws:cloudformation:us-east-2:<<account-id-redacted>>:stack/CdktestStack/6f32a8f0-58e9-11ef-b578-06c88167486b
✨ Total time: 180.65s
Issue not reproducible using ECS patterns as well (used aws-cdk-lib
version 2.151.0
):
import * as cdk from 'aws-cdk-lib';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ecsPatterns from 'aws-cdk-lib/aws-ecs-patterns';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
export class EcsPatternsAlbGraphWidgetStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const loadBalancedService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'MyAlbLoadBalancedfargateService', {
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample')
}
});
const cloudwatchDashboard = new cloudwatch.Dashboard(this, 'myDashboard', {
dashboardName: 'MyCloudWatchDashboard'
});
const alb5xxCountMetric = loadBalancedService.loadBalancer.metrics.httpCodeElb(elbv2.HttpCodeElb.ELB_5XX_COUNT);
const targetGroup5xxCountMetric = loadBalancedService.targetGroup.metrics.httpCodeTarget(elbv2.HttpCodeTarget.TARGET_5XX_COUNT);
cloudwatchDashboard.addWidgets(
new cloudwatch.GraphWidget({
left: [alb5xxCountMetric],
width: 6,
title: "LB 5xx Response Count",
leftYAxis: {
min: 0,
}
}),
new cloudwatch.GraphWidget({
left: [targetGroup5xxCountMetric],
width: 6,
title: "Target Group 5xx Response Count",
leftYAxis: {
min: 0,
}
})
);
}
}
CDK deployment works fine and CloudWatch Dashboard is created:
✨ Synthesis time: 4.24s
EcsPatternsAlbGraphWidgetStack: start: Building ee7de53d64cc9d6248fa6aa550f92358f6c907b5efd6f3298aeab1b5e7ea358a:current_account-current_region
EcsPatternsAlbGraphWidgetStack: success: Built ee7de53d64cc9d6248fa6aa550f92358f6c907b5efd6f3298aeab1b5e7ea358a:current_account-current_region
EcsPatternsAlbGraphWidgetStack: start: Building 4ff152020aafa3a7cc4494ab7de782aa7b0fccbbc575783f0ebbdfc5e3c0bf6c:current_account-current_region
EcsPatternsAlbGraphWidgetStack: success: Built 4ff152020aafa3a7cc4494ab7de782aa7b0fccbbc575783f0ebbdfc5e3c0bf6c:current_account-current_region
EcsPatternsAlbGraphWidgetStack: start: Publishing ee7de53d64cc9d6248fa6aa550f92358f6c907b5efd6f3298aeab1b5e7ea358a:current_account-current_region
EcsPatternsAlbGraphWidgetStack: start: Publishing 4ff152020aafa3a7cc4494ab7de782aa7b0fccbbc575783f0ebbdfc5e3c0bf6c:current_account-current_region
EcsPatternsAlbGraphWidgetStack: success: Published 4ff152020aafa3a7cc4494ab7de782aa7b0fccbbc575783f0ebbdfc5e3c0bf6c:current_account-current_region
EcsPatternsAlbGraphWidgetStack: success: Published ee7de53d64cc9d6248fa6aa550f92358f6c907b5efd6f3298aeab1b5e7ea358a:current_account-current_region
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:
IAM Statement Changes
┌───┬───────────────────────────────────────┬────────┬───────────────────────────────────────┬───────────────────────────────────────┬───────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼───────────────────────────────────────┼────────┼───────────────────────────────────────┼───────────────────────────────────────┼───────────┤
│ + │ ${Custom::VpcRestrictDefaultSGCustomR │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │
│ │ esourceProvider/Role.Arn} │ │ │ │ │
├───┼───────────────────────────────────────┼────────┼───────────────────────────────────────┼───────────────────────────────────────┼───────────┤
│ + │ ${MyAlbLoadBalancedfargateService/Tas │ Allow │ sts:AssumeRole │ Service:ecs-tasks.amazonaws.com │ │
│ │ kDef/ExecutionRole.Arn} │ │ │ │ │
├───┼───────────────────────────────────────┼────────┼───────────────────────────────────────┼───────────────────────────────────────┼───────────┤
│ + │ ${MyAlbLoadBalancedfargateService/Tas │ Allow │ sts:AssumeRole │ Service:ecs-tasks.amazonaws.com │ │
│ │ kDef/TaskRole.Arn} │ │ │ │ │
├───┼───────────────────────────────────────┼────────┼───────────────────────────────────────┼───────────────────────────────────────┼───────────┤
│ + │ ${MyAlbLoadBalancedfargateService/Tas │ Allow │ logs:CreateLogStream │ AWS:${MyAlbLoadBalancedfargateService │ │
│ │ kDef/web/LogGroup.Arn} │ │ logs:PutLogEvents │ /TaskDef/ExecutionRole} │ │
├───┼───────────────────────────────────────┼────────┼───────────────────────────────────────┼───────────────────────────────────────┼───────────┤
│ + │ arn:${AWS::Partition}:ec2:${AWS::Regi │ Allow │ ec2:AuthorizeSecurityGroupEgress │ AWS:${Custom::VpcRestrictDefaultSGCus │ │
│ │ on}:${AWS::AccountId}:security-group/ │ │ ec2:AuthorizeSecurityGroupIngress │ tomResourceProvider/Role} │ │
│ │ ${EcsDefaultClusterMnL3mNNYNVpc7788A5 │ │ ec2:RevokeSecurityGroupEgress │ │ │
│ │ 21.DefaultSecurityGroup} │ │ ec2:RevokeSecurityGroupIngress │ │ │
└───┴───────────────────────────────────────┴────────┴───────────────────────────────────────┴───────────────────────────────────────┴───────────┘
IAM Policy Changes
┌───┬─────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────┐
│ │ Resource │ Managed Policy ARN │
├───┼─────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────┤
│ + │ ${Custom::VpcRestrictDefaultSGCustomResourceProvider/Role} │ {"Fn::Sub":"arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLa │
│ │ │ mbdaBasicExecutionRole"} │
└───┴─────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────┘
Security Group Changes
┌───┬────────────────────────────────────────────────────────────┬─────┬────────────┬────────────────────────────────────────────────────────────┐
│ │ Group │ Dir │ Protocol │ Peer │
├───┼────────────────────────────────────────────────────────────┼─────┼────────────┼────────────────────────────────────────────────────────────┤
│ + │ ${MyAlbLoadBalancedfargateService/LB/SecurityGroup.GroupId │ In │ TCP 80 │ Everyone (IPv4) │
│ │ } │ │ │ │
│ + │ ${MyAlbLoadBalancedfargateService/LB/SecurityGroup.GroupId │ Out │ TCP 80 │ ${MyAlbLoadBalancedfargateService/Service/SecurityGroup.Gr │
│ │ } │ │ │ oupId} │
├───┼────────────────────────────────────────────────────────────┼─────┼────────────┼────────────────────────────────────────────────────────────┤
│ + │ ${MyAlbLoadBalancedfargateService/Service/SecurityGroup.Gr │ In │ TCP 80 │ ${MyAlbLoadBalancedfargateService/LB/SecurityGroup.GroupId │
│ │ oupId} │ │ │ } │
│ + │ ${MyAlbLoadBalancedfargateService/Service/SecurityGroup.Gr │ Out │ Everything │ Everyone (IPv4) │
│ │ oupId} │ │ │ │
└───┴────────────────────────────────────────────────────────────┴─────┴────────────┴────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
Do you wish to deploy these changes (y/n)? y
EcsPatternsAlbGraphWidgetStack: deploying... [1/1]
EcsPatternsAlbGraphWidgetStack: creating CloudFormation changeset...
✅ EcsPatternsAlbGraphWidgetStack
✨ Deployment time: 261.28s
Outputs:
EcsPatternsAlbGraphWidgetStack.MyAlbLoadBalancedfargateServiceLoadBalancerDNSC7BE6DCB = EcsPat-MyAlb-<<id-redacted>>.us-east-2.elb.amazonaws.com
EcsPatternsAlbGraphWidgetStack.MyAlbLoadBalancedfargateServiceServiceURLFE6ACF9F = http://EcsPat-MyAlb-<<id-redacted>>.us-east-2.elb.amazonaws.com
Stack ARN:
arn:aws:cloudformation:us-east-2:<<account-id-redacted>>:stack/EcsPatternsAlbGraphWidgetStack/d7067c20-58eb-11ef-a7b5-06f48749fb8f
✨ Total time: 265.52s
@modosc Somehow, the issue is not reproducible. I noticed that you are using the wrong enum values for httpCodeElb()
and httpCodeTarget()
. Could you try upgrading to latest version of CDK lib?
Thanks,
Ashish
I noticed that you are using the wrong enum values for httpCodeElb() and httpCodeTarget().
@ashishdhingra this is indeed the issue. importing the correct enums resolves this.
i apologize for the noise, thank you for your help.
Comments on closed issues and PRs are hard for our team to see.
If you need help, please open a new issue that references this one.