Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

(elbv2): metrics.(httpCodeElb|httpCodeTarget) doesn't work with GraphWidget #31066

Closed
modosc opened this issue Aug 8, 2024 · 4 comments
Closed
Assignees
Labels
@aws-cdk/aws-elasticloadbalancingv2 Related to Amazon Elastic Load Balancing V2 bug This issue is a bug. p3 response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Comments

@modosc
Copy link

modosc commented Aug 8, 2024

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

@modosc modosc added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Aug 8, 2024
@github-actions github-actions bot added the @aws-cdk/aws-elasticloadbalancingv2 Related to Amazon Elastic Load Balancing V2 label Aug 8, 2024
@ashishdhingra ashishdhingra self-assigned this Aug 12, 2024
@ashishdhingra ashishdhingra added p2 response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. needs-reproduction This issue needs reproduction. and removed needs-triage This issue or PR still needs to be triaged. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. labels Aug 12, 2024
@ashishdhingra
Copy link
Contributor

ashishdhingra commented Aug 12, 2024

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

@ashishdhingra
Copy link
Contributor

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

@ashishdhingra ashishdhingra added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. p3 and removed p2 needs-reproduction This issue needs reproduction. labels Aug 12, 2024
@modosc
Copy link
Author

modosc commented Aug 12, 2024

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.

@modosc modosc closed this as completed Aug 12, 2024
Copy link

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 12, 2024
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
@aws-cdk/aws-elasticloadbalancingv2 Related to Amazon Elastic Load Balancing V2 bug This issue is a bug. p3 response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
Projects
None yet
Development

No branches or pull requests

2 participants