(APIGatewayV2): API Gateway V2 ALB Integration - Multiple Route Creation Failure
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
Hey!
I'm not sure if this is a bug or if I'm misunderstanding something.
Posted to [discussions](https://github.com/aws/aws-cdk/discussions/34666) too, but I did not get any replies, so I created an issue.
I have a routes array (100+ items in it), which contains all routes for my service, but whenever I'm trying to deploy this solution, it will fail with the following error:
```
Unable to retrieve listener port and load balancer DNS name from ELB listener arn [listener-arn]. Please check that ELB listener exists in account [account-id]
```
However, when I only want to deploy, say, 50 routes (not every route at once), it works just fine.
### Regression Issue
- [ ] Select this option if this issue appears to be a regression.
### Last Known Working CDK Library Version
_No response_
### Expected Behavior
It should create all routes correctly without throwing the error:
```
Unable to retrieve listener port and load balancer DNS name from ELB listener arn [listener-arn]. Please check that ELB listener exists in account [account-id]
```
### Current Behavior
It throws
```
Unable to retrieve listener port and load balancer DNS name from ELB listener arn [listener-arn]. Please check that ELB listener exists in account [account-id]
```
but the listener exists, so the error does not make any sense to me.
### Reproduction Steps
```typescript
import * as apigw from 'aws-cdk-lib/aws-apigatewayv2';
import * as apigwInt from 'aws-cdk-lib/aws-apigatewayv2-integrations';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
import { Construct } from 'constructs';
class ApiGatewayWithAlbIntegration extends Construct {
constructor(scope: Construct, id: string) {
super(scope, id);
// Create or import ALB listener
const listener = elbv2.ApplicationListener.fromLookup(this, 'Listener', {
listenerArn: 'arn:aws:elasticloadbalancing:region:account:listener/app/alb/id/id'
});
// Create VPC Link
const vpcLink = new apigw.VpcLink(this, 'VpcLink', {
vpc: vpc
});
// Create HTTP API
const api = new apigw.HttpApi(this, 'Api');
// This works - single route with proxy
const proxyParameterMapping = new apigw.ParameterMapping()
.appendHeader('custom-header', apigw.MappingValue.custom('value'))
.overwritePath(apigw.MappingValue.custom('/$request.path.proxy'));
new apigw.HttpRoute(this, 'ProxyRoute', {
httpApi: api,
routeKey: apigw.HttpRouteKey.with('/{proxy+}', apigw.HttpMethod.ANY),
integration: new apigwInt.HttpAlbIntegration('Integration', listener, {
vpcLink,
parameterMapping: proxyParameterMapping
})
});
// This fails - multiple routes in sequence
const routes = [
{ path: '/users', method: apigw.HttpMethod.GET, backendPath: '/api/v1/users' },
{ path: '/users', method: apigw.HttpMethod.POST, backendPath: '/api/v1/users' },
{ path: '/products', method: apigw.HttpMethod.GET, backendPath: '/api/v1/products' },
// ... more routes
];
for (const route of routes) {
// Each route needs its own parameter mapping to forward the correct path
const routeParameterMapping = new apigw.ParameterMapping()
.appendHeader('custom-header', apigw.MappingValue.custom('value'))
.overwritePath(apigw.MappingValue.custom(route.backendPath)); // This is crucial
new apigw.HttpRoute(this, `Route-${route.path}-${route.method}`, {
httpApi: api,
routeKey: apigw.HttpRouteKey.with(route.path, route.method),
integration: new apigwInt.HttpAlbIntegration(
`Integration-${route.path}-${route.method}`,
listener,
{
vpcLink,
parameterMapping: routeParameterMapping,
method: route.method
}
)
});
}
}
}
```
### Possible Solution
- So, deploying in multiple steps is working, but far from ideal.
- The listener exists, so the error does not make any sense to me
- Is this a known limitation with the ALB listener? Or am I throttling the API to retrieve the listener when the HttpAlbIntegration is created?
- Are there best practices for creating multiple routes with ALB integrations that I'm not aware of?
Versions:
- "aws-cdk": "^2.1013.0"
- "aws-cdk-lib": "^2.194.0"
- "constructs": "^10.4.2"
### Additional Information/Context
- I cannot use `{proxy+}` since I have other routes that should not be accessible via this gateway for my service, so I have to specify which exact routes users can access
- I must have different parameter mappings for each route
- Currently, I'm using `{proxy+}` with an authorizer lambda, which just checks the route and forwards it to the service whenever needed, but I thought I didn't need the authorizer lambda for this after all.
### AWS CDK Library version (aws-cdk-lib)
2.194.0
### AWS CDK CLI version
2.1013.0
### Node.js Version
22
### OS
MacOS 15.4.1
### Language
TypeScript
### Language Version
_No response_
### Other information
_No response_
Contributor guide
Research direction
Start by reproducing the failure with the provided TypeScript example using HttpAlbIntegration, HttpRoute, and ApplicationListener.fromLookup, comparing one route with 100+ routes. Trace how the ALB listener is retrieved while integrations are created; done means deploying all routes successfully without the listener error while retaining each route's parameter mapping.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- api, cloud
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100