Skip to content

Commit ee143ca

Browse files
mickychettaroot
and
root
authored
feat(aws-wafwebacl-apigateway): created new construct (#366)
* created wafwebacl-apigateway construct and tests * added tests for compatible apigateway constructs * added webACL property to construct * updated README for aws-wafwebacl-apigateway * updated viperlight ignore * Updated README to webAcl and deleted existingRule prop * Fixed minor edits of WebAcl to Webacl * updated defaults with default props and add webaclScope param * updated defaultwebacl return type * updated function name to buildWebacl * Updated aws-wafwebacl-gateway construct by removing certain props and defining helper function better * updated multiple waf to use different gateway * updatd viperlightignore * updated viperlightignore * fixed conditions in helper function and unit tests * updated README with wrapManagedRuleSet helper function info * fixed typo in comment * fixed typo in comment * updated tests and fixed README * updated README * fixed paste error in original README * Updated node version in README and add test for existing acl * delete trailing whitespace Co-authored-by: root <[email protected]>
1 parent 42a7de6 commit ee143ca

29 files changed

+7232
-2
lines changed

.viperlightignore

+2
Original file line numberDiff line numberDiff line change
@@ -129,5 +129,7 @@ source/patterns/@aws-solutions-constructs/aws-lambda-sagemakerendpoint/test/test
129129
source/patterns/@aws-solutions-constructs/aws-lambda-sagemakerendpoint/test/test-helper.ts:81
130130
source/patterns/@aws-solutions-constructs/aws-lambda-sagemakerendpoint/test/test-helper.ts:84
131131
source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/integ.existing-s3-bucket.expected.json:33
132+
source/patterns/@aws-solutions-constructs/aws-wafwebacl-apigateway/test/integ.wafwebacl-apigateway-iot.expected.json:265
133+
source/patterns/@aws-solutions-constructs/aws-wafwebacl-apigateway/test/integ.existing-waf-to-multiple-gateways.expected.json:814
132134
# This is a test case
133135
source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/test.kinesisstream-gluejob.test.ts:127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
lib/*.js
2+
test/*.js
3+
*.d.ts
4+
coverage
5+
test/lambda/index.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
lib/*.js
2+
test/*.js
3+
*.js.map
4+
*.d.ts
5+
node_modules
6+
*.generated.ts
7+
dist
8+
.jsii
9+
10+
.LAST_BUILD
11+
.nyc_output
12+
coverage
13+
.nycrc
14+
.LAST_PACKAGE
15+
*.snk
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Exclude typescript source and config
2+
*.ts
3+
tsconfig.json
4+
coverage
5+
.nyc_output
6+
*.tgz
7+
*.snk
8+
*.tsbuildinfo
9+
10+
# Include javascript files and typescript declarations
11+
!*.js
12+
!*.d.ts
13+
14+
# Exclude jsii outdir
15+
dist
16+
17+
# Include .jsii
18+
!.jsii
19+
20+
# Include .jsii
21+
!.jsii
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# aws-wafwebacl-apigateway module
2+
<!--BEGIN STABILITY BANNER-->
3+
4+
---
5+
6+
![Stability: Experimental](https://img.shields.io/badge/stability-Experimental-important.svg?style=for-the-badge)
7+
8+
> All classes are under active development and subject to non-backward compatible changes or removal in any
9+
> future version. These are not subject to the [Semantic Versioning](https://semver.org/) model.
10+
> This means that while you may use them, you may need to update your source code when upgrading to a newer version of this package.
11+
12+
---
13+
<!--END STABILITY BANNER-->
14+
15+
| **Reference Documentation**:| <span style="font-weight: normal">https://docs.aws.amazon.com/solutions/latest/constructs/</span>|
16+
|:-------------|:-------------|
17+
<div style="height:8px"></div>
18+
19+
20+
| **Language** | **Package** |
21+
|:-------------|-----------------|
22+
|![Python Logo](https://docs.aws.amazon.com/cdk/api/latest/img/python32.png) Python|`aws_solutions_constructs.aws_wafwebacl_apigateway`|
23+
|![Typescript Logo](https://docs.aws.amazon.com/cdk/api/latest/img/typescript32.png) Typescript|`@aws-solutions-constructs/aws-wafwebacl-apigateway`|
24+
|![Java Logo](https://docs.aws.amazon.com/cdk/api/latest/img/java32.png) Java|`software.amazon.awsconstructs.services.wafwebaclapigateway`|
25+
26+
## Overview
27+
This AWS Solutions Construct implements an AWS WAF web ACL connected to Amazon API Gateway REST API.
28+
29+
Here is a minimal deployable pattern definition in Typescript:
30+
31+
``` typescript
32+
import * as api from '@aws-cdk/aws-apigateway';
33+
import * as lambda from "@aws-cdk/aws-lambda";
34+
import { ApiGatewayToLambda } from '@aws-solutions-constructs/aws-apigateway-lambda';
35+
import { WafwebaclToApiGatewayProps, WafwebaclToApiGateway } from "@aws-solutions-constructs/aws-wafwebacl-apigateway";
36+
37+
const apiGatewayToLambda = new ApiGatewayToLambda(this, 'ApiGatewayToLambdaPattern', {
38+
lambdaFunctionProps: {
39+
runtime: lambda.Runtime.NODEJS_14_X,
40+
handler: 'index.handler',
41+
code: lambda.Code.fromAsset(`lambda`)
42+
}
43+
});
44+
45+
// This construct can only be attached to a configured API Gateway.
46+
new WafwebaclToApiGateway(this, 'test-wafwebacl-apigateway', {
47+
existingApiGatewayInterface: apiGatewayToLambda.apiGateway
48+
});
49+
```
50+
51+
## Initializer
52+
53+
``` text
54+
new WafwebaclToApiGateway(scope: Construct, id: string, props: WafwebaclToApiGatewayProps);
55+
```
56+
57+
_Parameters_
58+
59+
* scope [`Construct`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_core.Construct.html)
60+
* id `string`
61+
* props [`WafwebaclToApiGatewayProps`](#pattern-construct-props)
62+
63+
## Pattern Construct Props
64+
65+
| **Name** | **Type** | **Description** |
66+
|:-------------|:----------------|-----------------|
67+
|existingApiGatewayInterface|[`api.IRestApi`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-apigateway.IRestApi.html)|The existing API Gateway instance that will be protected with the WAF web ACL. *Note that a WAF web ACL can only be added to a configured API Gateway, so this construct only accepts an existing IRestApi and does not accept apiGatewayProps.*|
68+
|existingWebaclObj?|[`waf.CfnWebACL`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-waf.CfnWebACL.html)|Existing instance of a WAF web ACL, an error will occur if this and props is set.|
69+
|webaclProps?|[`waf.CfnWebACLProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-waf.CfnWebACLProps.html)|Optional user-provided props to override the default props for the AWS WAF web ACL. To use a different collection of managed rule sets, specify a new rules property. Use our [`wrapManagedRuleSet(managedGroupName: string, vendorName: string, priority: number)`](../core/lib/waf-defaults.ts) function from core to create an array entry from each desired managed rule set.|
70+
71+
## Pattern Properties
72+
73+
| **Name** | **Type** | **Description** |
74+
|:-------------|:----------------|-----------------|
75+
|webacl|[`waf.CfnWebACL`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-waf.CfnWebACL.html)|Returns an instance of the waf.CfnWebACL created by the construct.|
76+
|apiGateway|[`api.IRestApi`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-apigateway.IRestApi.html)|Returns an instance of the API Gateway REST API created by the pattern. |
77+
78+
## Default settings
79+
80+
Out of the box implementation of the Construct without any override will set the following defaults:
81+
82+
### AWS WAF
83+
* Deploy a WAF web ACL with 7 [AWS managed rule groups](https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-list.html).
84+
* AWSManagedRulesBotControlRuleSet
85+
* AWSManagedRulesKnownBadInputsRuleSet
86+
* AWSManagedRulesCommonRuleSet
87+
* AWSManagedRulesAnonymousIpList
88+
* AWSManagedRulesAmazonIpReputationList
89+
* AWSManagedRulesAdminProtectionRuleSet
90+
* AWSManagedRulesSQLiRuleSet
91+
92+
*Note that the default rules can be replaced by specifying the rules property of CfnWebACLProps*
93+
* Send metrics to Amazon CloudWatch
94+
95+
### Amazon API Gateway
96+
* User provided API Gateway object is used as-is
97+
98+
## Architecture
99+
![Architecture Diagram](architecture.png)
100+
101+
***
102+
&copy; Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
5+
* with the License. A copy of the License is located at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
10+
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
11+
* and limitations under the License.
12+
*/
13+
14+
// Imports
15+
import * as api from '@aws-cdk/aws-apigateway';
16+
import * as waf from '@aws-cdk/aws-wafv2';
17+
import * as defaults from '@aws-solutions-constructs/core';
18+
// Note: To ensure CDKv2 compatibility, keep the import statement for Construct separate
19+
import { Construct, Stack } from '@aws-cdk/core';
20+
21+
/**
22+
* @summary The properties for the WafwebaclToApiGateway class.
23+
*/
24+
export interface WafwebaclToApiGatewayProps {
25+
/**
26+
* The existing API Gateway instance that will be protected with the WAF web ACL.
27+
*/
28+
readonly existingApiGatewayInterface: api.IRestApi,
29+
/**
30+
* Existing instance of a WAF web ACL, an error will occur if this and props is set
31+
*/
32+
readonly existingWebaclObj?: waf.CfnWebACL,
33+
/**
34+
* Optional user-provided props to override the default props for the AWS WAF web ACL.
35+
*
36+
* @default - Default properties are used.
37+
*/
38+
readonly webaclProps?: waf.CfnWebACLProps,
39+
}
40+
41+
/**
42+
* @summary The WafwebaclToApiGateway class.
43+
*/
44+
export class WafwebaclToApiGateway extends Construct {
45+
public readonly webacl: waf.CfnWebACL;
46+
public readonly apiGateway: api.IRestApi;
47+
/**
48+
* @summary Constructs a new instance of the WafwebaclToApiGateway class.
49+
* @param {cdk.App} scope - represents the scope for all the resources.
50+
* @param {string} id - this is a a scope-unique id.
51+
* @param {WafwebaclToApiGatewayProps} props - user provided props for the construct.
52+
* @access public
53+
*/
54+
constructor(scope: Construct, id: string, props: WafwebaclToApiGatewayProps) {
55+
super(scope, id);
56+
defaults.CheckProps(props);
57+
58+
// Build the Web ACL
59+
this.webacl = defaults.buildWebacl(this, 'REGIONAL', {
60+
existingWebaclObj: props.existingWebaclObj,
61+
webaclProps: props.webaclProps,
62+
});
63+
64+
const resourceArn = `arn:aws:apigateway:${Stack.of(scope).region}::/restapis/${props.existingApiGatewayInterface.restApiId}/stages/${props.existingApiGatewayInterface.deploymentStage.stageName}`;
65+
66+
// Setup the Web ACL Association
67+
new waf.CfnWebACLAssociation(scope, `${id}-WebACLAssociation`, {
68+
webAclArn: this.webacl.attrArn,
69+
resourceArn
70+
});
71+
72+
this.apiGateway = props.existingApiGatewayInterface;
73+
}
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
{
2+
"name": "@aws-solutions-constructs/aws-wafwebacl-apigateway",
3+
"version": "0.0.0",
4+
"description": "CDK constructs for defining an AWS web WAF connected to Amazon API Gateway REST API.",
5+
"main": "lib/index.js",
6+
"types": "lib/index.d.ts",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/awslabs/aws-solutions-constructs.git",
10+
"directory": "source/patterns/@aws-solutions-constructs/aws-wafwebacl-apigateway"
11+
},
12+
"author": {
13+
"name": "Amazon Web Services",
14+
"url": "https://aws.amazon.com",
15+
"organization": true
16+
},
17+
"license": "Apache-2.0",
18+
"scripts": {
19+
"build": "tsc -b .",
20+
"lint": "eslint -c ../eslintrc.yml --ext=.js,.ts . && tslint --project .",
21+
"lint-fix": "eslint -c ../eslintrc.yml --ext=.js,.ts --fix .",
22+
"test": "jest --coverage",
23+
"clean": "tsc -b --clean",
24+
"watch": "tsc -b -w",
25+
"integ": "cdk-integ",
26+
"integ-assert": "cdk-integ-assert",
27+
"integ-no-clean": "cdk-integ --no-clean",
28+
"jsii": "jsii",
29+
"jsii-pacmak": "jsii-pacmak",
30+
"build+lint+test": "npm run jsii && npm run lint && npm test && npm run integ-assert",
31+
"snapshot-update": "npm run jsii && npm test -- -u && npm run integ-assert"
32+
},
33+
"jsii": {
34+
"outdir": "dist",
35+
"targets": {
36+
"java": {
37+
"package": "software.amazon.awsconstructs.services.wafwebaclapigateway",
38+
"maven": {
39+
"groupId": "software.amazon.awsconstructs",
40+
"artifactId": "wafwebaclapigateway"
41+
}
42+
},
43+
"dotnet": {
44+
"namespace": "Amazon.Constructs.AWS.WafwebaclApiGateway",
45+
"packageId": "Amazon.Constructs.AWS.WafwebaclApiGateway",
46+
"signAssembly": true,
47+
"iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png"
48+
},
49+
"python": {
50+
"distName": "aws-solutions-constructs.aws-wafwebacl-apigateway",
51+
"module": "aws_solutions_constructs.aws_wafwebacl_apigateway"
52+
}
53+
}
54+
},
55+
"dependencies": {
56+
"@aws-cdk/aws-apigateway": "0.0.0",
57+
"@aws-cdk/aws-autoscaling": "0.0.0",
58+
"@aws-cdk/aws-ec2": "0.0.0",
59+
"@aws-cdk/aws-elasticloadbalancingv2": "0.0.0",
60+
"@aws-cdk/aws-wafv2": "0.0.0",
61+
"@aws-cdk/core": "0.0.0",
62+
"@aws-cdk/aws-lambda": "0.0.0",
63+
"@aws-solutions-constructs/core": "0.0.0",
64+
"@aws-solutions-constructs/aws-apigateway-lambda": "0.0.0",
65+
"@aws-solutions-constructs/aws-apigateway-dynamodb": "0.0.0",
66+
"@aws-solutions-constructs/aws-apigateway-iot": "0.0.0",
67+
"@aws-solutions-constructs/aws-apigateway-kinesisstreams": "0.0.0",
68+
"@aws-solutions-constructs/aws-apigateway-sagemakerendpoint": "0.0.0",
69+
"@aws-solutions-constructs/aws-apigateway-sqs": "0.0.0",
70+
"constructs": "^3.2.0"
71+
},
72+
"devDependencies": {
73+
"@aws-cdk/assert": "0.0.0",
74+
"@types/jest": "^26.0.22",
75+
"@types/node": "^10.3.0"
76+
},
77+
"jest": {
78+
"moduleFileExtensions": [
79+
"js"
80+
],
81+
"coverageReporters": [
82+
"text",
83+
[
84+
"lcov",
85+
{
86+
"projectRoot": "../../../../"
87+
}
88+
]
89+
]
90+
},
91+
"peerDependencies": {
92+
"@aws-cdk/aws-apigateway": "0.0.0",
93+
"@aws-cdk/aws-autoscaling": "0.0.0",
94+
"@aws-cdk/aws-ec2": "0.0.0",
95+
"@aws-cdk/aws-elasticloadbalancingv2": "0.0.0",
96+
"@aws-cdk/aws-wafv2": "0.0.0",
97+
"@aws-cdk/core": "0.0.0",
98+
"@aws-cdk/aws-lambda": "0.0.0",
99+
"@aws-solutions-constructs/core": "0.0.0",
100+
"@aws-solutions-constructs/aws-apigateway-lambda": "0.0.0",
101+
"@aws-solutions-constructs/aws-apigateway-dynamodb": "0.0.0",
102+
"@aws-solutions-constructs/aws-apigateway-iot": "0.0.0",
103+
"@aws-solutions-constructs/aws-apigateway-kinesisstreams": "0.0.0",
104+
"@aws-solutions-constructs/aws-apigateway-sagemakerendpoint": "0.0.0",
105+
"@aws-solutions-constructs/aws-apigateway-sqs": "0.0.0",
106+
"constructs": "^3.2.0"
107+
},
108+
"keywords": [
109+
"aws",
110+
"cdk",
111+
"awscdk",
112+
"AWS Solutions Constructs",
113+
"AWS WAF Web ACL",
114+
"Amazon API Gateway"
115+
]
116+
}

0 commit comments

Comments
 (0)