Skip to content

Instantly share code, notes, and snippets.

@kdgregory
Created November 9, 2020 12:14
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save kdgregory/bedda496da1e6b99984ef6c5d58946b4 to your computer and use it in GitHub Desktop.
Save kdgregory/bedda496da1e6b99984ef6c5d58946b4 to your computer and use it in GitHub Desktop.
Example of Terraform module to create an SQS queue.
##
## Main configuration: creates several SQS queues using a module, then
## combines their policies into an application role.
##
provider "aws" {}
module "notifications_queue" {
source = "./modules/sqs"
queue_name = "Notifications"
}
module "rendering_queue" {
source = "./modules/sqs"
queue_name = "Rendering"
}
module "reports_queue" {
source = "./modules/sqs"
queue_name = "ReportGeneration"
visibility_timeout = 600
receive_count = 1
}
resource "aws_iam_role" "application_role" {
name = "ApplicationRole"
assume_role_policy = jsonencode({
"Version" = "2012-10-17",
"Statement" = [
{
"Effect" = "Allow"
"Action" = "sts:AssumeRole"
"Principal" = { "Service" = "ec2.amazonaws.com" }
}
]
})
}
resource "aws_iam_role_policy_attachment" "application_role_notifications_producer" {
role = aws_iam_role.application_role.name
policy_arn = module.notifications_queue.producer_policy_arn
}
resource "aws_iam_role_policy_attachment" "application_role_rendering_producer" {
role = aws_iam_role.application_role.name
policy_arn = module.rendering_queue.producer_policy_arn
}
resource "aws_iam_role_policy_attachment" "application_role_reports_producer" {
role = aws_iam_role.application_role.name
policy_arn = module.reports_queue.producer_policy_arn
}
##
## A module to create an SQS queue, along with its dead-letter queue and access policies
##
provider "aws" {}
data "aws_region" "current" {}
##
## The primary and dead-letter queues
##
resource "aws_sqs_queue" "base_queue" {
name = var.queue_name
message_retention_seconds = var.retention_period
visibility_timeout_seconds = var.visibility_timeout
redrive_policy = jsonencode({
"deadLetterTargetArn" = aws_sqs_queue.deadletter_queue.arn,
"maxReceiveCount" = var.receive_count
})
}
resource "aws_sqs_queue" "deadletter_queue" {
name = "${var.queue_name}-DLQ"
message_retention_seconds = var.retention_period
visibility_timeout_seconds = var.visibility_timeout
}
##
## Managed policies that allow access to the queue
##
resource "aws_iam_policy" "consumer_policy" {
name = "SQS-${var.queue_name}-${data.aws_region.current.name}-consumer_policy"
description = "Attach this policy to consumers of ${var.queue_name} SQS queue"
policy = data.aws_iam_policy_document.consumer_policy.json
}
data "aws_iam_policy_document" "consumer_policy" {
statement {
actions = [
"sqs:ChangeMessageVisibility",
"sqs:ChangeMessageVisibilityBatch",
"sqs:DeleteMessage",
"sqs:DeleteMessageBatch",
"sqs:GetQueueAttributes",
"sqs:GetQueueUrl",
"sqs:ReceiveMessage"
]
resources = [
aws_sqs_queue.base_queue.arn,
aws_sqs_queue.deadletter_queue.arn
]
}
}
resource "aws_iam_policy" "producer_policy" {
name = "SQS-${var.queue_name}-${data.aws_region.current.name}-producer"
description = "Attach this policy to producers for ${var.queue_name} SQS queue"
policy = data.aws_iam_policy_document.producer_policy.json
}
data "aws_iam_policy_document" "producer_policy" {
statement {
actions = [
"sqs:GetQueueAttributes",
"sqs:GetQueueUrl",
"sqs:SendMessage",
"sqs:SendMessageBatch"
]
resources = [
aws_sqs_queue.base_queue.arn
]
}
}
output "base_queue_url" {
value = aws_sqs_queue.base_queue.id
}
output "deadletter_queue_url" {
value = aws_sqs_queue.deadletter_queue.id
}
output "consumer_policy_arn" {
value = aws_iam_policy.consumer_policy.arn
}
output "producer_policy_arn" {
value = aws_iam_policy.producer_policy.arn
}
variable "queue_name" {
description = "The name of the queue. Used as a prefix for related resource names."
type = string
}
variable "retention_period" {
description = "Time (in seconds) that messages will remain in queue before being purged"
type = number
default = 86400
}
variable "visibility_timeout" {
description = "Time (in seconds) that consumers have to process a message before it becomes available again"
type = number
default = 60
}
variable "receive_count" {
description = "The number of times that a message can be retrieved before being moved to the dead-letter queue"
type = number
default = 3
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment