Skip to content

Commit

Permalink
Merge pull request #278 from globaldatanet/4.2.0
Browse files Browse the repository at this point in the history
4.2.0
  • Loading branch information
daknhh authored Jan 16, 2024
2 parents 8ac079d + 1fdbf46 commit e0dd8d7
Show file tree
Hide file tree
Showing 36 changed files with 3,009 additions and 4,297 deletions.
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,32 @@

## Released

## 4.2.0
### Fixed
- Output of the correct ManagedRuleGroup version if the stack has already been deployed, no version has been specifically set or Enforce Update has been set
- Restructuring helpers to facilitate smoother integration with the code, particularly for all contributors. Helpers are now seperated into different files and directories grouped by aws service / usage.
- Fixed Codesmells which where found by SonarQube
- VersionEnabled behavior fixed for ManageRuleGroups
- Python Lambda translated into typescript
- Code was improved by removing Code duplications and enriched by more comments and descriptions.
- Bump @aws-sdk/client-service-quotas from 3.427.0 to 3.490.0
- Bump @aws-sdk/client-pricing from 3.427.0 to 3.490.0
- Bump @aws-sdk/client-shield from 3.433.0 to 3.490.0
- Bump @aws-sdk/client-cloudformation from 3.428.0 to 3.490.0
- Bump @aws-sdk/client-cloudwatch from 3.427. to 3.490.0
- Bump @aws-sdk/client-fms from 3.427.to 3.490.0
- Bump @aws-sdk/client-wafv2 from 3.427.0 to 3.490.0
- Bump @types/node 20.8.10 from to 20.11.4
- Bump @typescript-eslint/parser from 6.7.5 to 6.19.0
- Bump @typescript-eslint/eslint-plugin from 6.13.2 to 6.19.0
- Bump aws-cdk-lib from 2.100.0 to 2.121.1
- Bump eslint from 8.53.0 to 8.56.0
- Bump ts-node from 10.9.1 to 10.9.2
- Bump typescript from 5.2.2 to 5.3.3
- Bump @types/lodash from 4.14.178 to 4.14.202
- Bump constructs from 10.2.25 to 10.3.0
- Bump typedoc-plugin-keywords from 1.5.0 to 1.6.0

## 4.1.6
### Fixed
- Fixed Region addression in CloudWatch expressions for Dashboard
Expand Down
29 changes: 13 additions & 16 deletions bin/aws-firewall-factory.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#!/usr/bin/env node
import { WafStack } from "../lib/web-application-firewall-stack";
import { PrerequisitesStack } from "../lib/prerequisites-stack";
import { WafStack } from "../lib/_web-application-firewall-stack";
import { PrerequisitesStack } from "../lib/_prerequisites-stack";
import * as cdk from "aws-cdk-lib";
import { wrongLoggingConfiguration } from "../lib/tools/config-validator";
import { Config, Prerequisites, PriceRegions, RegionString } from "../lib/types/config";
import { isPolicyQuotaReached, isWcuQuotaReached, setOutputsFromStack, initRuntimeProperties, outputInfoBanner } from "../lib/tools/helpers";
import {isPriceCalculated, getCurrentPrices} from "../lib/tools/price-calculator";
import { wafHelper, afwfHelper, pricingHelper, cloudformationHelper } from "../lib/tools/helpers";
import * as values from "../values";

/**
Expand All @@ -27,11 +25,11 @@ void (async () => {
if(process.env.PREREQUISITE === "true") {
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-assignment
const prerequisites: Prerequisites = values.prereq[CONFIG_OBJECT_NAME];
outputInfoBanner();
afwfHelper.outputInfoBanner();

console.log("ℹ️ Deploying Prerequisites Stack.");
const app = new cdk.App();
new PrerequisitesStack(app, prerequisites.General.Prefix.toUpperCase() + "-AWS-FIREWALL-FACTORY-PREQUISITES", {
new PrerequisitesStack(app, prerequisites.General.Prefix.toUpperCase() + "-AWS-FIREWALL-FACTORY-PREQUISITES", { // NOSONAR -> SonarQube is identitfying this line as a Major Issue, but it is not. Error: Either remove this useless object instantiation or use it.
prerequisites,
env: {
region: process.env.AWS_REGION,
Expand All @@ -46,18 +44,18 @@ void (async () => {
else {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const config: Config = values.configs[CONFIG_OBJECT_NAME];
const deploymentRegion= outputInfoBanner(config);
const runtimeProperties = initRuntimeProperties();
const deploymentRegion= afwfHelper.outputInfoBanner(config);
const runtimeProperties = afwfHelper.initRuntimeProperties();
if (process.env.SKIP_QUOTA_CHECK === "true") {
console.log("❗️ SKIPPING Quota Check for Policies.❗️\n\n");
} else {
const policyQuotaReached = await isPolicyQuotaReached(deploymentRegion);
const policyQuotaReached = await wafHelper.isPolicyQuotaReached(deploymentRegion);
if (policyQuotaReached) {
console.error("\u001B[31m","🚨 ERROR: Exit process due Quota Check for Policies 🚨 \n\n","\x1b[0m" + "\n\n");
process.exit(1);
}
}
await setOutputsFromStack(deploymentRegion, runtimeProperties, config);
await cloudformationHelper.setOutputsFromStack(deploymentRegion, runtimeProperties, config);
if(config.General.DeployHash){
console.log("#️⃣ Deployment Hash for this WAF: "+ config.General.DeployHash);
console.log(" ⚠️ Legacy functionality ⌛️\n\n");
Expand Down Expand Up @@ -100,24 +98,23 @@ void (async () => {
console.log(" ⚙️ 🌎 [" + config.WebAcl.Scope+ "]");
}
}
const wcuQuotaReached = await isWcuQuotaReached(deploymentRegion, runtimeProperties, config);
const wcuQuotaReached = await wafHelper.isWcuQuotaReached(deploymentRegion, runtimeProperties, config);
if(wcuQuotaReached) {
console.error("\u001B[31m","🚨 ERROR: Exit process due Quota Check for WCU 🚨 \n\n","\x1b[0m" + "\n\n");
process.exit(1);
}
if(wrongLoggingConfiguration(config)){
if(afwfHelper.wrongLoggingConfiguration(config)){
console.error("\u001B[31m"," 🚨 ERROR: Amazon S3 bucket name is invalid 🚨 ", "\x1b[0m" +"\n 🪣 Amazon S3 bucket name must begin with \"aws-waf-logs-\" followed by at least one \n of the following characters [a-z0-9_.-]\n\n","\x1b[0m" + "\n\n");
process.exit(1);
}
new WafStack(app, `${config.General.Prefix.toUpperCase()}-WAF-${config.WebAcl.Name.toUpperCase()}-${config.General.Stage.toUpperCase()}${config.General.DeployHash ? "-"+config.General.DeployHash.toUpperCase() : ""}`, {
new WafStack(app, `${config.General.Prefix.toUpperCase()}-WAF-${config.WebAcl.Name.toUpperCase()}-${config.General.Stage.toUpperCase()}${config.General.DeployHash ? "-"+config.General.DeployHash.toUpperCase() : ""}`, { // NOSONAR -> SonarQube is identitfying this line as a Major Issue, but it is not. Error: Either remove this useless object instantiation or use it.
config, runtimeProperties: runtimeProperties,
env: {
region: deploymentRegion,
account: process.env.CDK_DEFAULT_ACCOUNT
},
});

await getCurrentPrices(PriceRegions[deploymentRegion as RegionString], runtimeProperties, config,deploymentRegion);
await isPriceCalculated(runtimeProperties);
await pricingHelper.isWafPriceCalculated(PriceRegions[deploymentRegion as RegionString], runtimeProperties, config,deploymentRegion);
}
})();
68 changes: 14 additions & 54 deletions lib/prerequisites-stack.ts → lib/_prerequisites-stack.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import { Prerequisites } from "./types/config";
import { aws_s3 as s3 } from "aws-cdk-lib";
import { aws_kms as kms } from "aws-cdk-lib";
import { aws_iam as iam } from "aws-cdk-lib";
import { aws_lambda as lambda } from "aws-cdk-lib";
import { aws_logs as logs } from "aws-cdk-lib";
import { aws_fms as fms } from "aws-cdk-lib";
import { aws_sns as sns } from "aws-cdk-lib";
import { aws_s3 as s3, aws_kms as kms, aws_iam as iam, aws_lambda as lambda, aws_lambda_nodejs as NodejsFunction, aws_logs as logs } from "aws-cdk-lib";
import * as path from "path";

export interface StackProps extends cdk.StackProps {
readonly prerequisites: Prerequisites;
}
Expand All @@ -31,16 +27,21 @@ export class PrerequisitesStack extends cdk.Stack {
Messenger="Teams";
WebhookUrl=props.prerequisites.Information.TeamsWebhook;
}
const ManagedRuleGroupInfo = new lambda.Function(this, "AWS-Firewall-Factory-ManagedRuleGroupInfo", {
runtime: lambda.Runtime.PYTHON_3_11,
code: lambda.Code.fromAsset("./lib/lambda/ManagedRuleGroupInfo"),
handler: "index.lambda_handler",
const ManagedRuleGroupInfo = new NodejsFunction.NodejsFunction(this, "AWS-Firewall-Factory-ManagedRuleGroupInfo", {
architecture: lambda.Architecture.ARM_64,
entry: path.join(__dirname, "../lib/lambda/ManagedRuleGroupInfo/index.ts"),
handler: "handler",
timeout: cdk.Duration.seconds(30),
environment: {
"Messenger": Messenger,
"WebhookUrl": WebhookUrl,
"MESSENGER": Messenger,
"WEBHOOK_URL": WebhookUrl,
},
logRetention: logs.RetentionDays.ONE_WEEK,
runtime: lambda.Runtime.NODEJS_20_X,
memorySize: 128,
bundling: {
minify: true,
},
description: "Lambda Function to send AWS managed rule group change status notifications (like upcoming new versions and urgent security updates) to messengers (Slack/Teams)",
});
ManagedRuleGroupInfo.addToRolePolicy(new iam.PolicyStatement({
Expand All @@ -53,47 +54,6 @@ export class PrerequisitesStack extends cdk.Stack {
sourceArn: "arn:aws:sns:us-east-1:248400274283:aws-managed-waf-rule-notifications",
});
}
if(props.prerequisites.DdosNotifications) {
console.log("📢 Creating Lambda Function that send notifications about potential DDoS activity for protected resources to messengers (Slack/Teams)");
let Messenger:string = "";
let WebhookUrl:string = "";
if(props.prerequisites.DdosNotifications.SlackWebhook) {
Messenger="Slack";
WebhookUrl=props.prerequisites.DdosNotifications.SlackWebhook;
}
if(props.prerequisites.DdosNotifications.TeamsWebhook) {
Messenger="Teams";
WebhookUrl=props.prerequisites.DdosNotifications.TeamsWebhook;
}
const FmsNotification = new lambda.Function(this, "AWS-Firewall-Factory-FMS-Notifications", {
runtime: lambda.Runtime.PYTHON_3_11,
code: lambda.Code.fromAsset("./lib/lambda/FmsNotification"),
handler: "index.lambda_handler",
timeout: cdk.Duration.seconds(30),
environment: {
"Messenger": Messenger,
"WebhookUrl": WebhookUrl,
},
logRetention: logs.RetentionDays.ONE_WEEK,
description: "Lambda Function that send notifications about potential DDoS activity for protected resources to messengers (Slack/Teams)",
});
const snsRoleName = `arn:aws:iam::${props.env?.account}:role/aws-service-role/fms.amazonaws.com/AWSServiceRoleForFMS`;
const FmsTopic = new sns.Topic(this, "FMS-Notifications-Topic");
FmsTopic.addToResourcePolicy(new iam.PolicyStatement({
actions: ["sns:Publish"],
principals: [iam.Role.fromRoleArn(this, "AWSServiceRoleForFMS",snsRoleName)],
}));
FmsNotification.addPermission("InvokeByFmsSnsTopic", {
action: "lambda:InvokeFunction",
principal: new iam.ServicePrincipal("sns.amazonaws.com"),
sourceArn: FmsTopic.topicArn,
});
new fms.CfnNotificationChannel(this, "AWS-Firewall-Factory-FMS-NotificationChannel", {
snsRoleName,
snsTopicArn: FmsTopic.topicArn,
});
}


if(props.prerequisites.Logging) {
if(props.prerequisites.Logging.FireHoseKey) {
Expand Down
Loading

0 comments on commit e0dd8d7

Please sign in to comment.