Skip to content

Commit

Permalink
feat(s3): constructs factories - create well architected s3 buckets (#…
Browse files Browse the repository at this point in the history
…1110)

* Establish baseline package.json

* Remove extra aws-cdk line

* Initial Implementation

* Documentation and new tests

* Fix typos

* Suppress no logging finding

* Suppress findings from CDK custom resources

* Fix last DDB reference

* Address Ryan's typo comment

* Make props arg required for factory so it matches constructs

* Fix error in jest test
  • Loading branch information
biffgaut committed Apr 24, 2024
1 parent dca402c commit f561cf6
Show file tree
Hide file tree
Showing 30 changed files with 2,180 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
lib/*.js
test/*.js
test/s3/*.js
*.d.ts
coverage
test/s3/integ.*.js.snapshot/
test/s3/cdk-integ.out.integ.*.snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
lib/*.js
test/*.js
test/s3/*.js
*.js.map
*.d.ts
node_modules
*.generated.ts
dist
.jsii

.LAST_BUILD
.nyc_output
coverage
.nycrc
.LAST_PACKAGE
*.snk
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Exclude typescript source and config
*.ts
tsconfig.json
coverage
.nyc_output
*.tgz
*.snk
*.tsbuildinfo

# Include javascript files and typescript declarations
!*.js
!*.d.ts

# Exclude jsii outdir
dist

# Include .jsii
!.jsii

# Include .jsii
!.jsii
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# aws-constructs-factories module
<!--BEGIN STABILITY BANNER-->

---

![Stability: Experimental](https://img.shields.io/badge/stability-Experimental-important.svg?style=for-the-badge)

> All classes are under active development and subject to non-backward compatible changes or removal in any
> future version. These are not subject to the [Semantic Versioning](https://semver.org/) model.
> This means that while you may use them, you may need to update your source code when upgrading to a newer version of this package.
---
<!--END STABILITY BANNER-->

| **Reference Documentation**:| <span style="font-weight: normal">https://docs.aws.amazon.com/solutions/latest/constructs/</span>|
|:-------------|:-------------|
<div style="height:8px"></div>

| **Language** | **Package** |
|:-------------|-----------------|
|![Python Logo](https://docs.aws.amazon.com/cdk/api/latest/img/python32.png) Python|`aws_solutions_constructs.aws_constructs_factories`|
|![Typescript Logo](https://docs.aws.amazon.com/cdk/api/latest/img/typescript32.png) Typescript|`@aws-solutions-constructs/aws-constructs-factories`|
|![Java Logo](https://docs.aws.amazon.com/cdk/api/latest/img/java32.png) Java|`software.amazon.awsconstructs.services.constructsfactories`|

## Overview
This AWS Solutions Construct exposes the same code used to create our underlying resources as factories, so clients can create individual resources that are well-architected.

### S3 Buckets

Create fully well-architected S3 buckets with as little as one function call. Here is a minimal deployable pattern definition:

Typescript
``` typescript
import { Construct } from 'constructs';
import { Stack, StackProps } from 'aws-cdk-lib';
import { ConstructsFactories } from '@aws-solutions-constructs/aws-constructs-factories';

const factories = new ConstructsFactories(this, 'integ-test');

factories.s3BucketFactory('test', {});
```

Python
``` python
# TBD
```

Java
``` java
// TBD
```

## S3BucketFactory Function Signature

``` typescript
s3BucketFactory(id: string, props: S3BucketFactoryProps): S3BucketFactoryResponse
```

## S3BucketFactoryProps

| **Name** | **Type** | **Description** |
|:-------------|:----------------|-----------------|
|bucketProps?|[`s3.BucketProps`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.BucketProps.html)|Optional user provided props to override the default props for the S3 Bucket.|
|logS3AccessLogs?|`boolean`|Whether to turn on Access Logging for the S3 bucket. Creates an S3 bucket with associated storage costs for the logs. Enabling Access Logging is a best practice. default - true|
|loggingBucketProps?|[`s3.BucketProps`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.BucketProps.html)|Optional user provided props to override the default props for the S3 Logging Bucket.|

## S3BucketFactoryResponse

| **Name** | **Type** | **Description** |
|:-------------|:----------------|-----------------|
|s3Bucket|[`s3.Bucket`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html)|The s3.Bucket created by the factory. |
|s3LoggingBucket?|[`s3.Bucket`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html)|The s3.Bucket created by the construct as the logging bucket for the primary bucket. If the logS3AccessLogs property is false, this value will be undefined.|

## Default settings

Out of the box implementation of the Construct without any override will set the following defaults:

* An S3 Content Bucket
* AWS managed Server Side Encryption (AES256)
* Lifecycle rule to transition objects to Glacier storage class in 90 days
* Access Logging enabled
* All Public access blocked
* Versioning enabled
* UpdateReplacePolicy is delete
* Deletion policy is delete
* Bucket policy requiring SecureTransport
* An S3 Bucket for Access Logs
* AWS managed Server Side Encryption (AES256)
* All public access blocked
* Versioning enabled
* UpdateReplacePolicy is delete
* Deletion policy is delete
* Bucket policy requiring SecureTransport
* Bucket policy granting PutObject privileges to the S3 logging service, from the content bucket in the content bucket account.
* cfn_nag suppression of access logging finding (not logging access to the access log bucket)

## Architecture
![Architecture Diagram](architecture.png)

***
&copy; Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"parallelRegions": [
"us-east-1"
],
"disable-update-workflow": true,
"update-on-failed": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/

// Note: To ensure CDKv2 compatibility, keep the import statement for Construct separate
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as defaults from '@aws-solutions-constructs/core';

export interface S3BucketFactoryProps {
readonly bucketProps?: s3.BucketProps | any,
readonly logS3AccessLogs?: boolean,
readonly loggingBucketProps?: s3.BucketProps,
}

// Create a response specifically for the interface to avoid coupling client with internal implementation
export interface S3BucketFactoryResponse {
readonly s3Bucket: s3.Bucket,
readonly s3LoggingBucket?: s3.Bucket,
}

export class ConstructsFactories extends Construct {
constructor(scope: Construct, id: string) {
super(scope, id);
}

public s3BucketFactory(id: string, props: S3BucketFactoryProps): S3BucketFactoryResponse {
defaults.CheckS3Props(props);

const propsArg: defaults.BuildS3BucketProps = props ? {
bucketProps: props.bucketProps,
loggingBucketProps: props.loggingBucketProps,
logS3AccessLogs: props.logS3AccessLogs,
} : {};

const buildS3BucketResponse = defaults.buildS3Bucket(this, propsArg, id);

return {
s3Bucket: buildS3BucketResponse.bucket,
s3LoggingBucket: buildS3BucketResponse.loggingBucket
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{
"name": "@aws-solutions-constructs/aws-constructs-factories",
"version": "0.0.0",
"description": "Factories to allow creation of individual resources",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/awslabs/aws-solutions-constructs.git",
"directory": "source/patterns/@aws-solutions-constructs/aws-constructs-factories"
},
"author": {
"name": "Amazon Web Services",
"url": "https://aws.amazon.com",
"organization": true
},
"license": "Apache-2.0",
"scripts": {
"build": "tsc -b .",
"lint": "eslint -c ../eslintrc.yml --ext=.js,.ts . && tslint --project .",
"lint-fix": "eslint -c ../eslintrc.yml --ext=.js,.ts --fix .",
"test": "jest --coverage",
"clean": "tsc -b --clean",
"watch": "tsc -b -w",
"integ": "integ-runner --update-on-failed",
"integ-no-clean": "integ-runner --update-on-failed --no-clean",
"integ-assert": "integ-runner",
"jsii": "jsii",
"jsii-pacmak": "jsii-pacmak",
"build+lint+test": "npm run jsii && npm run lint && npm test && npm run integ-assert",
"snapshot-update": "npm run jsii && npm test -- -u && npm run integ-assert"
},
"jsii": {
"outdir": "dist",
"targets": {
"java": {
"package": "software.amazon.awsconstructs.services.constructsfactories",
"maven": {
"groupId": "software.amazon.awsconstructs",
"artifactId": "constructsfactories"
}
},
"dotnet": {
"namespace": "Amazon.SolutionsConstructs.AWS.ConstructsFactories",
"packageId": "Amazon.SolutionsConstructs.AWS.ConstructsFactories",
"signAssembly": true,
"iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png"
},
"python": {
"distName": "aws-solutions-constructs.aws-constructs-factories",
"module": "aws_solutions_constructs.aws_constructs_factories"
}
}
},
"dependencies": {
"@aws-cdk/integ-tests-alpha": "0.0.0-alpha.0",
"@aws-solutions-constructs/core": "0.0.0",
"constructs": "^10.0.0"
},
"devDependencies": {
"@types/jest": "^27.4.0",
"@types/node": "^10.3.0",
"aws-cdk-lib": "0.0.0",
"constructs": "^10.0.0"
},
"jest": {
"moduleFileExtensions": [
"js"
],
"coverageReporters": [
"text",
[
"lcov",
{
"projectRoot": "../../../../"
}
]
]
},
"peerDependencies": {
"@aws-solutions-constructs/core": "0.0.0",
"aws-cdk-lib": "0.0.0",
"constructs": "^10.0.0"
},
"keywords": [
"aws",
"cdk",
"awscdk",
"Constructs Factories",
"AWS Solutions Constructs"
]
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":"36.0.0"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"version": "36.0.0",
"files": {
"6c1e9b465fa4b2d651dbc9ce3e732d8702a7b19137327684a71d89f1d355f1a2": {
"source": {
"path": "asset.6c1e9b465fa4b2d651dbc9ce3e732d8702a7b19137327684a71d89f1d355f1a2",
"packaging": "zip"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "6c1e9b465fa4b2d651dbc9ce3e732d8702a7b19137327684a71d89f1d355f1a2.zip",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
},
"2161142d5baee33bf29b5438c80e578a67773313c3407242b4229224aa35b9aa": {
"source": {
"path": "defaults.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "2161142d5baee33bf29b5438c80e578a67773313c3407242b4229224aa35b9aa.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Loading

0 comments on commit f561cf6

Please sign in to comment.