diff --git a/packages/aws-cdk-lib/aws-sns-subscriptions/test/sqs.test.ts b/packages/aws-cdk-lib/aws-sns-subscriptions/test/sqs.test.ts new file mode 100644 index 0000000000000..9e981a0f15903 --- /dev/null +++ b/packages/aws-cdk-lib/aws-sns-subscriptions/test/sqs.test.ts @@ -0,0 +1,31 @@ +import { Template } from '../../assertions'; +import * as kms from '../../aws-kms'; +import * as sns from '../../aws-sns'; +import * as sqs from '../../aws-sqs'; +import { Stack } from '../../core'; +import * as subscriptions from '../lib'; + +test('can add subscription to queue that has encryptionType auto changed', () => { + // GIVEN + const stack = new Stack(); + const key = new kms.Key(stack, 'CustomKey'); + const queue = new sqs.Queue(stack, 'Queue', { + encryption: sqs.QueueEncryption.KMS_MANAGED, + encryptionMasterKey: key, + }); + + const someTopic = new sns.Topic(stack, 'Topic'); + someTopic.addSubscription( + new subscriptions.SqsSubscription(queue, { + rawMessageDelivery: true, + }), + ); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { + Endpoint: { + 'Fn::GetAtt': ['Queue4A7E3555', 'Arn'], + }, + Protocol: 'sqs', + }); +}); \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-sqs/lib/queue.ts b/packages/aws-cdk-lib/aws-sqs/lib/queue.ts index c812cc099d470..16fb120d8f100 100644 --- a/packages/aws-cdk-lib/aws-sqs/lib/queue.ts +++ b/packages/aws-cdk-lib/aws-sqs/lib/queue.ts @@ -4,7 +4,7 @@ import { CfnQueue } from './sqs.generated'; import { validateProps } from './validate-props'; import * as iam from '../../aws-iam'; import * as kms from '../../aws-kms'; -import { Duration, RemovalPolicy, Stack, Token, ArnFormat } from '../../core'; +import { Duration, RemovalPolicy, Stack, Token, ArnFormat, Annotations } from '../../core'; /** * Properties for creating a new Queue @@ -336,7 +336,7 @@ export class Queue extends QueueBase { } : undefined; - const { encryptionMasterKey, encryptionProps } = _determineEncryptionProps.call(this); + const { encryptionMasterKey, encryptionProps, encryptionType } = _determineEncryptionProps.call(this); const fifoProps = this.determineFifoProps(props); this.fifo = fifoProps.fifoQueue || false; @@ -362,9 +362,13 @@ export class Queue extends QueueBase { this.encryptionMasterKey = encryptionMasterKey; this.queueUrl = queue.ref; this.deadLetterQueue = props.deadLetterQueue; - this.encryptionType = props.encryption; + this.encryptionType = encryptionType; - function _determineEncryptionProps(this: Queue): { encryptionProps: EncryptionProps, encryptionMasterKey?: kms.IKey } { + function _determineEncryptionProps(this: Queue): { + encryptionProps: EncryptionProps, + encryptionMasterKey?: kms.IKey, + encryptionType: QueueEncryption | undefined + } { let encryption = props.encryption; if (encryption === QueueEncryption.SQS_MANAGED && props.encryptionMasterKey) { @@ -372,15 +376,23 @@ export class Queue extends QueueBase { } if (encryption !== QueueEncryption.KMS && props.encryptionMasterKey) { + if (encryption !== undefined) { + Annotations.of(this).addWarningV2('@aws-cdk/aws-sqs:queueEncryptionChangedToKMS', [ + `encryption: Automatically changed to QueueEncryption.KMS, was: QueueEncryption.${Object.keys(QueueEncryption)[Object.values(QueueEncryption).indexOf(encryption)]}`, + 'When encryptionMasterKey is provided, always set `encryption: QueueEncryption.KMS`', + ].join('\n')); + } + encryption = QueueEncryption.KMS; // KMS is implied by specifying an encryption key } if (!encryption) { - return { encryptionProps: {} }; + return { encryptionProps: {}, encryptionType: encryption }; } if (encryption === QueueEncryption.UNENCRYPTED) { return { + encryptionType: encryption, encryptionProps: { sqsManagedSseEnabled: false, }, @@ -389,6 +401,7 @@ export class Queue extends QueueBase { if (encryption === QueueEncryption.KMS_MANAGED) { return { + encryptionType: encryption, encryptionProps: { kmsMasterKeyId: 'alias/aws/sqs', kmsDataKeyReusePeriodSeconds: props.dataKeyReuse && props.dataKeyReuse.toSeconds(), @@ -402,6 +415,7 @@ export class Queue extends QueueBase { }); return { + encryptionType: encryption, encryptionMasterKey: masterKey, encryptionProps: { kmsMasterKeyId: masterKey.keyArn, @@ -412,6 +426,7 @@ export class Queue extends QueueBase { if (encryption === QueueEncryption.SQS_MANAGED) { return { + encryptionType: encryption, encryptionProps: { sqsManagedSseEnabled: true, }, diff --git a/packages/aws-cdk-lib/aws-sqs/test/sqs.test.ts b/packages/aws-cdk-lib/aws-sqs/test/sqs.test.ts index 2db4c58550ef8..9ec5da716e28d 100644 --- a/packages/aws-cdk-lib/aws-sqs/test/sqs.test.ts +++ b/packages/aws-cdk-lib/aws-sqs/test/sqs.test.ts @@ -358,6 +358,7 @@ describe('queue encryption', () => { const queue = new sqs.Queue(stack, 'Queue', { encryptionMasterKey: key }); expect(queue.encryptionMasterKey).toEqual(key); + expect(queue.encryptionType).toEqual(sqs.QueueEncryption.KMS); Template.fromStack(stack).hasResourceProperties('AWS::SQS::Queue', { 'KmsMasterKeyId': { 'Fn::GetAtt': ['CustomKey1E6D0D07', 'Arn'] }, }); @@ -492,6 +493,19 @@ describe('queue encryption', () => { encryptionMasterKey: key, })).toThrow(/'encryptionMasterKey' is not supported if encryption type 'SQS_MANAGED' is used/); }); + + test('encryptionType is always KMS, when an encryptionMasterKey is provided', () => { + // GIVEN + const stack = new Stack(); + const key = new kms.Key(stack, 'CustomKey'); + const queue = new sqs.Queue(stack, 'Queue', { + encryption: sqs.QueueEncryption.KMS_MANAGED, + encryptionMasterKey: key, + }); + + // THEN + expect(queue.encryptionType).toBe(sqs.QueueEncryption.KMS); + }); }); describe('encryption in transit', () => {