TerraformPilot

Terraform

AWS SQS Queues with Terraform - Complete Guide

Create AWS SQS queues with Terraform. Standard and FIFO queues, dead-letter queues, encryption, Lambda triggers, and message retention policies.

LLuca Berton1 min read

Quick Answer

#
resource "aws_sqs_queue" "main" {
  name                       = "my-queue"
  visibility_timeout_seconds = 30
  message_retention_seconds  = 86400
}

Standard Queue with Dead-Letter Queue

#
resource "aws_sqs_queue" "dlq" {
  name                      = "${var.project}-dlq"
  message_retention_seconds = 1209600  # 14 days
 
  tags = { Environment = var.environment }
}
 
resource "aws_sqs_queue" "main" {
  name                       = "${var.project}-queue"
  visibility_timeout_seconds = 60
  message_retention_seconds  = 345600   # 4 days
  receive_wait_time_seconds  = 20       # Long polling
  sqs_managed_sse_enabled    = true     # Encryption at rest
 
  redrive_policy = jsonencode({
    deadLetterTargetArn = aws_sqs_queue.dlq.arn
    maxReceiveCount     = 3  # Move to DLQ after 3 failures
  })
 
  tags = { Environment = var.environment }
}
 
# Allow DLQ to receive from main queue
resource "aws_sqs_queue_redrive_allow_policy" "dlq" {
  queue_url = aws_sqs_queue.dlq.id
  redrive_allow_policy = jsonencode({
    redrivePermission = "byQueue"
    sourceQueueArns   = [aws_sqs_queue.main.arn]
  })
}

FIFO Queue

#
resource "aws_sqs_queue" "fifo" {
  name                        = "${var.project}-orders.fifo"
  fifo_queue                  = true
  content_based_deduplication = true
  deduplication_scope         = "messageGroup"
  fifo_throughput_limit       = "perMessageGroupId"
  visibility_timeout_seconds  = 60
 
  tags = { Environment = var.environment }
}

Lambda Trigger

#
resource "aws_lambda_event_source_mapping" "sqs" {
  event_source_arn                   = aws_sqs_queue.main.arn
  function_name                      = aws_lambda_function.processor.arn
  batch_size                         = 10
  maximum_batching_window_in_seconds = 5
  function_response_types            = ["ReportBatchItemFailures"]
}
 
# Lambda needs permission to read from SQS
resource "aws_iam_role_policy_attachment" "lambda_sqs" {
  role       = aws_iam_role.lambda.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole"
}

Queue Access Policy

#
resource "aws_sqs_queue_policy" "main" {
  queue_url = aws_sqs_queue.main.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Sid       = "AllowSNS"
      Effect    = "Allow"
      Principal = { Service = "sns.amazonaws.com" }
      Action    = "sqs:SendMessage"
      Resource  = aws_sqs_queue.main.arn
      Condition = {
        ArnEquals = { "aws:SourceArn" = aws_sns_topic.events.arn }
      }
    }]
  })
}

Standard vs FIFO

#
FeatureStandardFIFO
ThroughputUnlimited3,000 msg/s (with batching)
OrderingBest effortGuaranteed per message group
DeliveryAt least onceExactly once
Name suffixAnyMust end in .fifo
DeduplicationNoneBuilt-in or content-based
CostLower~25% higher

Configuration Defaults

#
SettingDefaultRecommendation
visibility_timeout_seconds306× your Lambda timeout
message_retention_seconds345600 (4 days)14 days for DLQ
receive_wait_time_seconds020 (long polling saves cost)
max_message_size262144 (256KB)Use S3 for larger payloads
#

Conclusion

#

Always pair main queues with dead-letter queues for reliability. Use long polling (receive_wait_time_seconds = 20) to reduce costs, set visibility timeout to 6× your consumer's processing time, and enable encryption. Use FIFO queues only when ordering or exactly-once delivery matters.

#Terraform#AWS#SQS#Messaging#Infrastructure as Code

Share this article