From 842272a9e39f8326a99b650a37441d56db9d2aee Mon Sep 17 00:00:00 2001 From: Pip Potter Date: Wed, 9 Jun 2021 22:50:44 -0700 Subject: [PATCH] LYN-4175: Improve security of s3 bucket example --- .../cdk/example/example_resources_stack.py | 58 +++++++++++-------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/Gems/AWSCore/cdk/example/example_resources_stack.py b/Gems/AWSCore/cdk/example/example_resources_stack.py index 42afdd6d9e..7fa48160de 100755 --- a/Gems/AWSCore/cdk/example/example_resources_stack.py +++ b/Gems/AWSCore/cdk/example/example_resources_stack.py @@ -11,10 +11,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. import os from aws_cdk import ( - aws_lambda as _lambda, - aws_s3 as _s3, + aws_lambda as lambda_, + aws_s3 as s3, aws_s3_deployment as s3_deployment, - aws_dynamodb as _dynamo, + aws_dynamodb as dynamo, core ) @@ -39,7 +39,7 @@ class ExampleResources(core.Stack): self._feature_name = feature_name self._policy = AuthPolicy(context=self).generate_admin_policy(stack=self) - self._s3 = self.__create_s3_bucket() + self._s3_bucket = self.__create_s3_bucket() self._lambda = self.__create_example_lambda() self._table = self.__create_dynamodb_table() @@ -49,8 +49,8 @@ class ExampleResources(core.Stack): self.__grant_access(props=props_) def __grant_access(self, props: CoreStackProperties): - self._s3.grant_read(props.user_group) - self._s3.grant_read(props.admin_group) + self._s3_bucket.grant_read(props.user_group) + self._s3_bucket.grant_read(props.admin_group) self._lambda.grant_invoke(props.user_group) self._lambda.grant_invoke(props.admin_group) @@ -58,42 +58,50 @@ class ExampleResources(core.Stack): self._table.grant_read_data(props.user_group) self._table.grant_read_data(props.admin_group) - def __create_s3_bucket(self) -> _s3.Bucket: - # create s3 bucket - - # create s3 bucket - s3 = _s3.Bucket(self, f'{self._project_name}-{self._feature_name}-Example-S3bucket') + def __create_s3_bucket(self) -> s3.Bucket: + # Create a sample S3 bucket following S3 best practices + # # See https://docs.aws.amazon.com/AmazonS3/latest/dev/security-best-practices.html + # 1. Block all public access to the bucket + # 2. Use SSE-S3 encryption. Explore encryption at rest options via + # https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html + example_bucket = s3.Bucket( + self, + f'{self._project_name}-{self._feature_name}-Example-S3bucket', + block_public_access=s3.BlockPublicAccess.BLOCK_ALL, + encryption=s3.BucketEncryption.S3_MANAGED + ) s3_deployment.BucketDeployment( self, f'{self._project_name}-{self._feature_name}-S3bucket-Deployment', - destination_bucket=s3, + destination_bucket=example_bucket, sources=[ s3_deployment.Source.asset('example/s3_content') ], retain_on_delete=False ) + return example_bucket - return s3 - - def __create_example_lambda(self) -> _lambda.Function: + def __create_example_lambda(self) -> lambda_.Function: # create lambda function - function = _lambda.Function(self, - f'{self._project_name}-{self._feature_name}-Lambda-Function', - runtime=_lambda.Runtime.PYTHON_3_8, - handler="lambda-handler.main", - code=_lambda.Code.asset(os.path.join(os.path.dirname(__file__), 'lambda'))) + function = lambda_.Function( + self, + f'{self._project_name}-{self._feature_name}-Lambda-Function', + runtime=lambda_.Runtime.PYTHON_3_8, + handler="lambda-handler.main", + code=lambda_.Code.asset(os.path.join(os.path.dirname(__file__), 'lambda')) + ) return function - def __create_dynamodb_table(self) -> _dynamo.Table: + def __create_dynamodb_table(self) -> dynamo.Table: # create dynamo table # NB: CDK does not support seeding data, see simple table_seeder.py - demo_table = _dynamo.Table( + demo_table = dynamo.Table( self, f'{self._project_name}-{self._feature_name}-Table', - partition_key=_dynamo.Attribute( + partition_key=dynamo.Attribute( name="id", - type=_dynamo.AttributeType.STRING + type=dynamo.AttributeType.STRING ) ) return demo_table @@ -106,7 +114,7 @@ class ExampleResources(core.Stack): id=f'ExampleBucketOutput', description='An example S3 bucket to use with AWSCore ScriptBehaviors', export_name=f"ExampleS3Bucket", - value=self._s3.bucket_arn) + value=self._s3_bucket.bucket_arn) # Define exports # Export resource group