Skip to content

Commit

Permalink
Merge the two cloudformation stacks
Browse files Browse the repository at this point in the history
  • Loading branch information
unstubbable committed Mar 16, 2024
1 parent cdcf79d commit 177e081
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 59 deletions.
23 changes: 6 additions & 17 deletions cdk/app.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
import * as cdk from 'aws-cdk-lib';
import './env.js';
import {MainStack} from './main-stack.js';
import {WafStack} from './waf-stack.js';
import {Stack} from './stack.js';

const app = new cdk.App();

const wafStack = new WafStack(app, `mfng-ai-demo-waf`, {
crossRegionReferences: true,
new Stack(app, `mfng-ai-demo`, {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
// For a web ACL with CLOUDFRONT scope, the WAF resources must be created in
// the US East (N. Virginia) Region, us-east-1.
// A web ACL with CLOUDFRONT scope, and the certificate for CloudFront, must
// both be created in the US East (N. Virginia) Region, us-east-1.
region: `us-east-1`,
},
webAclName: `mfng-ai-demo-waf`,
});

new MainStack(app, `mfng-ai-demo-app`, {
crossRegionReferences: true,
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION,
},
bucketName: `mfng-ai-demo-app-assets`,
bucketName: `mfng-ai-demo-assets`,
customDomain: {domainName: `strict.software`, subdomainName: `mfng-ai-demo`},
webAcl: wafStack.webAcl,
webAclName: `mfng-ai-demo`,
});
20 changes: 11 additions & 9 deletions cdk/main-stack.ts → cdk/stack.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import path from 'path';
import * as cdk from 'aws-cdk-lib';
import type {Construct} from 'constructs';
import {WebAcl} from './web-acl.js';

const distDirname = path.join(import.meta.dirname, `../dist/`);

export interface MainStackProps extends cdk.StackProps {
export interface StackProps extends cdk.StackProps {
readonly bucketName: string;
readonly customDomain?: {
readonly domainName: string;
readonly subdomainName: string;
};
readonly webAcl?: cdk.aws_wafv2.CfnWebACL;
readonly webAclName?: string;
}

export class MainStack extends cdk.Stack {
#webAcl: cdk.aws_wafv2.CfnWebACL | undefined;

constructor(scope: Construct, id: string, props: MainStackProps) {
const {bucketName, customDomain, webAcl, ...otherProps} = props;
export class Stack extends cdk.Stack {
constructor(scope: Construct, id: string, props: StackProps) {
const {bucketName, customDomain, webAclName, ...otherProps} = props;
super(scope, id, otherProps);
this.#webAcl = webAcl;

const webAcl = webAclName
? new WebAcl(this, `web-acl`, {webAclName})
: undefined;

const lambdaFunction = new cdk.aws_lambda_nodejs.NodejsFunction(
this,
Expand Down Expand Up @@ -104,7 +106,7 @@ export class MainStack extends cdk.Stack {
'/client/*': staticBehaviorOptions,
},
priceClass: cdk.aws_cloudfront.PriceClass.PRICE_CLASS_100,
webAclId: this.#webAcl?.attrArn,
webAclId: webAcl?.attrArn,
});

if (customDomain && hostedZone) {
Expand Down
56 changes: 23 additions & 33 deletions cdk/waf-stack.ts → cdk/web-acl.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
import * as cdk from 'aws-cdk-lib';
import type {Construct} from 'constructs';

export interface WafStackProps extends cdk.StackProps {
export interface WebAclProps {
readonly webAclName: string;
}

export class WafStack extends cdk.Stack {
#webAcl: cdk.aws_wafv2.CfnWebACL;
#webAclName: string;
#rulePriority = 0;
export class WebAcl extends cdk.aws_wafv2.CfnWebACL {
constructor(scope: Construct, id: string, props: WebAclProps) {
const {webAclName} = props;

constructor(scope: Construct, id: string, props: WafStackProps) {
const {webAclName, ...otherProps} = props;
super(scope, id, otherProps);
this.#webAclName = webAclName;
let rulePriority = 0;

this.#webAcl = new cdk.aws_wafv2.CfnWebACL(this, `waf`, {
const createWebAclRule = (
rule: Omit<
cdk.aws_wafv2.CfnWebACL.RuleProperty,
'priority' | 'visibilityConfig'
>,
): cdk.aws_wafv2.CfnWebACL.RuleProperty => ({
...rule,
priority: (rulePriority += 1),
visibilityConfig: {
cloudWatchMetricsEnabled: false,
metricName: `${webAclName}-${rule.name}`,
sampledRequestsEnabled: true,
},
});

super(scope, id, {
name: webAclName,
scope: `CLOUDFRONT`,
defaultAction: {
Expand All @@ -27,7 +38,7 @@ export class WafStack extends cdk.Stack {
sampledRequestsEnabled: true,
},
rules: [
this.#createWebAclRule({
createWebAclRule({
name: `request-body-size-limit`,
statement: {
sizeConstraintStatement: {
Expand All @@ -39,7 +50,7 @@ export class WafStack extends cdk.Stack {
},
action: {block: {customResponse: {responseCode: 413}}},
}),
this.#createWebAclRule({
createWebAclRule({
name: `rate-limit`,
statement: {
rateBasedStatement: {
Expand All @@ -60,25 +71,4 @@ export class WafStack extends cdk.Stack {
],
});
}

get webAcl(): cdk.aws_wafv2.CfnWebACL {
return this.#webAcl;
}

#createWebAclRule(
rule: Omit<
cdk.aws_wafv2.CfnWebACL.RuleProperty,
'priority' | 'visibilityConfig'
>,
): cdk.aws_wafv2.CfnWebACL.RuleProperty {
return {
...rule,
priority: (this.#rulePriority += 1),
visibilityConfig: {
cloudWatchMetricsEnabled: false,
metricName: `${this.#webAclName}-${rule.name}`,
sampledRequestsEnabled: true,
},
};
}
}

0 comments on commit 177e081

Please sign in to comment.