aws / aws/aws-cdk

(aws_ecs_patterns): ApplicationLoadBalancedFargateService and NetworkLoadBalancedFargateService fails to become private once configured as public

Open
#33,224 2 comments 0 reactions 0 assignees View on GitHub
@aws-cdk/aws-ec2 @aws-cdk/aws-ecs-patterns bug p3
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

### Describe the bug

I was testing out the CDK with Fargate services and I stumbled across these two constructs.
I tried configuring a sample application using NetworkLoadBalancedFargateService construct using the following code:

```
const fargateService = new NetworkLoadBalancedFargateService(this, "SampleNetworkLoadBalancedFargateService", {
vpc,
taskDefinition: taskDefinition,
minHealthyPercent: 100,
});

fargateService.service.connections.allowFromAnyIpv4(Port.tcp(80), "Allow inbound HTTP traffic");

fargateService.targetGroup.healthCheck = {
port: "80",
protocol: Protocol.TCP,
interval: Duration.seconds(20),
}

const vpcLink = new VpcLink(this, "SampleNodeVpcLink", {
targets: [fargateService.loadBalancer],
})

const integration = new Integration({
type: IntegrationType.HTTP_PROXY,
integrationHttpMethod: "ANY",
options: {
connectionType: ConnectionType.VPC_LINK,
vpcLink: vpcLink,
}
})

const api = new RestApi(this, "SampleNodeApi", {
defaultIntegration: integration,
deploy: true,
restApiName: "SampleNodeApi",
})

api.root.addResource("{proxy+}").addMethod("ANY", integration);
```
This deployed the network load balancer in the public subnet by default. I wanted to make this private so I added the parameter `publicLoadBalancer: false` in the NetworkLoadBalancedFargateService and tried to deploy it again as an update.

This created a new network load balancer and a new VPC link but it couldn't delete the previous load balancer because instead of deleting the VPC link first, the stack attempted to delete the network load balancer itself.

```
Resource handler returned message: "Load balancer 'arn:aws:elasticloadbalancing:eu-west-1:xxxxxxxxxx:loadbalancer/net/EcsCon-Sampl-YR9C1LyxDG1G/ec5eeca8f820165e' cannot be deleted because it is currently associated with another service (Service: ElasticLoadBalancingV2, Status Code: 400, Request ID: 95033b60-7fe2-4bca-bd34-01071c4e674d)" (RequestToken: 37e62d01-0029-18d2-d8d2-01db07df8ac4, HandlerErrorCode: InvalidRequest)
```

### Regression Issue

- [ ] Select this option if this issue appears to be a regression.

### Last Known Working CDK Version

_No response_

### Expected Behavior

It should delete the attach the API Gateway with the new VPC Link integration, then delete the old VPC link and then delete the network load balancer.

### Current Behavior

It tries to delete the network load balancer directly without taking care of it's connections and fails with the error:

```
Resource handler returned message: "Load balancer 'arn:aws:elasticloadbalancing:eu-west-1:xxxxxxxxxx:loadbalancer/net/EcsCon-Sampl-YR9C1LyxDG1G/ec5eeca8f820165e' cannot be deleted because it is currently associated with another service (Service: ElasticLoadBalancingV2, Status Code: 400, Request ID: 95033b60-7fe2-4bca-bd34-01071c4e674d)" (RequestToken: 37e62d01-0029-18d2-d8d2-01db07df8ac4, HandlerErrorCode: InvalidRequest)
```

### Reproduction Steps

Create and deploy a Fargate service using the construct:

```
const fargateService = new NetworkLoadBalancedFargateService(this, "SampleNetworkLoadBalancedFargateService", {
vpc,
taskDefinition: taskDefinition,
minHealthyPercent: 100,
});

fargateService.service.connections.allowFromAnyIpv4(Port.tcp(80), "Allow inbound HTTP traffic");

fargateService.targetGroup.healthCheck = {
port: "80",
protocol: Protocol.TCP,
interval: Duration.seconds(20),
}

const vpcLink = new VpcLink(this, "SampleNodeVpcLink", {
targets: [fargateService.loadBalancer],
})

const integration = new Integration({
type: IntegrationType.HTTP_PROXY,
integrationHttpMethod: "ANY",
options: {
connectionType: ConnectionType.VPC_LINK,
vpcLink: vpcLink,
}
})

const api = new RestApi(this, "SampleNodeApi", {
defaultIntegration: integration,
deploy: true,
restApiName: "SampleNodeApi",
})

api.root.addResource("{proxy+}").addMethod("ANY", integration);
```

Once it is created successfully, add the property `publicLoadBalancer: false` to the NetworkLoadBalancedFargateService like so:

```
const fargateService = new NetworkLoadBalancedFargateService(this, "SampleNetworkLoadBalancedFargateService", {
vpc,
taskDefinition: taskDefinition,
minHealthyPercent: 100,
publicLoadBalancer: false
});
```

### Possible Solution

_No response_

### Additional Information/Context

_No response_

### CDK CLI Version

2.177.0

### Framework Version

_No response_

### Node.js Version

v20.17.0

### OS

Windows

### Language

TypeScript

### Language Version

5.6.2

### Other information

_No response_

Contributor guide

Open the contributing guide

Research direction

Start by examining the NetworkLoadBalancedFargateService and ApplicationLoadBalancedFargateService construct entry points, then trace their load balancer relationships with VpcLink and API Gateway during replacement. Reproduce the update from publicLoadBalancer: true to false and inspect the synthesized resource dependencies; done means the new integration is attached before the old VpcLink and load balancer are deleted.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, typescript
Domain
cloud, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.