aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.63k stars 3.91k forks source link

Waf, Waf-v2, Waf-regional documentation #7985

Closed ghost closed 4 years ago

ghost commented 4 years ago

Hey guys, there is a lack of documentation regarding Waf - see #7925. But I could create a working example with api-gateway. Maybe you wanna add it to your docs?

import * as apigateway from "@aws-cdk/aws-apigateway";
import * as wafv2 from "@aws-cdk/aws-wafv2";
import * as cdk from "@aws-cdk/core";

export class WafStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const testApi = new apigateway.RestApi(this, "Test-API", {
      endpointConfiguration: {
        types: [apigateway.EndpointType.REGIONAL],
      },
    });
    testApi.root.addMethod("GET", new apigateway.MockIntegration());

    // @ts-ignore
    const webAcl = new wafv2.CfnWebACL(this, "WebAcl", {
      defaultAction: { allow: {} },
      rules: [
        {
          priority: 1,
          overrideAction: { none: {} },
          visibilityConfig: {
            sampledRequestsEnabled: true,
            cloudWatchMetricsEnabled: true,
            metricName: "AWS-AWSManagedRulesAmazonIpReputationList",
          },
          name: "AWS-AWSManagedRulesAmazonIpReputationList",
          statement: {
            managedRuleGroupStatement: {
              vendorName: "AWS",
              name: "AWSManagedRulesAmazonIpReputationList",
            },
          },
        },
        {
          priority: 2,
          overrideAction: { none: {} },
          visibilityConfig: {
            sampledRequestsEnabled: true,
            cloudWatchMetricsEnabled: true,
            metricName: "AWS-AWSManagedRulesCommonRuleSet",
          },
          name: "AWS-AWSManagedRulesCommonRuleSet",
          statement: {
            managedRuleGroupStatement: {
              vendorName: "AWS",
              name: "AWSManagedRulesCommonRuleSet",
            },
          },
        },
        {
          priority: 3,
          overrideAction: { none: {} },
          visibilityConfig: {
            sampledRequestsEnabled: true,
            cloudWatchMetricsEnabled: true,
            metricName: "AWS-AWSManagedRulesKnownBadInputsRuleSet",
          },
          name: "AWS-AWSManagedRulesKnownBadInputsRuleSet",
          statement: {
            managedRuleGroupStatement: {
              vendorName: "AWS",
              name: "AWSManagedRulesKnownBadInputsRuleSet",
            },
          },
        },
      ],
      scope: "REGIONAL",
      visibilityConfig: {
        sampledRequestsEnabled: true,
        cloudWatchMetricsEnabled: true,
        metricName: "web-acl",
      },
    });

    // Output of 'testApi.arnForExecuteApi(...)': 'arn:aws:execute-api:region:accout-id:api-id/*/*/*'
    // For webAcls we need the following pattern: 'arn:aws:apigateway:region::/restapis/api-id/stages/stage-name'
    // See here: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wafv2-webaclassociation.html#cfn-wafv2-webaclassociation-resourcearn
    const region = cdk.Stack.of(this).region;
    const arn = `arn:aws:apigateway:${region}::/restapis/${testApi.restApiId}/stages/${testApi.deploymentStage.stageName}`;

    // @ts-ignore
    new wafv2.CfnWebACLAssociation(this, "WebAclAssociation", {
      webAclArn: webAcl.attrArn,
      resourceArn: arn,
    });
  }
}

const app = new cdk.App();
new WafStack(app, "Waf-Stack");
rix0rrr commented 4 years ago

Thanks for the example!

An unfortunate truth is that we don't have time to spend on WAF right now, and even though it might sound that any example is better than no example, we also cannot readily accept your code for multiple reasons:

I would heartily recommend that you get this content out there and publish this content under your own name to your own platforms: maybe to a blog, maybe to a GitHub repository or a Gist. But we can't accept it into the upstream repository or docs, however silly that may sound.

Cheers!

bpcrao commented 4 years ago

thanks to @Syy0n

this really saved me a ton of time , I spent 6 hrs wasting on this issue thanks again for this one

I really feel AWS has poor examples on WAF - APIGW association and for some reason

This works

  const arn = `arn:aws:apigateway:${region}::/restapis/${this.appGateway.restApiId}/stages/${this.appAPIGateway.deploymentStage.stageName}`;
            console.log(arn);
            new wafv2.CfnWebACLAssociation(this, "WebAclAssociation", {
              webAclArn: props.regionalACLARN,
              resourceArn: arn,
            });

This did not work

new wafv2.CfnWebACLAssociation(this, 'WebAclAssociation', {
          webAclArn: props.regionalACLARN,
          resourceArn: `arn:aws:apigateway:${region}::/restapis/${this.appGateway.restApiId}/stages/${this.appAPIGateway.deploymentStage.stageName}`
        })
NickTheSecurityDude commented 3 years ago

I second adding non-L1 constructs and examples for WAFv2.

And for those of you who use Python, I made an example here:
https://raw.githubusercontent.com/NickTheSecurityDude/alb-asg-waf-cdk/main/stacks/wafv2_stack.py

gbooth27 commented 3 years ago

Yeah having some sort of example code would be very helpful

DC4JG commented 3 years ago

I wasted hours figuring out how to connect wafv2 rules to an API gateway via Python CDK. Example below for future developers.

# relevant imports
from aws_cdk import aws_apigateway as gateway
from aws_cdk import aws_wafv2 as waf2

api = gateway.LambdaRestApi(
  # configuration
)

webACL = waf2.CfnWebACL(
  # configuration
)

waf2.CfnWebACLAssociation(
  self, # or other applicable scope
  "foo", # identifier string of your choice
  web_acl_arn=webACL.attr_arn,
  resource_arn=f"arn:aws:apigateway:{api.env.region}::/restapis/{api.rest_api_id}/stages/{api.deployment_stage.stage_name}"
)
skinny85 commented 3 years ago

@DC4JG thanks for posting that! Any chance you'd like to submit an example to the aws-samples/aws-cdk-examples repository?

DC4JG commented 3 years ago

@skinny85 sure, if I find the time for it I'll gladly share my knowledge in some cleaned up examples and snippets.

ivandres73 commented 3 years ago

This is just perfect, this post needs to be more known as AWS doesn't have any examples at all of Wafv2 in aws-cdk

amouly commented 2 years ago

How is this supposed to work with API GW V2 (HTTP API) and also CloudFront distribution?

I've tried to create the WAF in both cases and neither worked.