aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.72k stars 3.94k forks source link

ElasticLoadBalancingV2: ApplicationLoadBalancer http2.enabled from false to true is ignored in cloudformation #31609

Closed robob4him closed 1 month ago

robob4him commented 2 months ago

Describe the bug

When an ApplicationLoadBalancer routing.http2.enabled attribute is modified from "false" to "true" CDK will remove the attribute with the expectation that "true" will be the default. CloudFormation does not remove the attribute nor does it set the attribute value back to default.

Regression Issue

Last Known Working CDK Version

No response

Expected Behavior

Modifying the attribute value from "false" to "true" modifies the load balancer attribute from "false" to "true"

Current Behavior

Value remains "false" despite the attribute being removed.

Reproduction Steps

New instance of load balancer, http2.enabled set to false; deploy Modify http2 from false to true; deploy

Possible Solution

When http2 is not undefined, reflect string value

Additional Information/Context

No response

CDK CLI Version

2.160.0 (build 7a8ae02)

Framework Version

No response

Node.js Version

v18.19.1

OS

Ubuntu 24.04.1 LTS

Language

.NET

Language Version

.Net 8.0.108

Other information

No response

ashishdhingra commented 2 months ago

Reproducible using code below:

import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
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 vpc = ec2.Vpc.fromLookup(this, 'DefaultVpc', { isDefault: true });
    new elbv2.ApplicationLoadBalancer(this, "TestALB", {
      vpc,
      http2Enabled: false
    });
  }
}

This creates an ALB with HTTP/2 set as Off.

Setting http2Enabled to true thereafter displays the following output when running cdk diff:

Resources
[~] AWS::ElasticLoadBalancingV2::LoadBalancer TestALB TestALB70A5B1F2 
 └─ [~] LoadBalancerAttributes
     └─ @@ -2,9 +2,5 @@
        [ ]   {
        [ ]     "Key": "deletion_protection.enabled",
        [ ]     "Value": "false"
        [-]   },
        [-]   {
        [-]     "Key": "routing.http2.enabled",
        [-]     "Value": "false"
        [ ]   }
        [ ] ]

So it removes the attribute, which is due to check here only sets routing.http2.enabled attribute if property http2Enabled is explicitly set to false.

Running cdk deploy appears to cause CloudFormation stack to be updated, but the ALB's HTTP/2 doesn't get updated. So simply removing the attribute would not reset it to default On. The attribute routing.http2.enabled needs to be explicitly set to true for CloudFormation to change it. This could be verified by using the following property override as a workaround (assuming that the position of routing.http2.enabled in LoadBalancerAttributes collection is known, 2nd in this case):

import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
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 vpc = ec2.Vpc.fromLookup(this, 'DefaultVpc', { isDefault: true });
    const alb = new elbv2.ApplicationLoadBalancer(this, "TestALB", {
      vpc,
      http2Enabled: true
    });

    const cfnLb = alb.node.defaultChild as elbv2.CfnLoadBalancer;
    cfnLb.addPropertyOverride('LoadBalancerAttributes.1.Key', 'routing.http2.enabled');
    cfnLb.addPropertyOverride('LoadBalancerAttributes.1.Value', 'true');
  }
}

Running cdk diff now adds routing.http2.enabled as true in LoadBalancerAttributes:

Resources
[~] AWS::ElasticLoadBalancingV2::LoadBalancer TestALB TestALB70A5B1F2 
 └─ [~] LoadBalancerAttributes
     └─ @@ -2,5 +2,9 @@
        [ ]   {
        [ ]     "Key": "deletion_protection.enabled",
        [ ]     "Value": "false"
        [+]   },
        [+]   {
        [+]     "Key": "routing.http2.enabled",
        [+]     "Value": "true"
        [ ]   }
        [ ] ]

✨  Number of stacks with differences: 1

Deploying it now sets HTTP/2 as On.

github-actions[bot] commented 1 month ago

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[bot] commented 1 month ago

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.