in packages/static-website/src/cloudfront-web-acl.ts [118:228]
private createOnEventHandler(stack: Stack, aclName: string): Function {
// NB without manually defining a name, the cdk generated name for the Provider function can become too long and
// deployments fail. This is because the Provider's name references the onEvent handler name and appends "-Provider"
// rather than being generated by cdk and truncated appropriately
const onEventHandlerName = `${PDKNag.getStackPrefix(stack)
.split("/")
.join("-")}AclEvent-${this.node.addr.slice(-6)}`;
const onEventHandlerRole = new Role(this, "OnEventHandlerRole", {
assumedBy: new ServicePrincipal("lambda.amazonaws.com"),
inlinePolicies: {
logs: new PolicyDocument({
statements: [
new PolicyStatement({
effect: Effect.ALLOW,
actions: [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
],
resources: [
`arn:aws:logs:${stack.region}:${stack.account}:log-group:/aws/lambda/${onEventHandlerName}`,
`arn:aws:logs:${stack.region}:${stack.account}:log-group:/aws/lambda/${onEventHandlerName}:*`,
],
}),
],
}),
wafv2: new PolicyDocument({
statements: [
new PolicyStatement({
effect: Effect.ALLOW,
actions: [
"wafv2:CreateWebACL",
"wafv2:DeleteWebACL",
"wafv2:UpdateWebACL",
"wafv2:GetWebACL",
],
resources: [
`arn:aws:wafv2:us-east-1:${stack.account}:global/ipset/${aclName}-IPSet/*`,
`arn:aws:wafv2:us-east-1:${stack.account}:global/webacl/${aclName}/*`,
`arn:aws:wafv2:us-east-1:${stack.account}:global/managedruleset/*/*`,
],
}),
new PolicyStatement({
effect: Effect.ALLOW,
actions: [
"wafv2:CreateIPSet",
"wafv2:DeleteIPSet",
"wafv2:UpdateIPSet",
"wafv2:GetIPSet",
],
resources: [
`arn:aws:wafv2:us-east-1:${stack.account}:global/ipset/${aclName}-IPSet/*`,
],
}),
],
}),
},
});
const onEventHandler = new Function(
this,
"CloudfrontWebAclOnEventHandler",
{
code: Code.fromAsset(path.join(__dirname, "./webacl_event_handler")),
role: onEventHandlerRole,
functionName: onEventHandlerName,
handler: "index.onEvent",
runtime: Runtime.NODEJS_18_X,
timeout: Duration.seconds(300),
}
);
["AwsSolutions-IAM5", "AwsPrototyping-IAMNoWildcardPermissions"].forEach(
(RuleId) => {
NagSuppressions.addResourceSuppressions(
onEventHandlerRole,
[
{
id: RuleId,
reason:
"WafV2 resources have been scoped down to the ACL/IPSet level, however * is still needed as resource id's are created just in time.",
appliesTo: [
{
regex: `/^Resource::arn:aws:wafv2:us-east-1:${PDKNag.getStackAccountRegex(
stack
)}:global/(.*)$/g`,
},
],
},
{
id: RuleId,
reason:
"Cloudwatch resources have been scoped down to the LogGroup level, however * is still needed as stream names are created just in time.",
appliesTo: [
{
regex: `/^Resource::arn:aws:logs:${PDKNag.getStackRegionRegex(
stack
)}:${PDKNag.getStackAccountRegex(
stack
)}:log-group:/aws/lambda/${onEventHandlerName}:\*/g`,
},
],
},
],
true
);
}
);
return onEventHandler;
}