I am trying to get a SNS topic to send messages to a Dead Letter Queue after failing. However I keep seeing the error message saying:
Dead-letter queue (redrive policy) permissions Couldn't check Amazon SQS queue permissions. Make sure that the queue exists and that your account has permission to read the attributes of the queue. To allow an Amazon SNS topic to send messages to an Amazon SQS queue, you must create an Amazon SQS queue policy.
My code provided does work but the message does not go away. What could be the fix?
import { Duration, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
import * as sns from 'aws-cdk-lib/aws-sns';
import * as subscriptions from 'aws-cdk-lib/aws-sns-subscriptions';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import { CdkStackProps } from '../cdk.stack';
import * as iam from 'aws-cdk-lib/aws-iam';
import { ServicePrincipal } from 'aws-cdk-lib/aws-iam';
export class EventBridgeSnsStack extends Stack {
constructor(scope: Construct, id: string, props?: CdkStackProps) {
super(scope, id, props);
const dlQueue = new sqs.Queue(this, 'DeadLetterQueue', {
queueName: `${props?.envProps.shortName}-xxxxSubscription_DLQ`,
retentionPeriod: Duration.days(14),
});
// create an SNS topic
const topic = new sns.Topic(this, 'xxxxTopic', {
displayName: 'xxxxTopic',
topicName: `${props?.envProps.shortName}-xxxxTopic`,
});
// add an HTTP subscription to the topic
const subscription = new subscriptions.UrlSubscription(
`https://${props?.envProps.apiDomainAlias}/batch-job/update-xxxxx-statuses`,
{
deadLetterQueue: dlQueue,
filterPolicy: {
// Only process messages with a retryCount equal to 2
// RetryCount will be set to 2 after first try fails
retryCount: sns.SubscriptionFilter.numericFilter({
allowlist: [2],
}),
},
},
);
topic.addSubscription(subscription);
dlQueue.addToResourcePolicy(
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
principals: [new ServicePrincipal('sns.amazonaws.com')],
actions: ['SQS:SendMessage'],
resources: [dlQueue.queueArn],
conditions: {
ArnEquals: {
'aws:SourceArn': topic.topicArn,
},
},
}),
);
// create an EventBridge rule that triggers the SNS topic
const rule = new events.Rule(this, 'xxxxRule', {
schedule: events.Schedule.cron({ minute: '0', hour: '0' }), // trigger at midnight every day
targets: [new targets.SnsTopic(topic)],
});
// configure the EventBridge rule to trigger the SNS topic
rule.addTarget(new targets.SnsTopic(topic));
}
}