Skip to content

Commit

Permalink
reduce cdk nag policies (#14)
Browse files Browse the repository at this point in the history
Co-authored-by: Ran Isenberg <[email protected]>
  • Loading branch information
ran-isenberg and Ran Isenberg authored Jul 23, 2024
1 parent 8a4ccab commit 31122d9
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 27 deletions.
1 change: 0 additions & 1 deletion cdk/blueprint/constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
SERVICE_ROLE_ARN = 'ServiceRoleArn'
LAMBDA_BASIC_EXECUTION_ROLE = 'AWSLambdaBasicExecutionRole'
SERVICE_ROLE = 'ServiceRole'
CREATE_LAMBDA = 'SQSLambda'
LAMBDA_LAYER_NAME = 'common'
Expand Down
27 changes: 15 additions & 12 deletions cdk/blueprint/service_stack.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from aws_cdk import Aspects, Stack, Tags
from cdk_nag import AwsSolutionsChecks, NagSuppressions
from cdk_nag import AwsSolutionsChecks, NagPackSuppression, NagSuppressions
from constructs import Construct

from cdk.blueprint.constants import OWNER_TAG, SERVICE_NAME, SERVICE_NAME_TAG
Expand All @@ -26,20 +26,23 @@ def _add_stack_tags(self) -> None:
Tags.of(self).add(SERVICE_NAME_TAG, SERVICE_NAME)
Tags.of(self).add(OWNER_TAG, get_username())

# Define the custom suppression condition
def custom_suppression_condition(policy_statement):
if 'Action' in policy_statement and 'logs:*' in policy_statement['Action']:
if 'Resource' in policy_statement and '*' in policy_statement['Resource']:
return True
return False

def _add_security_tests(self) -> None:
Aspects.of(self).add(AwsSolutionsChecks(verbose=True))
# Suppress a specific rule for this resource
NagSuppressions.add_stack_suppressions(
self,
[
{'id': 'AwsSolutions-IAM4', 'reason': 'policy for cloudwatch logs.'},
{'id': 'AwsSolutions-IAM5', 'reason': 'policy for cloudwatch logs.'},
{'id': 'AwsSolutions-APIG2', 'reason': 'lambda does input validation'},
{'id': 'AwsSolutions-APIG1', 'reason': 'not mandatory in a sample template'},
{'id': 'AwsSolutions-APIG3', 'reason': 'not mandatory in a sample template'},
{'id': 'AwsSolutions-APIG6', 'reason': 'not mandatory in a sample template'},
{'id': 'AwsSolutions-APIG4', 'reason': 'authorization not mandatory in a sample template'},
{'id': 'AwsSolutions-COG4', 'reason': 'not using cognito'},
{'id': 'AwsSolutions-L1', 'reason': 'False positive'},
stack=self,
suppressions=[
NagPackSuppression(
id='AwsSolutions-IAM5',
reason='Suppressed for logs:* and xray permissions on all resources',
applies_to=['Action::logs:*', 'Action::xray:*', 'Resource::*'],
)
],
)
23 changes: 16 additions & 7 deletions cdk/blueprint/sqs_lambda_s3_blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from aws_cdk import aws_lambda_event_sources as lambda_event_sources
from aws_cdk import aws_s3 as s3
from aws_cdk.aws_lambda_python_alpha import PythonLayerVersion
from aws_cdk.aws_logs import RetentionDays
from constructs import Construct

import cdk.blueprint.constants as constants
Expand Down Expand Up @@ -38,19 +37,30 @@ def _build_lambda_role(self, bucket: s3.Bucket) -> iam.Role:
constants.SERVICE_ROLE_ARN,
assumed_by=iam.ServicePrincipal('lambda.amazonaws.com'),
inline_policies={
'bucket': iam.PolicyDocument(
'Bucket': iam.PolicyDocument(
statements=[
iam.PolicyStatement(
actions=['s3:PutObject', 's3:PutObjectAcl'],
resources=[f'{bucket.bucket_arn}/*'],
resources=[bucket.bucket_arn],
effect=iam.Effect.ALLOW,
),
]
),
# similar to https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaBasicExecutionRole.html
'CloudwatchLogs': iam.PolicyDocument(
statements=[
iam.PolicyStatement(
actions=[
'logs:CreateLogGroup',
'logs:CreateLogStream',
'logs:PutLogEvents',
],
resources=['*'],
effect=iam.Effect.ALLOW,
)
]
),
},
managed_policies=[
iam.ManagedPolicy.from_aws_managed_policy_name(managed_policy_name=(f'service-role/{constants.LAMBDA_BASIC_EXECUTION_ROLE}'))
],
)

def _build_common_layer(self) -> PythonLayerVersion:
Expand Down Expand Up @@ -85,7 +95,6 @@ def _create_lambda_function(
memory_size=constants.API_HANDLER_LAMBDA_MEMORY_SIZE,
layers=[self.common_layer],
role=role,
log_retention=RetentionDays.ONE_DAY,
log_format=_lambda.LogFormat.JSON.value,
system_log_level=_lambda.SystemLogLevel.INFO.value,
)
Expand Down
21 changes: 14 additions & 7 deletions cdk/blueprint/sqs_redrive_construct.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ class RedrivableSQS(Construct):
max_retry_attempts (int): The maximum number of times to retry processing a message in the SQS before sending it to the DLQ. Default is 3. #pylint: disable=line-too-long
"""

LAMBDA_BASIC_EXECUTION_ROLE = 'AWSLambdaBasicExecutionRole'

def __init__(
self,
scope: Construct,
Expand Down Expand Up @@ -105,12 +103,21 @@ def _create_redrive_function(
)
]
),
# similar to https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaBasicExecutionRole.html
'CloudwatchLogs': iam.PolicyDocument(
statements=[
iam.PolicyStatement(
actions=[
'logs:CreateLogGroup',
'logs:CreateLogStream',
'logs:PutLogEvents',
],
resources=['*'],
effect=iam.Effect.ALLOW,
)
]
),
},
managed_policies=[
iam.ManagedPolicy.from_aws_managed_policy_name(
managed_policy_name=f'service-role/{RedrivableSQS.LAMBDA_BASIC_EXECUTION_ROLE}',
)
],
)

return _lambda.Function(
Expand Down

0 comments on commit 31122d9

Please sign in to comment.