Skip to content

Commit

Permalink
Implement no-fail-destination rule
Browse files Browse the repository at this point in the history
  • Loading branch information
PChol22 committed May 27, 2022
1 parent 07d7367 commit 53616cf
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 6 deletions.
14 changes: 8 additions & 6 deletions src/guardian/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import NoMaximumTimeout from "./rules/best_practices/no-max-timeout";
import NoMaximumMemory from "./rules/best_practices/no-max-memory";
import NoIdenticalCode from "./rules/best_practices/no-identical-code";
import NoSharedRoles from "./rules/best_practices/no-shared-roles";
import FailDestination from "./rules/best_practices/fail-destination";
import {
getAWSCredentials,
getStackResources,
Expand Down Expand Up @@ -37,12 +38,13 @@ class GuardianCI {
this.AWS = AWS;
this.stackName = program.stackName;
this.checksToRun = [
NoDefaultMemory,
NoDefaultTimeout,
NoMaximumTimeout,
NoMaximumMemory,
NoIdenticalCode,
NoSharedRoles,
// NoDefaultMemory,
// NoDefaultTimeout,
// NoMaximumTimeout,
// NoMaximumMemory,
// NoIdenticalCode,
// NoSharedRoles,
FailDestination,
];
this.failingChecks = [];

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# No Functions Have Memory Configuration Left as Default (no-default-memory)

Lambda Functions memory is configurable and should be configured for the use-case.
This can impact the speed and running cost of the Lambda Function.
> **Note:** Any increase in memory size triggers an equivalent increase in CPU available to your function
---

## Suggested Actions:

- Look into your CloudWatch Logs for the Lambda function to find `Max Memory Used` [more information](https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html)
```
REPORT RequestId: 3604209a-e9a3-11e6-939a-754dd98c7be3 Duration: 12.34 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 18 MB
```
- Power-tune using [aws-lambda-power-tuning](https://github.com/alexcasalboni/aws-lambda-power-tuning)
87 changes: 87 additions & 0 deletions src/guardian/rules/best_practices/fail-destination/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
const ASYNC_AWS_SERVICES = ["events", "s3", "sqs", "sns"];

const getAwsServiceFromArn = (arn) => arn.split(":")[2];

const isLambdaPolicyAsync = (policy) => {
const sourceArns = policy.Statement.map(
(statement) => statement.Condition.ArnLike["AWS:SourceArn"]
);
return sourceArns.some((sourceArn) =>
ASYNC_AWS_SERVICES.includes(getAwsServiceFromArn(sourceArn))
);
};

class FailDestination {
constructor(AWS, stackName, stackFunctions, SLS) {
this.name = "no-default-timeout";
this.AWS = AWS;
this.stackName = stackName;
this.stackFunctions = stackFunctions;
this.result = false;
this.defaultTimeoutAWS = 3;
this.defaultTimeoutServerlessFramework = 6;
this.failingResources = [];
this.SLS = SLS;
this.failureMessage =
"The following asynchroneous functions have no destination configured on-failure.";
this.rulePage = "***RulePage***";
this.lambda = new this.AWS.Lambda();
}

async run() {
try {
this.result = false;

const stackLambdaPolicies = await Promise.all(
this.stackFunctions.map(({ FunctionName }) =>
this.lambda
.getPolicy({
FunctionName,
})
.promise()
.then((policy) => ({ ...policy, FunctionName }))
.catch(() => {})
)
);

const asyncFunctionsNames = stackLambdaPolicies
.filter(
(policy) =>
policy !== undefined &&
isLambdaPolicyAsync(JSON.parse(policy.Policy))
)
.map((policy) => policy.FunctionName);

const invokeEventConfigs = await Promise.all(
asyncFunctionsNames.map((FunctionName) =>
this.lambda
.getFunctionEventInvokeConfig({
FunctionName,
})
.promise()
.then((invokeEventConfig) => ({
...invokeEventConfig,
FunctionName,
}))
.catch(() => ({ FunctionName }))
)
);

this.failingResources = invokeEventConfigs
.filter(
(invokeEventConfig) =>
invokeEventConfig.DestinationConfig === undefined ||
invokeEventConfig.DestinationConfig.OnFailure.destination === null
)
.map(({ FunctionName }) => ({
FunctionName,
}));
this.result = this.failingResources.length === 0;
} catch (e) {
console.error(e);
}
return this.result;
}
}

export default FailDestination;

0 comments on commit 53616cf

Please sign in to comment.