diff --git a/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/.eslintignore b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/.eslintignore new file mode 100644 index 000000000..910cb0513 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/.eslintignore @@ -0,0 +1,4 @@ +lib/*.js +test/*.js +*.d.ts +coverage \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/.gitignore b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/.gitignore new file mode 100644 index 000000000..6773cabd2 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/.gitignore @@ -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 \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/.npmignore b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/.npmignore new file mode 100644 index 000000000..f66791629 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/.npmignore @@ -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 \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/README.md b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/README.md new file mode 100644 index 000000000..bbcd7e292 --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/README.md @@ -0,0 +1,102 @@ +# aws-wafwebacl-alb module + + +--- + +![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. + +--- + + +| **Reference Documentation**:| https://docs.aws.amazon.com/solutions/latest/constructs/| +|:-------------|:-------------| +
+ + +| **Language** | **Package** | +|:-------------|-----------------| +|![Python Logo](https://docs.aws.amazon.com/cdk/api/latest/img/python32.png) Python|`aws_solutions_constructs.aws_wafwebacl_alb`| +|![Typescript Logo](https://docs.aws.amazon.com/cdk/api/latest/img/typescript32.png) Typescript|`@aws-solutions-constructs/aws-wafwebacl-alb`| +|![Java Logo](https://docs.aws.amazon.com/cdk/api/latest/img/java32.png) Java|`software.amazon.awsconstructs.services.wafwebaclalb`| + +## Overview +This AWS Solutions Construct implements an AWS WAF web ACL connected to an Application Load Balancer. + +Here is a minimal deployable pattern definition in Typescript: + +``` typescript +import { Route53ToAlb } from '@aws-solutions-constructs/aws-route53-alb'; +import { WafwebaclToAlbProps, WafwebaclToAlb } from "@aws-solutions-constructs/aws-wafwebacl-alb"; + +// A constructed ALB is required to be attached to the WAF Web ACL. +// In this case, we are using this construct to create one. +const r53ToAlb = new Route53ToAlb(this, 'Route53ToAlbPattern', { + privateHostedZoneProps: { + zoneName: 'www.example.com', + }, + publicApi: false, + logAccessLogs: false +}); + +// This construct can only be attached to a configured Application Load Balancer. +new WafwebaclToAlb(this, 'test-wafwebacl-alb', { + existingLoadBalancerObj: r53ToAlb.loadBalancer +}); +``` + +## Initializer + +``` text +new WafwebaclToAlb(scope: Construct, id: string, props: WafwebaclToAlbProps); +``` + +_Parameters_ + +* scope [`Construct`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_core.Construct.html) +* id `string` +* props [`WafwebaclToAlbProps`](#pattern-construct-props) + +## Pattern Construct Props + +| **Name** | **Type** | **Description** | +|:-------------|:----------------|-----------------| +|existingLoadBalancerObj|[`elbv2.ApplicationLoadBalancer`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-elasticloadbalancingv2.ApplicationLoadBalancer.html)|The existing Application Load Balancer Object that will be protected with the WAF web ACL. *Note that a WAF web ACL can only be added to a configured Application Load Balancer, so this construct only accepts an existing ApplicationLoadBalancer and does not accept applicationLoadBalancerProps.*| +|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.| +|loadBalancer|[`elbv2.ApplicationLoadBalancer`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-elasticloadbalancingv2.ApplicationLoadBalancer.html)|Returns an instance of the Application Load Balancer Object 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 + +### Application Load Balancer +* User provided Application Load Balancer object is used as-is + +## Architecture +![Architecture Diagram](architecture.png) + +*** +© Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/architecture.png b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/architecture.png new file mode 100644 index 000000000..039628bf3 Binary files /dev/null and b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/architecture.png differ diff --git a/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/lib/index.ts new file mode 100644 index 000000000..ce4dbdefa --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/lib/index.ts @@ -0,0 +1,72 @@ +/** + * 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 waf from '@aws-cdk/aws-wafv2'; +import * as elbv2 from "@aws-cdk/aws-elasticloadbalancingv2"; +import * as defaults from '@aws-solutions-constructs/core'; +// Note: To ensure CDKv2 compatibility, keep the import statement for Construct separate +import { Construct } from '@aws-cdk/core'; + +/** + * @summary The properties for the WafwebaclToAlb class. + */ +export interface WafwebaclToAlbProps { + /** + * The existing Application Load Balancer instance that will be protected with the WAF web ACL. + */ + readonly existingLoadBalancerObj: elbv2.ApplicationLoadBalancer, + /** + * 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 WafwebaclToAlb class. + */ +export class WafwebaclToAlb extends Construct { + public readonly webacl: waf.CfnWebACL; + public readonly loadBalancer: elbv2.ApplicationLoadBalancer; + /** + * @summary Constructs a new instance of the WafwebaclToAlb class. + * @param {cdk.App} scope - represents the scope for all the resources. + * @param {string} id - this is a a scope-unique id. + * @param {WafwebaclToAlbProps} props - user provided props for the construct. + * @access public + */ + constructor(scope: Construct, id: string, props: WafwebaclToAlbProps) { + super(scope, id); + defaults.CheckProps(props); + + // Build the Web ACL + this.webacl = defaults.buildWebacl(this, 'REGIONAL', { + existingWebaclObj: props.existingWebaclObj, + webaclProps: props.webaclProps, + }); + + // Setup the Web ACL Association + new waf.CfnWebACLAssociation(scope, `${id}-WebACLAssociation`, { + webAclArn: this.webacl.attrArn, + resourceArn: props.existingLoadBalancerObj.loadBalancerArn + }); + + this.loadBalancer = props.existingLoadBalancerObj; + } +} \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/package.json b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/package.json new file mode 100644 index 000000000..ad4d384fe --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/package.json @@ -0,0 +1,102 @@ +{ + "name": "@aws-solutions-constructs/aws-wafwebacl-alb", + "version": "0.0.0", + "description": "CDK constructs for defining an AWS web WAF connected to an Application Load Balancer.", + "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-alb" + }, + "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.wafwebaclalb", + "maven": { + "groupId": "software.amazon.awsconstructs", + "artifactId": "wafwebaclalb" + } + }, + "dotnet": { + "namespace": "Amazon.Constructs.AWS.WafwebaclAlb", + "packageId": "Amazon.Constructs.AWS.WafwebaclAlb", + "signAssembly": true, + "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png" + }, + "python": { + "distName": "aws-solutions-constructs.aws-wafwebacl-alb", + "module": "aws_solutions_constructs.aws_wafwebacl_alb" + } + } + }, + "dependencies": { + "@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-solutions-constructs/core": "0.0.0", + "@aws-solutions-constructs/aws-route53-alb": "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-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-solutions-constructs/core": "0.0.0", + "@aws-solutions-constructs/aws-route53-alb": "0.0.0", + "constructs": "^3.2.0" + }, + "keywords": [ + "aws", + "cdk", + "awscdk", + "AWS Solutions Constructs", + "AWS WAF Web ACL", + "Application Load Balancer" + ] +} \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/test/integ.no-arguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/test/integ.no-arguments.expected.json new file mode 100644 index 000000000..fb2c3e0ed --- /dev/null +++ b/source/patterns/@aws-solutions-constructs/aws-wafwebacl-alb/test/integ.no-arguments.expected.json @@ -0,0 +1,915 @@ +{ + "Resources": { + "Vpc8378EB38": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "172.168.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc" + } + ] + } + }, + "VpcPublicSubnet1Subnet5C2D37C4": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "172.168.0.0/19", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "no-arguments/Vpc/PublicSubnet1" + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W33", + "reason": "Allow Public Subnets to have MapPublicIpOnLaunch set to true" + } + ] + } + } + }, + "VpcPublicSubnet1RouteTable6C95E38E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1RouteTableAssociation97140677": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } + } + }, + "VpcPublicSubnet1DefaultRoute3DA9E72A": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet1EIPD7E02669": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1NATGateway4D7517AA": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet1EIPD7E02669", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet2Subnet691E08A3": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "172.168.32.0/19", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1b", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "no-arguments/Vpc/PublicSubnet2" + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W33", + "reason": "Allow Public Subnets to have MapPublicIpOnLaunch set to true" + } + ] + } + } + }, + "VpcPublicSubnet2RouteTable94F7E489": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2RouteTableAssociationDD5762D8": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + } + }, + "VpcPublicSubnet2DefaultRoute97F91067": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet2EIP3C605A87": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2NATGateway9182C01D": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet2EIP3C605A87", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet3SubnetBE12F0B6": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "172.168.64.0/19", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1c", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "no-arguments/Vpc/PublicSubnet3" + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W33", + "reason": "Allow Public Subnets to have MapPublicIpOnLaunch set to true" + } + ] + } + } + }, + "VpcPublicSubnet3RouteTable93458DBB": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc/PublicSubnet3" + } + ] + } + }, + "VpcPublicSubnet3RouteTableAssociation1F1EDF02": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet3RouteTable93458DBB" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet3SubnetBE12F0B6" + } + } + }, + "VpcPublicSubnet3DefaultRoute4697774F": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet3RouteTable93458DBB" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet3EIP3A666A23": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc/PublicSubnet3" + } + ] + } + }, + "VpcPublicSubnet3NATGateway7640CD1D": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet3SubnetBE12F0B6" + }, + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet3EIP3A666A23", + "AllocationId" + ] + }, + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc/PublicSubnet3" + } + ] + } + }, + "VpcPrivateSubnet1Subnet536B997A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "172.168.96.0/19", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "no-arguments/Vpc/PrivateSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableB2C5B500": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc/PrivateSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableAssociation70C59FA6": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + } + } + }, + "VpcPrivateSubnet1DefaultRouteBE02A9ED": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" + } + } + }, + "VpcPrivateSubnet2Subnet3788AAA1": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "172.168.128.0/19", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1b", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "no-arguments/Vpc/PrivateSubnet2" + } + ] + } + }, + "VpcPrivateSubnet2RouteTableA678073B": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc/PrivateSubnet2" + } + ] + } + }, + "VpcPrivateSubnet2RouteTableAssociationA89CAD56": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + } + }, + "VpcPrivateSubnet2DefaultRoute060D2087": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet2NATGateway9182C01D" + } + } + }, + "VpcPrivateSubnet3SubnetF258B56E": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "172.168.160.0/19", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1c", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "no-arguments/Vpc/PrivateSubnet3" + } + ] + } + }, + "VpcPrivateSubnet3RouteTableD98824C7": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc/PrivateSubnet3" + } + ] + } + }, + "VpcPrivateSubnet3RouteTableAssociation16BDDC43": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet3RouteTableD98824C7" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet3SubnetF258B56E" + } + } + }, + "VpcPrivateSubnet3DefaultRoute94B74F0D": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet3RouteTableD98824C7" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet3NATGateway7640CD1D" + } + } + }, + "VpcIGWD7BA715C": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc" + } + ] + } + }, + "VpcVPCGWBF912B6E": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "InternetGatewayId": { + "Ref": "VpcIGWD7BA715C" + } + } + }, + "VpcFlowLogIAMRole6A475D41": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "vpc-flow-logs.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc" + } + ] + } + }, + "VpcFlowLogIAMRoleDefaultPolicy406FB995": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents", + "logs:DescribeLogStreams" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "VpcFlowLogLogGroup7B5C56B9", + "Arn" + ] + } + }, + { + "Action": "iam:PassRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "VpcFlowLogIAMRole6A475D41", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "VpcFlowLogIAMRoleDefaultPolicy406FB995", + "Roles": [ + { + "Ref": "VpcFlowLogIAMRole6A475D41" + } + ] + } + }, + "VpcFlowLogLogGroup7B5C56B9": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "RetentionInDays": 731 + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain", + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W84", + "reason": "By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)" + } + ] + } + } + }, + "VpcFlowLog8FF33A73": { + "Type": "AWS::EC2::FlowLog", + "Properties": { + "ResourceId": { + "Ref": "Vpc8378EB38" + }, + "ResourceType": "VPC", + "TrafficType": "ALL", + "DeliverLogsPermissionArn": { + "Fn::GetAtt": [ + "VpcFlowLogIAMRole6A475D41", + "Arn" + ] + }, + "LogDestinationType": "cloud-watch-logs", + "LogGroupName": { + "Ref": "VpcFlowLogLogGroup7B5C56B9" + }, + "Tags": [ + { + "Key": "Name", + "Value": "no-arguments/Vpc" + } + ] + } + }, + "newlbF396DAF2": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "LoadBalancerAttributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "false" + } + ], + "Scheme": "internal", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "newlbSecurityGroup04195C74", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + }, + { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + }, + { + "Ref": "VpcPrivateSubnet3SubnetF258B56E" + } + ], + "Type": "application" + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W52", + "reason": "This test is explicitly to test the no logging case." + } + ] + } + } + }, + "newlbSecurityGroup04195C74": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Automatically created Security Group for ELB noargumentsnewlb0B076C69", + "SecurityGroupEgress": [ + { + "CidrIp": "255.255.255.255/32", + "Description": "Disallow all traffic", + "FromPort": 252, + "IpProtocol": "icmp", + "ToPort": 86 + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W29", + "reason": "CDK created rule that blocks all traffic." + } + ] + } + } + }, + "testwafwebaclalbtestwafwebaclalbWebACL994469BE": { + "Type": "AWS::WAFv2::WebACL", + "Properties": { + "DefaultAction": { + "Allow": {} + }, + "Scope": "REGIONAL", + "VisibilityConfig": { + "CloudWatchMetricsEnabled": true, + "MetricName": "webACL", + "SampledRequestsEnabled": true + }, + "Rules": [ + { + "Name": "AWS-AWSManagedRulesBotControlRuleSet", + "OverrideAction": { + "None": {} + }, + "Priority": 0, + "Statement": { + "ManagedRuleGroupStatement": { + "Name": "AWSManagedRulesBotControlRuleSet", + "VendorName": "AWS" + } + }, + "VisibilityConfig": { + "CloudWatchMetricsEnabled": true, + "MetricName": "AWSManagedRulesBotControlRuleSet", + "SampledRequestsEnabled": true + } + }, + { + "Name": "AWS-AWSManagedRulesKnownBadInputsRuleSet", + "OverrideAction": { + "None": {} + }, + "Priority": 1, + "Statement": { + "ManagedRuleGroupStatement": { + "Name": "AWSManagedRulesKnownBadInputsRuleSet", + "VendorName": "AWS" + } + }, + "VisibilityConfig": { + "CloudWatchMetricsEnabled": true, + "MetricName": "AWSManagedRulesKnownBadInputsRuleSet", + "SampledRequestsEnabled": true + } + }, + { + "Name": "AWS-AWSManagedRulesCommonRuleSet", + "OverrideAction": { + "None": {} + }, + "Priority": 2, + "Statement": { + "ManagedRuleGroupStatement": { + "Name": "AWSManagedRulesCommonRuleSet", + "VendorName": "AWS" + } + }, + "VisibilityConfig": { + "CloudWatchMetricsEnabled": true, + "MetricName": "AWSManagedRulesCommonRuleSet", + "SampledRequestsEnabled": true + } + }, + { + "Name": "AWS-AWSManagedRulesAnonymousIpList", + "OverrideAction": { + "None": {} + }, + "Priority": 3, + "Statement": { + "ManagedRuleGroupStatement": { + "Name": "AWSManagedRulesAnonymousIpList", + "VendorName": "AWS" + } + }, + "VisibilityConfig": { + "CloudWatchMetricsEnabled": true, + "MetricName": "AWSManagedRulesAnonymousIpList", + "SampledRequestsEnabled": true + } + }, + { + "Name": "AWS-AWSManagedRulesAmazonIpReputationList", + "OverrideAction": { + "None": {} + }, + "Priority": 4, + "Statement": { + "ManagedRuleGroupStatement": { + "Name": "AWSManagedRulesAmazonIpReputationList", + "VendorName": "AWS" + } + }, + "VisibilityConfig": { + "CloudWatchMetricsEnabled": true, + "MetricName": "AWSManagedRulesAmazonIpReputationList", + "SampledRequestsEnabled": true + } + }, + { + "Name": "AWS-AWSManagedRulesAdminProtectionRuleSet", + "OverrideAction": { + "None": {} + }, + "Priority": 5, + "Statement": { + "ManagedRuleGroupStatement": { + "Name": "AWSManagedRulesAdminProtectionRuleSet", + "VendorName": "AWS" + } + }, + "VisibilityConfig": { + "CloudWatchMetricsEnabled": true, + "MetricName": "AWSManagedRulesAdminProtectionRuleSet", + "SampledRequestsEnabled": true + } + }, + { + "Name": "AWS-AWSManagedRulesSQLiRuleSet", + "OverrideAction": { + "None": {} + }, + "Priority": 6, + "Statement": { + "ManagedRuleGroupStatement": { + "Name": "AWSManagedRulesSQLiRuleSet", + "VendorName": "AWS" + } + }, + "VisibilityConfig": { + "CloudWatchMetricsEnabled": true, + "MetricName": "AWSManagedRulesSQLiRuleSet", + "SampledRequestsEnabled": true + } + } + ] + } + }, + "testwafwebaclalbWebACLAssociation": { + "Type": "AWS::WAFv2::WebACLAssociation", + "Properties": { + "ResourceArn": { + "Ref": "newlbF396DAF2" + }, + "WebACLArn": { + "Fn::GetAtt": [ + "testwafwebaclalbtestwafwebaclalbWebACL994469BE", + "Arn" + ] + } + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value