Robert Reiz
Robert Reiz

Reputation: 4433

AWS CloudWatch event triggering SQS - not working

I did setup an AWS SQS queue with Terraform. There are some subscribers running on AWS ECS. My plan was to setup a CloudWatch rule with a cron expression, which periodically sends a message into the SQS queue. The SQS queue looks like this:

resource "aws_sqs_queue" "main-queue-fifo" {
  name                        = join("-", [var.environment, "main", "queue.fifo"])
  fifo_queue                  = true
  content_based_deduplication = true
  delay_seconds               = 0
  max_message_size            = 51200  # 50 kb
  message_retention_seconds   = 345600 # 4 days
  receive_wait_time_seconds   = 10
  visibility_timeout_seconds  = 180

  tags = {
    Environment = var.environment
  }
}

And the AWS CloudWatch rule + target looks like this:

resource "aws_cloudwatch_event_rule" "sqs_cn_overdue_reminder" {
  name                = join("-", [var.environment, "sqs-cn-overdue-reminder-rule"]) 
  description         = "Remind organisation to pay overdue credit notes"
  schedule_expression = "cron(0 11 ? * MON-FRI *)" # Monday to Friday 11:00
}

resource "aws_cloudwatch_event_target" "sqs_cn_overdue_reminder" {
  target_id = join("-", [var.environment, "sqs-cn-overdue-reminder-target"])
  arn       = aws_sqs_queue.main-queue-fifo.arn
  input     = jsonencode({"event": "cn_overdue_reminder"})
  rule      = aws_cloudwatch_event_rule.sqs_cn_overdue_reminder.name
  sqs_target {
    message_group_id = "main"
  }
}

The problem is that the message never arrives in the SQS queue. In the rule metrics I can see that the invocation was triggered, but it failed. But I can not see why the invocation failed. Does anybody know why the invocation failed?

Upvotes: 1

Views: 2236

Answers (1)

Robert Reiz
Robert Reiz

Reputation: 4433

After some hours of research I found out that the invocation failed because CloudWatch did not have the permission to access the SQS queue. SQS queues can have an optional access policy. After I added the access policy like in the example below, it worked perfectly.

resource "aws_sqs_queue_policy" "main-queue-fifo-policy" {
  queue_url = aws_sqs_queue.main-queue-fifo.id
  policy = data.aws_iam_policy_document.main-queue-policy-doc.json
}

data "aws_iam_policy_document" "main-queue-policy-doc" {
  statement {
    effect  = "Allow"
    actions = ["sqs:SendMessage"]

    principals {
      type        = "Service"
      identifiers = ["events.amazonaws.com"]
    }

    resources = [aws_sqs_queue.main-queue-fifo.arn]
  }
}

Upvotes: 2

Related Questions