Skip to content

Commit 69f4b8d

Browse files
authored
feat(app-staging-synthesizer-alpha): encryption type for staging bucket (#28903)
Closes #28815. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 8430ea5 commit 69f4b8d

13 files changed

+1223
-6
lines changed

packages/@aws-cdk/app-staging-synthesizer-alpha/README.md

+16
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,22 @@ const app = new App({
265265
});
266266
```
267267

268+
### Staging Bucket Encryption
269+
270+
By default, the staging resources will be stored in an S3 Bucket with KMS encryption. To use
271+
SSE-S3, set `stagingBucketEncryption` to `BucketEncryption.S3_MANAGED`.
272+
273+
```ts
274+
import { BucketEncryption } from 'aws-cdk-lib/aws-s3';
275+
276+
const app = new App({
277+
defaultStackSynthesizer: AppStagingSynthesizer.defaultResources({
278+
appId: 'my-app-id',
279+
stagingBucketEncryption: BucketEncryption.S3_MANAGED,
280+
}),
281+
});
282+
```
283+
268284
## Using a Custom Staging Stack per Environment
269285

270286
If you want to customize some behavior that is not configurable via properties,

packages/@aws-cdk/app-staging-synthesizer-alpha/lib/default-staging-stack.ts

+19-2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ export interface DefaultStagingStackOptions {
6161
*/
6262
readonly stagingBucketName?: string;
6363

64+
/**
65+
* Encryption type for staging bucket
66+
*
67+
* @default - s3.BucketEncryption.KMS
68+
*/
69+
readonly stagingBucketEncryption?: s3.BucketEncryption;
70+
6471
/**
6572
* Pass in an existing role to be used as the file publishing role.
6673
*
@@ -219,6 +226,7 @@ export class DefaultStagingStack extends Stack implements IStagingResources {
219226

220227
private readonly appId: string;
221228
private readonly stagingBucketName?: string;
229+
private stagingBucketEncryption?: s3.BucketEncryption;
222230

223231
/**
224232
* File publish role ARN in asset manifest format
@@ -259,6 +267,7 @@ export class DefaultStagingStack extends Stack implements IStagingResources {
259267

260268
this.deployRoleArn = props.deployRoleArn;
261269
this.stagingBucketName = props.stagingBucketName;
270+
this.stagingBucketEncryption = props.stagingBucketEncryption;
262271
const specializer = new StringSpecializer(this, props.qualifier);
263272

264273
this.providedFileRole = props.fileAssetPublishingRole?._specialize(specializer);
@@ -358,7 +367,15 @@ export class DefaultStagingStack extends Stack implements IStagingResources {
358367
}
359368

360369
this.ensureFileRole();
361-
const key = this.createBucketKey();
370+
371+
let key = undefined;
372+
if (this.stagingBucketEncryption === s3.BucketEncryption.KMS || this.stagingBucketEncryption === undefined) {
373+
if (this.stagingBucketEncryption === undefined) {
374+
// default is KMS as an AWS best practice, and for backwards compatibility
375+
this.stagingBucketEncryption = s3.BucketEncryption.KMS;
376+
}
377+
key = this.createBucketKey();
378+
}
362379

363380
// Create the bucket once the dependencies have been created
364381
const bucket = new s3.Bucket(this, bucketId, {
@@ -369,7 +386,7 @@ export class DefaultStagingStack extends Stack implements IStagingResources {
369386
} : {
370387
removalPolicy: RemovalPolicy.RETAIN,
371388
}),
372-
encryption: s3.BucketEncryption.KMS,
389+
encryption: this.stagingBucketEncryption,
373390
encryptionKey: key,
374391

375392
// Many AWS account safety checkers will complain when buckets aren't versioned

packages/@aws-cdk/app-staging-synthesizer-alpha/test/app-staging-synthesizer.test.ts

+49-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as path from 'path';
33
import { App, Stack, CfnResource, FileAssetPackaging, Token, Lazy, Duration } from 'aws-cdk-lib';
44
import { Match, Template } from 'aws-cdk-lib/assertions';
55
import * as lambda from 'aws-cdk-lib/aws-lambda';
6+
import { BucketEncryption } from 'aws-cdk-lib/aws-s3';
67
import * as cxschema from 'aws-cdk-lib/cloud-assembly-schema';
78
import { CloudAssembly } from 'aws-cdk-lib/cx-api';
89
import { evaluateCFN } from './evaluate-cfn';
@@ -257,7 +258,7 @@ describe(AppStagingSynthesizer, () => {
257258
stack = new Stack(app, 'Stack', {
258259
env: {
259260
account: '000000000000',
260-
region: 'us-west-2',
261+
region: 'us-east-1',
261262
},
262263
});
263264
new CfnResource(stack, 'Resource', {
@@ -268,16 +269,60 @@ describe(AppStagingSynthesizer, () => {
268269
const asm = app.synth();
269270

270271
// THEN
271-
const stagingStackArtifact = asm.getStackArtifact(`StagingStack-${APP_ID}-000000000000-us-west-2`);
272-
273-
Template.fromJSON(stagingStackArtifact.template).hasResourceProperties('AWS::S3::Bucket', {
272+
Template.fromJSON(getStagingResourceStack(asm).template).hasResourceProperties('AWS::S3::Bucket', {
274273
LifecycleConfiguration: {
275274
Rules: Match.arrayWith([{
276275
ExpirationInDays: 1,
277276
Prefix: DEPLOY_TIME_PREFIX,
278277
Status: 'Enabled',
279278
}]),
280279
},
280+
// When stagingBucketEncryption is not specified, it should be KMS for backwards compatibility
281+
BucketEncryption: {
282+
ServerSideEncryptionConfiguration: [
283+
{
284+
ServerSideEncryptionByDefault: {
285+
SSEAlgorithm: 'aws:kms',
286+
},
287+
},
288+
],
289+
},
290+
});
291+
});
292+
293+
test('staging bucket with SSE-S3 encryption', () => {
294+
// GIVEN
295+
app = new App({
296+
defaultStackSynthesizer: AppStagingSynthesizer.defaultResources({
297+
appId: APP_ID,
298+
deployTimeFileAssetLifetime: Duration.days(1),
299+
stagingBucketEncryption: BucketEncryption.S3_MANAGED,
300+
}),
301+
});
302+
stack = new Stack(app, 'Stack', {
303+
env: {
304+
account: '000000000000',
305+
region: 'us-east-1',
306+
},
307+
});
308+
new CfnResource(stack, 'Resource', {
309+
type: 'Some::Resource',
310+
});
311+
312+
// WHEN
313+
const asm = app.synth();
314+
315+
// THEN
316+
Template.fromJSON(getStagingResourceStack(asm).template).hasResourceProperties('AWS::S3::Bucket', {
317+
BucketEncryption: {
318+
ServerSideEncryptionConfiguration: [
319+
{
320+
ServerSideEncryptionByDefault: {
321+
SSEAlgorithm: 'AES256',
322+
},
323+
},
324+
],
325+
},
281326
});
282327
});
283328
});

0 commit comments

Comments
 (0)