aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code

Home Page:https://aws.amazon.com/cdk

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

(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.