diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/README.md b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/README.md index c410c1e45f9d3..18d7d24e3f5db 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/README.md +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/README.md @@ -193,6 +193,8 @@ If you do not provide any options for this method, it redirects HTTP port 80 to By default all ingress traffic will be allowed on the source port. If you want to be more selective with your ingress rules then set `open: false` and use the listener's `connections` object to selectively grant access to the listener. +**Note**: The `path` parameter must start with a `/`. + ### Application Load Balancer attributes You can modify attributes of Application Load Balancers: diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-listener-action.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-listener-action.ts index 589c3f1f24cb7..9cc89cd125b1c 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-listener-action.ts +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-listener-action.ts @@ -2,7 +2,7 @@ import { Construct, IConstruct } from 'constructs'; import { IApplicationListener } from './application-listener'; import { IApplicationTargetGroup } from './application-target-group'; import { Port } from '../../../aws-ec2'; -import { Duration, SecretValue, Tokenization } from '../../../core'; +import { Duration, SecretValue, Token, Tokenization } from '../../../core'; import { CfnListener, CfnListenerRule } from '../elasticloadbalancingv2.generated'; import { IListenerAction } from '../shared/listener-action'; @@ -115,6 +115,9 @@ export class ListenerAction implements IListenerAction { if ([options.host, options.path, options.port, options.protocol, options.query].findIndex(x => x !== undefined) === -1) { throw new Error('To prevent redirect loops, set at least one of \'protocol\', \'host\', \'port\', \'path\', or \'query\'.'); } + if (options.path && !Token.isUnresolved(options.path) && !options.path.startsWith('/')) { + throw new Error(`Redirect path must start with a \'/\', got: ${options.path}`); + } return new ListenerAction({ type: 'redirect', diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/alb/actions.test.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/alb/actions.test.ts index c3b1d090ceb98..11c804a052032 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/alb/actions.test.ts +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/alb/actions.test.ts @@ -338,4 +338,19 @@ describe('tests', () => { ], }); }); + + test('throw error for invalid path pattern for redirect action', () => { + // GIVEN + const listener = lb.addListener('Listener', { port: 80 }); + + // THEN + expect(() => { + listener.addAction('RedirectAction', { + action: elbv2.ListenerAction.redirect({ + protocol: elbv2.ApplicationProtocol.HTTPS, + path: 'example', + }), + }); + }).toThrow('Redirect path must start with a \'/\', got: example'); + }); });