Skip to content

Commit

Permalink
feat(apigatewayv2-integrations): http private integrations - tls conf…
Browse files Browse the repository at this point in the history
…ig (aws#15469)

Adds the option to specify tlsConfig for `AWS::ApiGatewayV2::Integration` resources, to enable use of HTTPS when configuring private integrations.

closes aws#14036

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
dan-lind authored and TikiTDO committed Aug 3, 2021
1 parent 1ce02ae commit 44c1baf
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export class HttpAlbIntegration extends HttpPrivateIntegration {
connectionType: this.connectionType,
connectionId: vpcLink.vpcLinkId,
uri: this.props.listener.listenerArn,
secureServerName: this.props.secureServerName,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,12 @@ export interface HttpPrivateIntegrationOptions {
* @default HttpMethod.ANY
*/
readonly method?: HttpMethod;
}

/**
* Specifies the server name to verified by HTTPS when calling the backend integration
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigatewayv2-integration-tlsconfig.html
* @default undefined private integration traffic will use HTTP protocol
*/

readonly secureServerName?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export class HttpNlbIntegration extends HttpPrivateIntegration {
connectionType: this.connectionType,
connectionId: vpcLink.vpcLinkId,
uri: this.props.listener.listenerArn,
secureServerName: this.props.secureServerName,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class HttpServiceDiscoveryIntegration extends HttpPrivateIntegration {
connectionType: this.connectionType,
connectionId: this.props.vpcLink.vpcLinkId,
uri: this.props.service.serviceArn,
secureServerName: this.props.secureServerName,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,31 @@ describe('HttpAlbIntegration', () => {
routeKey: HttpRouteKey.with('/pets'),
})).toThrow(/vpcLink property must be specified/);
});

test('tlsConfig option is correctly recognized', () => {
// GIVEN
const stack = new Stack();
const vpc = new ec2.Vpc(stack, 'VPC');
const lb = new elbv2.ApplicationLoadBalancer(stack, 'lb', { vpc });
const listener = lb.addListener('listener', { port: 80 });
listener.addTargets('target', { port: 80 });

// WHEN
const api = new HttpApi(stack, 'HttpApi');
new HttpRoute(stack, 'HttpProxyPrivateRoute', {
httpApi: api,
integration: new HttpAlbIntegration({
listener,
secureServerName: 'name-to-verify',
}),
routeKey: HttpRouteKey.with('/pets'),
});

// THEN
expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', {
TlsConfig: {
ServerNameToVerify: 'name-to-verify',
},
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,31 @@ describe('HttpNlbIntegration', () => {
routeKey: HttpRouteKey.with('/pets'),
})).toThrow(/vpcLink property must be specified/);
});

test('tlsConfig option is correctly recognized', () => {
// GIVEN
const stack = new Stack();
const vpc = new ec2.Vpc(stack, 'VPC');
const lb = new elbv2.NetworkLoadBalancer(stack, 'lb', { vpc });
const listener = lb.addListener('listener', { port: 80 });
listener.addTargets('target', { port: 80 });

// WHEN
const api = new HttpApi(stack, 'HttpApi');
new HttpRoute(stack, 'HttpProxyPrivateRoute', {
httpApi: api,
integration: new HttpNlbIntegration({
listener,
secureServerName: 'name-to-verify',
}),
routeKey: HttpRouteKey.with('/pets'),
});

// THEN
expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', {
TlsConfig: {
ServerNameToVerify: 'name-to-verify',
},
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,35 @@ describe('HttpServiceDiscoveryIntegration', () => {
routeKey: HttpRouteKey.with('/pets'),
})).toThrow(/vpcLink property is mandatory/);
});

test('tlsConfig option is correctly recognized', () => {
// GIVEN
const stack = new Stack();
const vpc = new ec2.Vpc(stack, 'VPC');
const vpcLink = new VpcLink(stack, 'VpcLink', { vpc });
const namespace = new servicediscovery.PrivateDnsNamespace(stack, 'Namespace', {
name: 'foobar.com',
vpc,
});
const service = namespace.createService('Service');

// WHEN
const api = new HttpApi(stack, 'HttpApi');
new HttpRoute(stack, 'HttpProxyPrivateRoute', {
httpApi: api,
integration: new HttpServiceDiscoveryIntegration({
vpcLink,
service,
secureServerName: 'name-to-verify',
}),
routeKey: HttpRouteKey.with('/pets'),
});

// THEN
expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', {
TlsConfig: {
ServerNameToVerify: 'name-to-verify',
},
});
});
});
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-apigatewayv2/lib/http/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ abstract class HttpApiBase extends ApiBase implements IHttpApi { // note that th
connectionId: config.connectionId,
connectionType: config.connectionType,
payloadFormatVersion: config.payloadFormatVersion,
secureServerName: config.secureServerName,
});
this._integrationCache.saveIntegration(scope, config, integration);

Expand Down
22 changes: 22 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2/lib/http/integration.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable quotes */
import { Resource } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnIntegration } from '../apigatewayv2.generated';
Expand Down Expand Up @@ -120,6 +121,13 @@ export interface HttpIntegrationProps {
* @default - defaults to latest in the case of HttpIntegrationType.LAMBDA_PROXY`, irrelevant otherwise.
*/
readonly payloadFormatVersion?: PayloadFormatVersion;

/**
* Specifies the TLS configuration for a private integration
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigatewayv2-integration-tlsconfig.html
* @default undefined private integration traffic will use HTTP protocol
*/
readonly secureServerName?: string;
}

/**
Expand All @@ -142,6 +150,13 @@ export class HttpIntegration extends Resource implements IHttpIntegration {
connectionType: props.connectionType,
payloadFormatVersion: props.payloadFormatVersion?.version,
});

if (props.secureServerName) {
integ.tlsConfig = {
serverNameToVerify: props.secureServerName,
};
}

this.integrationId = integ.ref;
this.httpApi = props.httpApi;
}
Expand Down Expand Up @@ -215,4 +230,11 @@ export interface HttpRouteIntegrationConfig {
* @default - undefined
*/
readonly payloadFormatVersion: PayloadFormatVersion;

/**
* Specifies the server name to verified by HTTPS when calling the backend integration
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigatewayv2-integration-tlsconfig.html
* @default undefined private integration traffic will use HTTP protocol
*/
readonly secureServerName?: string;
}
5 changes: 5 additions & 0 deletions packages/@aws-cdk/aws-apigatewayv2/test/http/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ describe('HttpRoute', () => {
connectionId: 'some-connection-id',
connectionType: HttpConnectionType.VPC_LINK,
uri: 'some-target-arn',
secureServerName: 'some-server-name',
};
}
}
Expand All @@ -192,7 +193,11 @@ describe('HttpRoute', () => {
IntegrationMethod: 'ANY',
IntegrationUri: 'some-target-arn',
PayloadFormatVersion: '1.0',
TlsConfig: {
ServerNameToVerify: 'some-server-name',
},
});

expect(stack).not.toHaveResource('AWS::ApiGatewayV2::VpcLink');
});

Expand Down

0 comments on commit 44c1baf

Please sign in to comment.