Skip to content
New issue

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

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

Already on GitHub? Sign in 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
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
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