Skip to content

Commit

Permalink
feat: convenience method for ALB redirects (#9913)
Browse files Browse the repository at this point in the history
After the feedback I received for my latest addition of the redirect method to the ÀpplicationLoadBalancerFargateService` I propose a convenience method for the ALB to create redirects.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
hoegertn committed Sep 1, 2020
1 parent 745922a commit 5bed08a
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 1 deletion.
13 changes: 13 additions & 0 deletions packages/@aws-cdk/aws-elasticloadbalancingv2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,19 @@ listener.addAction('DefaultAction', {
});
```

If you just want to redirect all incoming traffic on one port to another port, you can use the following code:

```ts
lb.addRedirect({
sourceProtocol: elbv2.ApplicationProtocol.HTTPS,
sourcePort: 8443,
targetProtocol: elbv2.ApplicationProtocol.HTTP,
targetPort: 8080,
});
```

If you do not provide any options for this method, it redirects HTTP port 80 to HTTPS port 443.

### Defining a Network Load Balancer

Network Load Balancers are defined in a similar way to Application Load
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
import * as ec2 from '@aws-cdk/aws-ec2';
import { Construct, Duration, Lazy, Resource } from '@aws-cdk/core';
import { BaseLoadBalancer, BaseLoadBalancerProps, ILoadBalancerV2 } from '../shared/base-load-balancer';
import { IpAddressType } from '../shared/enums';
import { IpAddressType, ApplicationProtocol } from '../shared/enums';
import { ApplicationListener, BaseApplicationListenerProps } from './application-listener';
import { ListenerAction } from './application-listener-action';

/**
* Properties for defining an Application Load Balancer
Expand Down Expand Up @@ -88,6 +89,24 @@ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplic
});
}

/**
* Add a redirection listener to this load balancer
*/
public addRedirect(props: ApplicationLoadBalancerRedirectConfig = {}): ApplicationListener {
const sourcePort = props.sourcePort ?? 80;
const targetPort = (props.targetPort ?? 443).toString();
return this.addListener(`Redirect${sourcePort}To${targetPort}`, {
protocol: props.sourceProtocol ?? ApplicationProtocol.HTTP,
port: sourcePort,
open: true,
defaultAction: ListenerAction.redirect({
port: targetPort,
protocol: props.targetProtocol ?? ApplicationProtocol.HTTPS,
permanent: true,
}),
});
}

/**
* Return the given named metric for this Application Load Balancer
*
Expand Down Expand Up @@ -571,3 +590,38 @@ class ImportedApplicationLoadBalancer extends Resource implements IApplicationLo
throw new Error(`'loadBalancerDnsName' was not provided when constructing Application Load Balancer ${this.node.path} from attributes`);
}
}

/**
* Properties for a redirection config
*/
export interface ApplicationLoadBalancerRedirectConfig {

/**
* The protocol of the listener being created
*
* @default HTTP
*/
readonly sourceProtocol?: ApplicationProtocol;

/**
* The port number to listen to
*
* @default 80
*/
readonly sourcePort?: number;

/**
* The protocol of the redirection target
*
* @default HTTPS
*/
readonly targetProtocol?: ApplicationProtocol;

/**
* The port number to redirect to
*
* @default 443
*/
readonly targetPort?: number;

}
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,68 @@ describe('tests', () => {
});
});

test('Can add simple redirect responses', () => {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'VPC');
const lb = new elbv2.ApplicationLoadBalancer(stack, 'LoadBalancer', {
vpc,
});

// WHEN
lb.addRedirect();

// THEN
expect(stack).toHaveResource('AWS::ElasticLoadBalancingV2::Listener', {
Port: 80,
Protocol: 'HTTP',
DefaultActions: [
{
RedirectConfig: {
Port: '443',
Protocol: 'HTTPS',
StatusCode: 'HTTP_301',
},
Type: 'redirect',
},
],
});
});

test('Can add simple redirect responses with custom values', () => {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'VPC');
const lb = new elbv2.ApplicationLoadBalancer(stack, 'LoadBalancer', {
vpc,
});

// WHEN
const listener = lb.addRedirect({
sourceProtocol: elbv2.ApplicationProtocol.HTTPS,
sourcePort: 8443,
targetProtocol: elbv2.ApplicationProtocol.HTTP,
targetPort: 8080,
});
listener.addCertificateArns('ListenerCertificateX', ['cert3']);

// THEN
expect(stack).toHaveResource('AWS::ElasticLoadBalancingV2::Listener', {
Port: 8443,
Protocol: 'HTTPS',
DefaultActions: [
{
RedirectConfig: {
Port: '8080',
Protocol: 'HTTP',
StatusCode: 'HTTP_301',
},
Type: 'redirect',
},
],
});
});

test('Can configure deregistration_delay for targets', () => {
// GIVEN
const stack = new cdk.Stack();
Expand Down

0 comments on commit 5bed08a

Please sign in to comment.