Я использую terraform для создания очередей, а также создаю правила событий Cloudwatch и устанавливаю одну из очередей в качестве цели для правил.
Таким образом, у меня есть одна очередь, которая является целью для 3 отдельных событий cloudwatch. Проблема в том, что хотя правила событий cloudwatch идентичны, только одно из них работает при создании через terraform, остальные заканчиваются неудачными вызовами в консоли без журнала или какой-либо отладочной информации. Если пользовательские события создаются из консоли aws, все работает хорошо.
resource "aws_sqs_queue" "queue_cron" {
name = "cron"
visibility_timeout_seconds = 300 # 5 minutes
delay_seconds = 0
message_retention_seconds = 1800 # 30 minutes
receive_wait_time_seconds = 20
}
resource "aws_cloudwatch_event_rule" "eve_vendors_bot_sync" {
name = "vendors-bot-sync"
schedule_expression = "rate(1 minute)"
description = "Notify cron queue for vendors bot sync"
is_enabled = true
}
resource "aws_cloudwatch_event_target" "sqs_cron_vendors_bot_sync" {
rule = aws_cloudwatch_event_rule.eve_vendors_bot_sync.name
arn = var.queue_cron_arn
target_id = "sqsCronVendorBotSync"
input_transformer {
input_template = <<EOF
{
"messageType":"cron",
"cronType":"vendors-bot-sync"
}
EOF
}
}
resource "aws_cloudwatch_event_rule" "eve_restos_sync" {
name = "restos-sync"
schedule_expression = "rate(1 minute)"
description = "Notify cron queue for restos sync"
is_enabled = true
}
resource "aws_cloudwatch_event_target" "sqs_cron_restos_sync" {
rule = aws_cloudwatch_event_rule.eve_restos_sync.name
arn = var.queue_cron_arn
target_id = "sqsCronRestosSync"
input_transformer {
input_template = <<EOF
{
"messageType":"cron",
"cronType":"restaurant-hours-open-close-management"
}
EOF
}
}
resource "aws_cloudwatch_event_rule" "eve_vendors_orders_sync" {
name = "vendors-orders-sync"
schedule_expression = "rate(1 minute)"
description = "Notify cron queue for vendors orders sync"
is_enabled = true
}
resource "aws_cloudwatch_event_target" "target_cron_vendors_sync" {
rule = aws_cloudwatch_event_rule.eve_vendors_orders_sync.name
arn = var.queue_cron_arn
target_id = "sqsCronVendorsOrderSync"
input_transformer {
input_template = <<EOF
{
"messageType":"cron",
"cronType":"vendors-orders-sync"
}
EOF
}
}
Недостающая часть головоломки, как справедливо указал @Marchin, действительно была политикой, которая не позволяла cloudwatch отправлять сообщение в SQS. Вот обновленный конфиг, который заставил его работать.
resource "aws_sqs_queue" "queue_cron" {
name = "cron"
visibility_timeout_seconds = 300 # 5 minutes
delay_seconds = 0
message_retention_seconds = 1800 # 30 minutes
receive_wait_time_seconds = 20
}
data "aws_iam_policy_document" "policy_sqs" {
statement {
sid = "AWSEvents_"
effect = "Allow"
actions = [
"sqs:SendMessage",
]
principals {
type = "Service"
identifiers = ["events.amazonaws.com"]
}
resources = [aws_sqs_queue.queue_cron.arn]
}
}
resource "aws_sqs_queue_policy" "cron_sqs_policy" {
queue_url = aws_sqs_queue.queue_cron.id
policy = data.aws_iam_policy_document.policy_sqs.json
}
Я думаю, что ваши разрешения на очередь SQS отсутствуют или неверны. Предполагая, что вы создаете свой queue_cron в terraform (не показан в вопросе), очередь и ее политика, разрешающая CW Events отправлять в нее сообщения, будут:
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
resource "aws_sqs_queue" "queue_cron" {
name = "queue_cron"
}
resource "aws_sqs_queue_policy" "test" {
queue_url = aws_sqs_queue.queue_cron.id
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "sqspolicy",
"Statement": [
{
"Sid": "First",
"Effect": "Allow",
"Principal": {
"AWS": "${data.aws_caller_identity.current.account_id}"
},
"Action": "sqs:*",
"Resource": "${aws_sqs_queue.queue_cron.arn}"
},
{
"Sid": "AWSEvents_",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "sqs:SendMessage",
"Resource": "${aws_sqs_queue.queue_cron.arn}",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "arn:aws:events:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:rule/*"
}
}
}
]
}
POLICY
}
@Marchin Я обновил вопрос, включив в него создание очереди, и я действительно не привязывал к нему никаких конкретных политик. Я попробую приведенный выше код, но непонятно, почему одно из событий будет работать, а другие нет, если политика была неправильной, ни одно из них не должно было работать.
@JudeFernandes Это правильно. Но поскольку вы не показали создание очереди или ее политику, возможный сценарий заключался в том, что она была создана в консоли AWS и настроена с помощью политики только для одной очереди.
@Marchin, это действительно была политика, большое спасибо. Вся инфраструктура была построена исключительно с использованием terraform до того момента, когда события не сработали, когда я попробовал это через консоль. Странно, что один работал, а другой нет, но они все работают теперь, когда политика прилагается.
Настроили ли вы политику SQS для предоставления разрешений на публикацию событий CW в sqs?