Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions packages/@aws-cdk/aws-s3tables-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,22 @@ const sampleTableBucket = new TableBucket(scope, 'ExampleTableBucket', {

Learn more about table buckets maintenance operations and default behavior from the [S3 Tables User Guide](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-table-buckets-maintenance.html)

### Server-side Encryption

By default, S3 Tables buckets are encrypted using Amazon S3-managed keys (SSE-S3). You can also use AWS Key Management Service (AWS KMS) keys to encrypt your data.
To do this, you can specify the `kmsKey` property when creating the bucket:

```ts
declare const kmsKey: kms.IKey;

new TableBucket(this, 'TableBucket', {
tableBucketName: 'kms-key-s3tables-bucket',
kmsKey,
});
```

**Note**: AWS CDK automatically add a resource policy to the KMS key to allow the S3 Tables service to use it for automatic table maintenance. Detail information can be found in the [security for S3 tables](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables-kms-permissions.html) documentation.

### Controlling Table Bucket Permissions

```ts
Expand Down
36 changes: 35 additions & 1 deletion packages/@aws-cdk/aws-s3tables-alpha/lib/table-bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { TableBucketPolicy } from './table-bucket-policy';
import * as perms from './permissions';
import { validateTableBucketAttributes } from './util';
import * as iam from 'aws-cdk-lib/aws-iam';
import { Resource, IResource, UnscopedValidationError, RemovalPolicy, Token } from 'aws-cdk-lib/core';
import * as kms from 'aws-cdk-lib/aws-kms';
import { Resource, IResource, UnscopedValidationError, RemovalPolicy, Token, Stack } from 'aws-cdk-lib/core';
import { addConstructMetadata } from 'aws-cdk-lib/core/lib/metadata-resource';

/**
Expand Down Expand Up @@ -258,6 +259,13 @@ export interface TableBucketProps {
* @default RETAIN
*/
readonly removalPolicy?: RemovalPolicy;

/**
* The KMS key to use for server-side encryption.
*
* @default - Server-side encryption with Amazon S3-managed keys (SSE-S3)
*/
readonly kmsKey?: kms.IKey;
}

/**
Expand Down Expand Up @@ -498,8 +506,34 @@ export class TableBucket extends TableBucketBase {
noncurrentDays: props.unreferencedFileRemoval?.noncurrentDays,
unreferencedDays: props.unreferencedFileRemoval?.unreferencedDays,
},
encryptionConfiguration: props?.kmsKey
? {
sseAlgorithm: 'aws:kms',
kmsKeyArn: props.kmsKey.keyArn,
}
: undefined,
});

// add resource policy to the encryption key
// see https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables-kms-permissions.html#tables-kms-maintenance-permissions
props?.kmsKey?.addToResourcePolicy(
new iam.PolicyStatement({
actions: ['kms:Decrypt', 'kms:GenerateDataKey'],
resources: ['*'],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the documentation specifies using the KMS Key ARN as resource section, I am using a wildcard (*) for the following reasons:

effect: iam.Effect.ALLOW,
principals: [new iam.ServicePrincipal('maintenance.s3tables.amazonaws.com')],
conditions: {
StringLike: {
'kms:EncryptionContext:aws:s3:arn': `${Stack.of(this).formatArn({
service: 's3tables',
resource: 'bucket',
resourceName: props.tableBucketName,
})}/*`,
},
},
}),
);

this.tableBucketName = this.getResourceNameAttribute(this._resource.ref);
this.tableBucketArn = this._resource.attrTableBucketArn;
this._resource.applyRemovalPolicy(props.removalPolicy);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Construct } from 'constructs';
import { Stack } from 'aws-cdk-lib';
import { TableBucket, UnreferencedFileRemovalStatus } from '@aws-cdk/aws-s3tables-alpha';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as kms from 'aws-cdk-lib/aws-kms';

class Fixture extends Stack {
constructor(scope: Construct, id: string) {
Expand Down

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

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

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,126 @@
{
"Resources": {
"KmsKey46693ADD": {
"Type": "AWS::KMS::Key",
"Properties": {
"KeyPolicy": {
"Statement": [
{
"Action": "kms:*",
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::",
{
"Ref": "AWS::AccountId"
},
":root"
]
]
}
},
"Resource": "*"
},
{
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Condition": {
"StringLike": {
"kms:EncryptionContext:aws:s3:arn": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":s3tables:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":bucket/kms-key-s3tables-bucket/*"
]
]
}
}
},
"Effect": "Allow",
"Principal": {
"Service": "maintenance.s3tables.amazonaws.com"
},
"Resource": "*"
}
],
"Version": "2012-10-17"
}
},
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"TableBucket0BF18B0D": {
"Type": "AWS::S3Tables::TableBucket",
"Properties": {
"EncryptionConfiguration": {
"KMSKeyArn": {
"Fn::GetAtt": [
"KmsKey46693ADD",
"Arn"
]
},
"SSEAlgorithm": "aws:kms"
},
"TableBucketName": "kms-key-s3tables-bucket",
"UnreferencedFileRemoval": {}
},
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
}
},
"Parameters": {
"BootstrapVersion": {
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "/cdk-bootstrap/hnb659fds/version",
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
}
},
"Rules": {
"CheckBootstrapVersion": {
"Assertions": [
{
"Assert": {
"Fn::Not": [
{
"Fn::Contains": [
[
"1",
"2",
"3",
"4",
"5"
],
{
"Ref": "BootstrapVersion"
}
]
}
]
},
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
}
]
}
}
}

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

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

Loading
Loading