Amazon Simple Queue Service is a fully managed message queuing service that helps decouple and scale distributed applications. Using Terraform to provision and manage SQS queues ensures consistent, automated, and repeatable infrastructure deployments. In this article, we’ll show you how to define and configure an Amazon SQS queue using Terraform and provide example configurations that streamline message handling in your cloud architecture.
Amazon SQS Simple Queue Service is a fully managed message queuing service that enables decoupling of distributed systems by allowing asynchronous communication between microservices and other components. SQS works by temporarily storing messages in a queue until they are retrieved and processed by a consuming service. This improves system resilience and scalability by isolating producers from consumers.
By defining queues declaratively, teams can manage lifecycle changes and maintain version control over messaging components. As part of a scalable cloud-native design, Terraform-managed SQS queues support both high-throughput and decoupled application architectures across development environments.
Core SQS Concepts Managed by Terraform
What we’ll cover:
- What is an SQS Queue?
- How to use SQS Queue in Terraform
- Example 1: Production queue with custom behavior
- Example 2: Secure encrypted queue for sensitive data
- Example of a FIFO Queue
- How to import existing AWS SQS queues into Terraform state
- Best practices for naming and permissions of SQS queues in Terraform
Tags mark both queues as part of the production orders service so it is clear in the AWS console what they belong to. If you plug this Terraform SQS queue into a worker service such as ECS, EKS, or Lambda, you get a clean and predictable production setup that is easy to reason about and safe by default.
Queue Policy Versus IAM Role Policy
Most applications can rely on IAM role policies alone. Use awssqsqueue_policy when you need cross-account access or access from AWS services that require a queue policy for example SNS fan-out to SQS.
Keep these policies minimal and explicit, granting access only to the required principals and actions.
Use queue policies only when necessary. Most applications can rely on IAM role policies alone. Use awssqsqueue_policy when you need cross-account access or access from AWS services that require a queue policy for example SNS fan-out to SQS. Keep these policies minimal and explicit, granting access only to the required principals and actions.
The awsiampolicydocument data source builds a JSON policy that grants SQS actions only to a specific IAM role. This role is your application worker that processes sensitive messages. Then awssqsqueuepolicy attaches that policy to the queue.
You can safely publish and consume sensitive events by pointing your applications to awssqsqueue.sensitive_data.id and managing all infrastructure changes through Terraform.
IAM Role Per Service Design
Use IAM roles per service. Create a dedicated IAM role for each consumer producer service and grant only the actions it needs:
- Producers: usually sqs:SendMessage, sqs:GetQueueAttributes
- Consumers: sqs:ReceiveMessage, sqs:DeleteMessage, sqs:ChangeMessageVisibility, sqs:GetQueueAttributes
Define policies in Terraform using awsiampolicy_document so they’re easy to review and reuse:
hcl
data "aws_iam_policy_document" "orders_consumer" {
statement {
actions = [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:ChangeMessageVisibility",
"sqs:GetQueueAttributes"
]
resources = [
aws_sqs_queue.orders_queue.arn
]
}
}
Prefer resource-level restrictions over wildcards. Avoid * in resources or actions whenever possible. Scope resources to a single queue ARN or a small set of ARNs. Restrict actions to only what the service needs instead of broad permissions like sqs:*.
For cross-account scenarios, add conditions such as aws:SourceAccount and aws:SourceArn to the queue policy statements that allow access to reduce the blast radius if credentials are leaked.
Encryption Alignment With KMS Permissions
Align permissions with encryption. If you use a customer managed KMS key for queue encryption, make sure:
- The IAM role that accesses the queue also has kms:Encrypt, kms:Decrypt, and kms:GenerateDataKey* on the relevant KMS key
- The KMS key policy allows the SQS service and your application roles to use the key
If you stay with the default AWS-managed key for SQS encryption, AWS handles most of the key policy for you, and you usually do not need extra KMS permissions.
Managing both queue and KMS permissions in Terraform keeps your security posture consistent and avoids subtle runtime failures when messages are encrypted.
Example 2: Secure encrypted queue for sensitive data. You can create a secure, encrypted SQS queue in Terraform by combining three things: the queue itself, a KMS key for encryption, and an optional queue policy that controls who can send and receive messages.
```hcl
provider "aws" {
region = "eu-central-1"
}
resource "awskmskey" "sensitivedata" {
description = "KMS key for encrypting sensitive SQS messages"
enablekey_rotation = true
}
resource "awskmsalias" "sensitivedata" {
name = "alias/sensitive-sqs-queue"
targetkeyid = awskmskey.sensitivedata.key_id
}
resource "awssqsqueue" "sensitivedata" {
name = "sensitive-data-queue"
kmsmasterkeyid = awskmskey.sensitivedata.arn
kmsdatakeyreuseperiodseconds = 300
# Encryption at rest + tight access window
visibilitytimeoutseconds = 30
messageretentionseconds = 86400 # 1 day
delayseconds = 0
fifoqueue = false
# Optional dead letter queue support would go here
}
```
Restrictive queue policy only allow a specific IAM role
hcl
data "aws_iam_policy_document" "sensitive_data_queue" {
statement {
sid = "AllowSpecificRoleOnly"
principals {
type =
FIFO Queue Guarantees
Example of a FIFO Queue. A FIFO SQS queue guarantees that messages are processed in the exact order they are sent and that they are processed only once.
| Attribute | Production Standard Queue | Secure Encrypted Queue Example |
|---|---|---|
| name | sensitive-data-queue | sensitive-data-queue |
| kmsmasterkey_id | awskmskey.sensitive_data.arn | awskmskey.sensitive_data.arn |
| kmsdatakeyreuseperiod_seconds | 300 | 300 |
| visibilitytimeoutseconds | 30 | 30 |
| messageretentionseconds | 86400 | 86400 |
| delay_seconds | 0 | 0 |
| fifo_queue | false | false |
Policy Scope Table
| Scenario | Recommended Mechanism | Key Constraints |
|---|---|---|
| Same account internal worker | IAM role policy | actions limited to ReceiveMessage, DeleteMessage, ChangeMessageVisibility, GetQueueAttributes |
| Cross account producer | awssqsqueue_policy | principals limited, aws:SourceAccount condition |
| SNS fan-out to SQS | awssqsqueue_policy | minimal explicit actions, no wildcard resources |
| Customer managed KMS encryption | KMS key policy + IAM role | kms:Encrypt, kms:Decrypt, kms:GenerateDataKey* required |
Terraform Workflow Automation
Terraform is really powerful, but to achieve an end-to-end secure GitOps approach, you need to use a product that can run your Terraform workflows.
Automate Terraform deployments with Spacelift. Automate your infrastructure provisioning and build more complex workflows based on Terraform using policy as code, programmatic configuration, context sharing, drift detection, resource visualization, and many more.
Automate Terraform deployments with Spacelift. Terraform is really powerful, but to achieve an end-to-end secure GitOps approach, you need to use a product that can run your Terraform workflows.
Email, SQS, Lambda, and HTTP endpoints with encryption and access policies.
Deploy AWS CloudFront distributions with Terraform. S3 origin, ALB origin, custom domains, SSL certificates, cache policies, and WAF integration.
Deploy AWS ElastiCache Redis with Terraform. Cluster mode, replication groups, subnet groups, encryption, and parameter group configuration.
Deploy AWS Kinesis Data Streams with Terraform. Stream configuration, shard management, Lambda consumers, Firehose delivery, and encryption settings.
Naming and Permission Best Practices Summary
- Use awssqsqueue_policy when you need cross-account access or access from AWS services that require a queue policy for example SNS fan-out to SQS
- Keep these policies minimal and explicit, granting access only to the required principals and actions
- Align permissions with encryption. If you use a customer managed KMS key for queue encryption, make sure the IAM role that accesses the queue also has kms:Encrypt, kms:Decrypt, and kms:GenerateDataKey* on the relevant KMS key
- The KMS key policy allows the SQS service and your application roles to use the key
- If you stay with the default AWS-managed key for SQS encryption, AWS handles most of the key policy for you, and you usually do not need extra KMS permissions
- Use IAM roles per service. Create a dedicated IAM role for each consumer producer service and grant only the actions it needs
- Prefer resource-level restrictions over wildcards. Avoid * in resources or actions whenever possible
- Use queue policies only when necessary. Most applications can rely on IAM role policies alone
Conclusion
Terraform SQS queue policy design is about choosing the right enforcement layer for the access pattern you need. IAM role policies provide the default, least privilege foundation for same account producers and consumers. Queue policies become essential when access must cross account boundaries or originate from AWS services like SNS that require resource based authorization. When encryption is customer managed via KMS, the queue policy is only one part of the trust boundary. The IAM role that reads and writes must hold kms:Encrypt, kms:Decrypt, and kms:GenerateDataKey* on the key, and the key policy must explicitly allow SQS and the application roles. Keeping policies minimal and explicit, scoping resources to a single queue ARN, and adding conditions such as aws:SourceAccount and aws:SourceArn reduces blast radius if credentials leak.
Declarative definition through Terraform gives teams version control over messaging components and lifecycle changes. Tags make ownership visible in the AWS console, and integration with ECS, EKS, or Lambda yields a predictable production setup. Automating Terraform deployments with policy as code, drift detection, and resource visualization completes the secure GitOps loop for SQS messaging.