Skip to content

Commit

Permalink
Merge pull request #23 from elsa-data/feature/optional-waf
Browse files Browse the repository at this point in the history
Added the ability to specify the rules for an optional WAF to attach to the app
  • Loading branch information
andrewpatto authored Nov 1, 2023
2 parents bed6294 + 20acc42 commit 0c0e9ad
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 2 deletions.
92 changes: 90 additions & 2 deletions dev/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ const descriptionWithTag = (tag?: string) =>

// bring this out to the top as it is the type of thing we might want to change during dev
// to point to other PR branches etc
const DEV_DEPLOYED_IMAGE_TAG = "0.4.4";
const DEV_DEPLOYED_IMAGE_TAG = "0.4.7";

let rulePriorityCounter = 0;

/**
* Stack for dev
Expand Down Expand Up @@ -63,6 +65,92 @@ new ElsaDataStack(
},
enableAccessPoints: true,
},
databaseName: "elsa_data",
databaseName: "elsa_data_nov_2023",
wafRules: [
{
name: "LimitRequests100",
priority: rulePriorityCounter++,
action: {
block: {},
},
statement: {
rateBasedStatement: {
// given our site is not one where you'd expect high traffic - we set this to
// the minimum, and we will see how that plays out
limit: 100,
aggregateKeyType: "IP",
},
},
visibilityConfig: {
sampledRequestsEnabled: true,
cloudWatchMetricsEnabled: true,
metricName: "LimitRequests100",
},
},
{
name: "AllowedCountriesOnly",
priority: rulePriorityCounter++,
action: {
block: {},
},
statement: {
notStatement: {
statement: {
geoMatchStatement: {
// block traffic if not from below
countryCodes: ["AU"],
},
},
},
},
visibilityConfig: {
sampledRequestsEnabled: true,
cloudWatchMetricsEnabled: true,
metricName: "AllowedCountriesOnly",
},
},
{
name: "AWS-AWSManagedRulesCommonRuleSet",
priority: rulePriorityCounter++,
statement: {
managedRuleGroupStatement: {
name: "AWSManagedRulesCommonRuleSet",
vendorName: "AWS",
// an example of how we might want to exclude rules
// excludedRules: [
// {
// name: "SizeRestrictions_BODY",
// },
//],
},
},
overrideAction: {
none: {},
},
visibilityConfig: {
sampledRequestsEnabled: true,
cloudWatchMetricsEnabled: true,
metricName: "AWS-AWSManagedRulesCommonRuleSet",
},
},
{
name: "AWS-AWSManagedRulesAmazonIpReputationList",
priority: rulePriorityCounter++,
statement: {
managedRuleGroupStatement: {
vendorName: "AWS",
name: "AWSManagedRulesAmazonIpReputationList",
},
},
overrideAction: {
none: {},
},
visibilityConfig: {
sampledRequestsEnabled: true,
cloudWatchMetricsEnabled: true,
metricName: "AWS-AWSManagedRulesAmazonIpReputationList",
},
},
],
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { IBucket } from "aws-cdk-lib/aws-s3";
import { ContainerConstruct } from "../construct/container-construct";
import { IHostedZone } from "aws-cdk-lib/aws-route53";
import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
import { CfnWebACL, CfnWebACLAssociation } from "aws-cdk-lib/aws-wafv2";

interface Props extends ElsaDataApplicationSettings {
readonly vpc: ec2.IVpc;
Expand Down Expand Up @@ -109,6 +110,26 @@ export class ElsaDataApplicationAppRunnerConstruct extends Construct {
vpcConnector: vpcConnector,
});

if (props.wafRules && props.wafRules.length > 0) {
const cfnWebAcl = new CfnWebACL(this, "WebAcl", {
defaultAction: {
allow: {},
},
scope: "REGIONAL",
visibilityConfig: {
cloudWatchMetricsEnabled: true,
metricName: "MetricForWebACLCDK",
sampledRequestsEnabled: true,
},
rules: props.wafRules,
});

new CfnWebACLAssociation(this, "WebAclAssociation", {
resourceArn: appService.serviceArn,
webAclArn: cfnWebAcl.attrArn,
});
}

// register a cloudMapService for the Application in our namespace
// chose a sensible default - but allow an alteration in case I guess someone might
// want to run two Elsa *in the same infrastructure*
Expand Down
8 changes: 8 additions & 0 deletions packages/aws-application/elsa-data-application-settings.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { CfnWebACL } from "aws-cdk-lib/aws-wafv2";

/**
* The user settable settings for the Elsa Data application service.
*/
Expand Down Expand Up @@ -83,6 +85,12 @@ export interface ElsaDataApplicationSettings {
* The cpu assigned to the Elsa Data application container - defaults to something sensible
*/
readonly cpu?: number;

/**
* If present and non-empty - tells us to use these rules for establishing a WAF.
* If not present, then no WAF is installed.
*/
readonly wafRules?: CfnWebACL.RuleProperty[];
}

export interface ElsaDataApplicationBuildLocal {
Expand Down

0 comments on commit 0c0e9ad

Please sign in to comment.