Header menu logo FsCDK

SNS SQS Amazon SNS and SQS

Amazon SNS (Simple Notification Service) and SQS (Simple Queue Service) are fully managed messaging services that enable you to decouple and scale microservices, distributed systems, and serverless applications.

SNS/SQS Messaging Patterns

SNS/SQS Messaging Patterns

Quick Start

#r "../src/bin/Release/net8.0/publish/Amazon.JSII.Runtime.dll"
#r "../src/bin/Release/net8.0/publish/Constructs.dll"
#r "../src/bin/Release/net8.0/publish/Amazon.CDK.Lib.dll"
#r "../src/bin/Release/net8.0/publish/FsCDK.dll"

open FsCDK
open Amazon.CDK
open Amazon.CDK.AWS.SNS
open Amazon.CDK.AWS.SQS
open Amazon.CDK.AWS.Lambda

SNS: Basic Topic

Create a simple SNS topic for pub/sub messaging.

stack "BasicSNS" { topic "OrderNotifications" { displayName "Order Processing Notifications" } }

SNS: FIFO Topic

Create a FIFO topic for ordered, exactly-once message delivery.

stack "FIFOTopic" {
    topic "Transactions.fifo" {
        displayName "Transaction Events"
        fifo true
        contentBasedDeduplication true
    }
}

SQS: Basic Queue

Create a simple SQS queue for asynchronous message processing.

stack "BasicSQS" {
    queue "OrderProcessing" {
        visibilityTimeout 30.0
        messageRetention 345600.0 // 4 days
    }
}

SQS: FIFO Queue

Create a FIFO queue for ordered message processing.

stack "FIFOQueue" {
    queue "Transactions.fifo" {
        fifo true
        contentBasedDeduplication true
        visibilityTimeout 60.0
    }
}

SQS: Queue with Dead Letter Queue

Implement error handling with a dead-letter queue.

stack "QueueWithDLQ" {
    // Create dead-letter queue first
    let dlq =
        queue "ProcessingDLQ" {
            messageRetention 1209600.0 // 14 days
        }

    // Create main queue with DLQ
    queue "OrderProcessing" {
        visibilityTimeout 30.0
        deadLetterQueue "ProcessingDLQ" 3 // 3 max receives
    }
}

SNS to SQS: Fan-Out Pattern

Distribute messages from one SNS topic to multiple SQS queues.

stack "FanOutPattern" {
    // Create SNS topic
    let orderTopic = topic "OrderEvents" { displayName "Order Processing Events" }

    // Create multiple queues for different processing
    let inventoryQueue = queue "InventoryProcessing" { visibilityTimeout 30.0 }

    let shippingQueue = queue "ShippingProcessing" { visibilityTimeout 60.0 }

    let analyticsQueue = queue "AnalyticsProcessing" { visibilityTimeout 120.0 }

    // Note: Subscriptions must be configured using CDK directly
    // Example: orderTopic.AddSubscription(SqsSubscription inventoryQueue)
    ()
}

SNS to Lambda

Trigger Lambda functions from SNS topics.

stack "SNSToLambda" {
    // Create Lambda function
    let processorFunc =
        lambda "EventProcessor" {
            runtime Runtime.DOTNET_8
            handler "App::ProcessEvent"
            code "./lambda"
        }

    // Create SNS topic
    let eventTopic = topic "SystemEvents" { displayName "System Event Notifications" }

    // Note: Subscription must be configured using CDK directly
    // Example: eventTopic.AddSubscription(LambdaSubscription processorFunc)
    ()
}

SQS to Lambda

Process SQS messages with Lambda functions.

stack "SQSToLambda" {
    // Create queue
    let workQueue =
        queue "WorkQueue" {
            visibilityTimeout 300.0 // 5 minutes (match Lambda timeout)
        }

    // Create Lambda function
    let workerFunc =
        lambda "Worker" {
            runtime Runtime.DOTNET_8
            handler "App::ProcessMessage"
            code "./lambda"
            timeout 300.0 // 5 minutes
        }

    // Note: Event source mapping must be configured using CDK directly
    // Example: workQueue.GrantConsumeMessages workerFunc
    ()
}

Email Notifications

Send email notifications using SNS.

Note: Email subscriptions must be configured using CDK directly. Email addresses require confirmation.

SMS Notifications

Send SMS notifications using SNS.

Note: SMS subscriptions must be configured using CDK directly. Requires SMS settings configuration in AWS account.

Best Practices

SNS Best Practices

Performance

Security

Cost Optimization

Reliability

SQS Best Practices

Performance

Security

Cost Optimization

Reliability

Message Processing Patterns

Fan-Out (SNS to Multiple SQS)

Queue Chain (SQS to Lambda to SQS)

Priority Queue

Circuit Breaker

SNS vs SQS

Feature

SNS

SQS

Pattern

Pub/Sub (push)

Queue (pull)

Delivery

Push to subscribers

Pull by consumers

Message Persistence

No

Yes (up to 14 days)

Subscribers

Multiple

One consumer per message

Ordering

FIFO topics only

FIFO queues only

Best For

Fan-out, notifications

Decoupling, buffering

FIFO vs Standard

Feature

Standard

FIFO

Throughput

Unlimited

300 msg/s (batch: 3000)

Ordering

Best effort

Guaranteed

Delivery

At least once

Exactly once

Cost

Lower

Higher

Use Case

Most scenarios

Banking, trading

Message Attributes

Use message attributes for filtering and routing:

// In Lambda publishing to SNS:
let attributes = Dictionary<string, MessageAttributeValue>()
attributes.Add("eventType", MessageAttributeValue(StringValue = "order"))
attributes.Add("priority", MessageAttributeValue(StringValue = "high"))

topic.Publish(PublishRequest(
    Message = json,
    MessageAttributes = attributes
))

Resources

namespace FsCDK
namespace Amazon
namespace Amazon.CDK
namespace Amazon.CDK.AWS
namespace Amazon.CDK.AWS.SNS
namespace Amazon.CDK.AWS.SQS
namespace Amazon.CDK.AWS.Lambda
val stack: name: string -> StackBuilder
<summary>Creates an AWS CDK Stack construct.</summary>
<param name="name">The name of the stack.</param>
<code lang="fsharp"> stack "MyStack" { lambda myFunction bucket myBucket } </code>
val topic: name: string -> TopicBuilder
<summary>Creates an SNS topic configuration.</summary>
<param name="name">The topic name.</param>
<code lang="fsharp"> topic "MyTopic" { displayName "My Notification Topic" fifo true } </code>
custom operation: displayName (string) Calls TopicBuilder.DisplayName
<summary>Sets the display name for the topic.</summary>
<param name="displayName">The display name shown in email notifications.</param>
<code lang="fsharp"> topic "MyTopic" { displayName "Order Notifications" } </code>
custom operation: fifo (bool) Calls TopicBuilder.Fifo
<summary>Configures the topic as a FIFO topic.</summary>
<param name="isFifo">Whether the topic is FIFO.</param>
<code lang="fsharp"> topic "MyTopic.fifo" { fifo true } </code>
custom operation: contentBasedDeduplication (bool) Calls TopicBuilder.ContentBasedDeduplication
<summary>Enables content-based deduplication for FIFO topics.</summary>
<param name="enabled">Whether content-based deduplication is enabled.</param>
<code lang="fsharp"> topic "MyTopic.fifo" { fifo true contentBasedDeduplication true } </code>
val queue: name: string -> QueueBuilder
<summary>Creates an SQS queue configuration.</summary>
<param name="name">The queue name.</param>
<code lang="fsharp"> queue "MyQueue" { visibilityTimeout 30.0 fifo true } </code>
custom operation: visibilityTimeout (float) Calls QueueBuilder.VisibilityTimeout
<summary>Sets the visibility timeout for messages in the queue.</summary>
<param name="seconds">The visibility timeout in seconds.</param>
<code lang="fsharp"> queue "MyQueue" { visibilityTimeout 30.0 } </code>
custom operation: messageRetention (float) Calls QueueBuilder.MessageRetention
<summary>Sets the message retention period for the queue.</summary>
<param name="seconds">The retention period in seconds.</param>
<code lang="fsharp"> queue "MyQueue" { messageRetention 345600.0 // 4 days } </code>
custom operation: fifo (bool) Calls QueueBuilder.Fifo
<summary>Configures the queue as a FIFO queue.</summary>
<param name="isFifo">Whether the queue is FIFO.</param>
<code lang="fsharp"> queue "MyQueue.fifo" { fifo true } </code>
custom operation: contentBasedDeduplication (bool) Calls QueueBuilder.ContentBasedDeduplication
<summary>Enables content-based deduplication for FIFO queues.</summary>
<param name="enabled">Whether content-based deduplication is enabled.</param>
<code lang="fsharp"> queue "MyQueue.fifo" { fifo true contentBasedDeduplication true } </code>
val dlq: QueueSpec
custom operation: deadLetterQueue (string) (int) Calls QueueBuilder.DeadLetterQueue
<summary>Configures a dead-letter queue for the queue.</summary>
<param name="dlqName">The name of the dead-letter queue.</param>
<param name="maxReceiveCount">Maximum receives before sending to DLQ.</param>
<code lang="fsharp"> queue "MyQueue" { deadLetterQueue "MyDLQ" 3 } </code>
val orderTopic: TopicSpec
val inventoryQueue: QueueSpec
val shippingQueue: QueueSpec
val analyticsQueue: QueueSpec
val processorFunc: FunctionSpec
val lambda: name: string -> FunctionBuilder
<summary>Creates a Lambda function configuration.</summary>
<param name="name">The function name.</param>
<code lang="fsharp"> lambda "MyFunction" { handler "index.handler" runtime Runtime.NODEJS_18_X code "./lambda" timeout 30.0 } </code>
custom operation: runtime (Runtime) Calls FunctionBuilder.Runtime
<summary>Sets the runtime for the Lambda function.</summary>
<param name="runtime">The Lambda runtime.</param>
<code lang="fsharp"> lambda "MyFunction" { runtime Runtime.NODEJS_18_X } </code>
Multiple items
type Runtime = inherit DeputyBase new: name: string * ?family: Nullable<RuntimeFamily> * ?props: ILambdaRuntimeProps -> unit member RuntimeEquals: other: Runtime -> bool member ToString: unit -> string member BundlingImage: DockerImage member Family: Nullable<RuntimeFamily> member IsVariable: bool member Name: string member SupportsCodeGuruProfiling: bool member SupportsInlineCode: bool ...

--------------------
Runtime(name: string, ?family: System.Nullable<RuntimeFamily>, ?props: ILambdaRuntimeProps) : Runtime
property Runtime.DOTNET_8: Runtime with get
custom operation: handler (string) Calls FunctionBuilder.Handler
<summary>Sets the handler for the Lambda function.</summary>
<param name="handler">The handler name (e.g., "index.handler").</param>
<code lang="fsharp"> lambda "MyFunction" { handler "index.handler" } </code>
custom operation: code (Code) Calls FunctionBuilder.Code
<summary>Sets the code source from a Code object.</summary>
<param name="path">The Code object.</param>
<code lang="fsharp"> lambda "MyFunction" { code (Code.FromBucket myBucket "lambda.zip") } </code>
val eventTopic: TopicSpec
val workQueue: QueueSpec
val workerFunc: FunctionSpec
custom operation: timeout (float) Calls FunctionBuilder.Timeout
<summary>Sets the timeout for the Lambda function.</summary>
<param name="seconds">The timeout in seconds.</param>
<code lang="fsharp"> lambda "MyFunction" { timeout 30.0 } </code>
val attributes: obj
Multiple items
val string: value: 'T -> string

--------------------
type string = System.String

Type something to start searching.