Skip to content

Commit

Permalink
feat(aws-wafwebacl-apigateway): created new construct (#366)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
mickychetta and root committed Sep 17, 2021
1 parent 42a7de6 commit ee143ca
Show file tree
Hide file tree
Showing 29 changed files with 7,232 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .viperlightignore
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,7 @@ source/patterns/@aws-solutions-constructs/aws-lambda-sagemakerendpoint/test/test
source/patterns/@aws-solutions-constructs/aws-lambda-sagemakerendpoint/test/test-helper.ts:81
source/patterns/@aws-solutions-constructs/aws-lambda-sagemakerendpoint/test/test-helper.ts:84
source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/integ.existing-s3-bucket.expected.json:33
source/patterns/@aws-solutions-constructs/aws-wafwebacl-apigateway/test/integ.wafwebacl-apigateway-iot.expected.json:265
source/patterns/@aws-solutions-constructs/aws-wafwebacl-apigateway/test/integ.existing-waf-to-multiple-gateways.expected.json:814
# This is a test case
source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/test.kinesisstream-gluejob.test.ts:127
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
lib/*.js
test/*.js
*.d.ts
coverage
test/lambda/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
lib/*.js
test/*.js
*.js.map
*.d.ts
node_modules
*.generated.ts
dist
.jsii

.LAST_BUILD
.nyc_output
coverage
.nycrc
.LAST_PACKAGE
*.snk
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Exclude typescript source and config
*.ts
tsconfig.json
coverage
.nyc_output
*.tgz
*.snk
*.tsbuildinfo

# Include javascript files and typescript declarations
!*.js
!*.d.ts

# Exclude jsii outdir
dist

# Include .jsii
!.jsii

# Include .jsii
!.jsii
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# aws-wafwebacl-apigateway module
<!--BEGIN STABILITY BANNER-->

---

![Stability: Experimental](https://img.shields.io/badge/stability-Experimental-important.svg?style=for-the-badge)

> All classes are under active development and subject to non-backward compatible changes or removal in any
> future version. These are not subject to the [Semantic Versioning](https://semver.org/) model.
> 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.
---
<!--END STABILITY BANNER-->

| **Reference Documentation**:| <span style="font-weight: normal">https://docs.aws.amazon.com/solutions/latest/constructs/</span>|
|:-------------|:-------------|
<div style="height:8px"></div>


| **Language** | **Package** |
|:-------------|-----------------|
|![Python Logo](https://docs.aws.amazon.com/cdk/api/latest/img/python32.png) Python|`aws_solutions_constructs.aws_wafwebacl_apigateway`|
|![Typescript Logo](https://docs.aws.amazon.com/cdk/api/latest/img/typescript32.png) Typescript|`@aws-solutions-constructs/aws-wafwebacl-apigateway`|
|![Java Logo](https://docs.aws.amazon.com/cdk/api/latest/img/java32.png) Java|`software.amazon.awsconstructs.services.wafwebaclapigateway`|

## Overview
This AWS Solutions Construct implements an AWS WAF web ACL connected to Amazon API Gateway REST API.

Here is a minimal deployable pattern definition in Typescript:

``` typescript
import * as api from '@aws-cdk/aws-apigateway';
import * as lambda from "@aws-cdk/aws-lambda";
import { ApiGatewayToLambda } from '@aws-solutions-constructs/aws-apigateway-lambda';
import { WafwebaclToApiGatewayProps, WafwebaclToApiGateway } from "@aws-solutions-constructs/aws-wafwebacl-apigateway";

const apiGatewayToLambda = new ApiGatewayToLambda(this, 'ApiGatewayToLambdaPattern', {
lambdaFunctionProps: {
runtime: lambda.Runtime.NODEJS_14_X,
handler: 'index.handler',
code: lambda.Code.fromAsset(`lambda`)
}
});

// This construct can only be attached to a configured API Gateway.
new WafwebaclToApiGateway(this, 'test-wafwebacl-apigateway', {
existingApiGatewayInterface: apiGatewayToLambda.apiGateway
});
```

## Initializer

``` text
new WafwebaclToApiGateway(scope: Construct, id: string, props: WafwebaclToApiGatewayProps);
```

_Parameters_

* scope [`Construct`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_core.Construct.html)
* id `string`
* props [`WafwebaclToApiGatewayProps`](#pattern-construct-props)

## Pattern Construct Props

| **Name** | **Type** | **Description** |
|:-------------|:----------------|-----------------|
|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.*|
|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.|
|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.|

## Pattern Properties

| **Name** | **Type** | **Description** |
|:-------------|:----------------|-----------------|
|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.|
|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. |

## Default settings

Out of the box implementation of the Construct without any override will set the following defaults:

### AWS WAF
* 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).
* AWSManagedRulesBotControlRuleSet
* AWSManagedRulesKnownBadInputsRuleSet
* AWSManagedRulesCommonRuleSet
* AWSManagedRulesAnonymousIpList
* AWSManagedRulesAmazonIpReputationList
* AWSManagedRulesAdminProtectionRuleSet
* AWSManagedRulesSQLiRuleSet

*Note that the default rules can be replaced by specifying the rules property of CfnWebACLProps*
* Send metrics to Amazon CloudWatch

### Amazon API Gateway
* User provided API Gateway object is used as-is

## Architecture
![Architecture Diagram](architecture.png)

***
&copy; Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/

// Imports
import * as api from '@aws-cdk/aws-apigateway';
import * as waf from '@aws-cdk/aws-wafv2';
import * as defaults from '@aws-solutions-constructs/core';
// Note: To ensure CDKv2 compatibility, keep the import statement for Construct separate
import { Construct, Stack } from '@aws-cdk/core';

/**
* @summary The properties for the WafwebaclToApiGateway class.
*/
export interface WafwebaclToApiGatewayProps {
/**
* The existing API Gateway instance that will be protected with the WAF web ACL.
*/
readonly existingApiGatewayInterface: api.IRestApi,
/**
* Existing instance of a WAF web ACL, an error will occur if this and props is set
*/
readonly existingWebaclObj?: waf.CfnWebACL,
/**
* Optional user-provided props to override the default props for the AWS WAF web ACL.
*
* @default - Default properties are used.
*/
readonly webaclProps?: waf.CfnWebACLProps,
}

/**
* @summary The WafwebaclToApiGateway class.
*/
export class WafwebaclToApiGateway extends Construct {
public readonly webacl: waf.CfnWebACL;
public readonly apiGateway: api.IRestApi;
/**
* @summary Constructs a new instance of the WafwebaclToApiGateway class.
* @param {cdk.App} scope - represents the scope for all the resources.
* @param {string} id - this is a a scope-unique id.
* @param {WafwebaclToApiGatewayProps} props - user provided props for the construct.
* @access public
*/
constructor(scope: Construct, id: string, props: WafwebaclToApiGatewayProps) {
super(scope, id);
defaults.CheckProps(props);

// Build the Web ACL
this.webacl = defaults.buildWebacl(this, 'REGIONAL', {
existingWebaclObj: props.existingWebaclObj,
webaclProps: props.webaclProps,
});

const resourceArn = `arn:aws:apigateway:${Stack.of(scope).region}::/restapis/${props.existingApiGatewayInterface.restApiId}/stages/${props.existingApiGatewayInterface.deploymentStage.stageName}`;

// Setup the Web ACL Association
new waf.CfnWebACLAssociation(scope, `${id}-WebACLAssociation`, {
webAclArn: this.webacl.attrArn,
resourceArn
});

this.apiGateway = props.existingApiGatewayInterface;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
{
"name": "@aws-solutions-constructs/aws-wafwebacl-apigateway",
"version": "0.0.0",
"description": "CDK constructs for defining an AWS web WAF connected to Amazon API Gateway REST API.",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/awslabs/aws-solutions-constructs.git",
"directory": "source/patterns/@aws-solutions-constructs/aws-wafwebacl-apigateway"
},
"author": {
"name": "Amazon Web Services",
"url": "https://aws.amazon.com",
"organization": true
},
"license": "Apache-2.0",
"scripts": {
"build": "tsc -b .",
"lint": "eslint -c ../eslintrc.yml --ext=.js,.ts . && tslint --project .",
"lint-fix": "eslint -c ../eslintrc.yml --ext=.js,.ts --fix .",
"test": "jest --coverage",
"clean": "tsc -b --clean",
"watch": "tsc -b -w",
"integ": "cdk-integ",
"integ-assert": "cdk-integ-assert",
"integ-no-clean": "cdk-integ --no-clean",
"jsii": "jsii",
"jsii-pacmak": "jsii-pacmak",
"build+lint+test": "npm run jsii && npm run lint && npm test && npm run integ-assert",
"snapshot-update": "npm run jsii && npm test -- -u && npm run integ-assert"
},
"jsii": {
"outdir": "dist",
"targets": {
"java": {
"package": "software.amazon.awsconstructs.services.wafwebaclapigateway",
"maven": {
"groupId": "software.amazon.awsconstructs",
"artifactId": "wafwebaclapigateway"
}
},
"dotnet": {
"namespace": "Amazon.Constructs.AWS.WafwebaclApiGateway",
"packageId": "Amazon.Constructs.AWS.WafwebaclApiGateway",
"signAssembly": true,
"iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png"
},
"python": {
"distName": "aws-solutions-constructs.aws-wafwebacl-apigateway",
"module": "aws_solutions_constructs.aws_wafwebacl_apigateway"
}
}
},
"dependencies": {
"@aws-cdk/aws-apigateway": "0.0.0",
"@aws-cdk/aws-autoscaling": "0.0.0",
"@aws-cdk/aws-ec2": "0.0.0",
"@aws-cdk/aws-elasticloadbalancingv2": "0.0.0",
"@aws-cdk/aws-wafv2": "0.0.0",
"@aws-cdk/core": "0.0.0",
"@aws-cdk/aws-lambda": "0.0.0",
"@aws-solutions-constructs/core": "0.0.0",
"@aws-solutions-constructs/aws-apigateway-lambda": "0.0.0",
"@aws-solutions-constructs/aws-apigateway-dynamodb": "0.0.0",
"@aws-solutions-constructs/aws-apigateway-iot": "0.0.0",
"@aws-solutions-constructs/aws-apigateway-kinesisstreams": "0.0.0",
"@aws-solutions-constructs/aws-apigateway-sagemakerendpoint": "0.0.0",
"@aws-solutions-constructs/aws-apigateway-sqs": "0.0.0",
"constructs": "^3.2.0"
},
"devDependencies": {
"@aws-cdk/assert": "0.0.0",
"@types/jest": "^26.0.22",
"@types/node": "^10.3.0"
},
"jest": {
"moduleFileExtensions": [
"js"
],
"coverageReporters": [
"text",
[
"lcov",
{
"projectRoot": "../../../../"
}
]
]
},
"peerDependencies": {
"@aws-cdk/aws-apigateway": "0.0.0",
"@aws-cdk/aws-autoscaling": "0.0.0",
"@aws-cdk/aws-ec2": "0.0.0",
"@aws-cdk/aws-elasticloadbalancingv2": "0.0.0",
"@aws-cdk/aws-wafv2": "0.0.0",
"@aws-cdk/core": "0.0.0",
"@aws-cdk/aws-lambda": "0.0.0",
"@aws-solutions-constructs/core": "0.0.0",
"@aws-solutions-constructs/aws-apigateway-lambda": "0.0.0",
"@aws-solutions-constructs/aws-apigateway-dynamodb": "0.0.0",
"@aws-solutions-constructs/aws-apigateway-iot": "0.0.0",
"@aws-solutions-constructs/aws-apigateway-kinesisstreams": "0.0.0",
"@aws-solutions-constructs/aws-apigateway-sagemakerendpoint": "0.0.0",
"@aws-solutions-constructs/aws-apigateway-sqs": "0.0.0",
"constructs": "^3.2.0"
},
"keywords": [
"aws",
"cdk",
"awscdk",
"AWS Solutions Constructs",
"AWS WAF Web ACL",
"Amazon API Gateway"
]
}
Loading

0 comments on commit ee143ca

Please sign in to comment.