From a733bd1e983f88b7dacb6969a0dea06e5e8da5e4 Mon Sep 17 00:00:00 2001 From: Kyle H <8424419+khoberg@users.noreply.github.com> Date: Tue, 3 Mar 2020 09:58:50 -0800 Subject: [PATCH] feat(apigateway): DomainName supports SecurityPolicy (#6374) * Pass securityPolicy from API Gateway DomainName to cfnDomainName * Update ApiGateway README with example securityPolicy * DomainName: Add documentation for SecurityPolicy TSL versions, add test for absent securityPolicy * fix tsdoc @default Co-authored-by: Void-Concept <49216983+Void-Concept@users.noreply.github.com> Co-authored-by: Niranjan Jayakar <16217941+nija-at@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- packages/@aws-cdk/aws-apigateway/README.md | 3 +- .../aws-apigateway/lib/domain-name.ts | 20 +++++++- .../aws-apigateway/test/test.domains.ts | 49 ++++++++++++++++++- 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-apigateway/README.md b/packages/@aws-cdk/aws-apigateway/README.md index c7d33102bce74..a2367e302a613 100644 --- a/packages/@aws-cdk/aws-apigateway/README.md +++ b/packages/@aws-cdk/aws-apigateway/README.md @@ -540,7 +540,8 @@ You can also define a `DomainName` resource directly in order to customize the d new apigw.DomainName(this, 'custom-domain', { domainName: 'example.com', certificate: acmCertificateForExampleCom, - endpointType: apigw.EndpointType.EDGE // default is REGIONAL + endpointType: apigw.EndpointType.EDGE, // default is REGIONAL + securityPolicy: apigw.SecurityPolicy.TLS_1_2 }); ``` diff --git a/packages/@aws-cdk/aws-apigateway/lib/domain-name.ts b/packages/@aws-cdk/aws-apigateway/lib/domain-name.ts index 013cc86020cea..ac6126eb50860 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/domain-name.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/domain-name.ts @@ -2,7 +2,17 @@ import * as acm from '@aws-cdk/aws-certificatemanager'; import { Construct, IResource, Resource } from '@aws-cdk/core'; import { CfnDomainName } from './apigateway.generated'; import { BasePathMapping, BasePathMappingOptions } from './base-path-mapping'; -import { EndpointType, IRestApi} from './restapi'; +import { EndpointType, IRestApi } from './restapi'; + +/** + * The minimum version of the SSL protocol that you want API Gateway to use for HTTPS connections. + */ +export enum SecurityPolicy { + /** Cipher suite TLS 1.0 */ + TLS_1_0 = 'TLS_1_0', + /** Cipher suite TLS 1.2 */ + TLS_1_2 = 'TLS_1_2' +} export interface DomainNameOptions { /** @@ -22,6 +32,13 @@ export interface DomainNameOptions { * @default REGIONAL */ readonly endpointType?: EndpointType; + + /** + * The Transport Layer Security (TLS) version + cipher suite for this domain name. + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-domainname.html + * @default SecurityPolicy.TLS_1_0 + */ + readonly securityPolicy?: SecurityPolicy } export interface DomainNameProps extends DomainNameOptions { @@ -90,6 +107,7 @@ export class DomainName extends Resource implements IDomainName { certificateArn: edge ? props.certificate.certificateArn : undefined, regionalCertificateArn: edge ? undefined : props.certificate.certificateArn, endpointConfiguration: { types: [endpointType] }, + securityPolicy: props.securityPolicy }); this.domainName = resource.ref; diff --git a/packages/@aws-cdk/aws-apigateway/test/test.domains.ts b/packages/@aws-cdk/aws-apigateway/test/test.domains.ts index a285b472f3dd9..fd7d3e7e85c2a 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.domains.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.domains.ts @@ -1,5 +1,5 @@ // tslint:disable:object-literal-key-quotes -import { expect, haveResource } from '@aws-cdk/assert'; +import { ABSENT, expect, haveResource } from '@aws-cdk/assert'; import * as acm from '@aws-cdk/aws-certificatemanager'; import { Stack } from '@aws-cdk/core'; import { Test } from 'nodeunit'; @@ -65,6 +65,53 @@ export = { test.done(); }, + 'accepts different security policies'(test: Test) { + // GIVEN + const stack = new Stack(); + const cert = new acm.Certificate(stack, 'Cert', { domainName: 'example.com' }); + + // WHEN + new apigw.DomainName(stack, 'my-domain', { + domainName: 'old.example.com', + certificate: cert, + securityPolicy: apigw.SecurityPolicy.TLS_1_0 + }); + + new apigw.DomainName(stack, 'your-domain', { + domainName: 'new.example.com', + certificate: cert, + securityPolicy: apigw.SecurityPolicy.TLS_1_2 + }); + + new apigw.DomainName(stack, 'default-domain', { + domainName: 'default.example.com', + certificate: cert + }); + + // THEN + expect(stack).to(haveResource('AWS::ApiGateway::DomainName', { + "DomainName": "old.example.com", + "EndpointConfiguration": { "Types": [ "REGIONAL" ] }, + "RegionalCertificateArn": { "Ref": "Cert5C9FAEC1" }, + "SecurityPolicy": "TLS_1_0" + })); + + expect(stack).to(haveResource('AWS::ApiGateway::DomainName', { + "DomainName": "new.example.com", + "EndpointConfiguration": { "Types": [ "REGIONAL" ] }, + "RegionalCertificateArn": { "Ref": "Cert5C9FAEC1" }, + "SecurityPolicy": "TLS_1_2" + })); + + expect(stack).to(haveResource('AWS::ApiGateway::DomainName', { + "DomainName": "default.example.com", + "EndpointConfiguration": { "Types": [ "REGIONAL" ] }, + "RegionalCertificateArn": { "Ref": "Cert5C9FAEC1" }, + "SecurityPolicy": ABSENT + })); + test.done(); + }, + '"mapping" can be used to automatically map this domain to the deployment stage of an API'(test: Test) { // GIVEN const stack = new Stack();