Cloudwatch 自定义事件 SQS 无法正常工作
Posted
技术标签:
【中文标题】Cloudwatch 自定义事件 SQS 无法正常工作【英文标题】:Cloudwatch Custom Events SQS fails to work 【发布时间】:2021-03-30 15:41:00 【问题描述】:我正在使用 terraform 创建队列,同时还创建 Cloudwatch 事件规则并将其中一个队列设置为规则的目标。
总之,我有一个队列,它是 3 个单独的 cloudwatch 事件的目标。问题在于,即使 cloudwatch 事件规则相同,但只有一个在通过 terraform 创建时有效,其他最终在控制台中调用失败,没有日志或任何类型的可调试信息。如果自定义事件是从 aws 控制台创建的,则一切正常。
terraform中队列的创建
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 发送消息的策略。 这是使它工作的更新配置。
-
创建队列
创建允许 cloudwatch 向队列发送消息的策略
将策略附加到队列
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 策略以授予 CW 事件发布到 sqs 的权限? 【参考方案1】:我认为您对 SQS 队列的权限丢失或不正确。假设您在 terraform 中创建 queue_cron
(未在问题中显示),允许 CW 事件向其发送消息的队列及其策略将是:
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 构建的,直到事件失败,也就是我通过控制台尝试它的时候。奇怪的是,一个工作而另一个没有工作,但现在附加了政策,他们都在工作。以上是关于Cloudwatch 自定义事件 SQS 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
AWS 事件总线无法将日志写入来自 AWS Lambda 的自定义日志组上的 CloudWatch
CloudWatch SQS 指标问题上的 AWS Autoscaling
如何聚合 AWS SQS ApproximateNumberOfMessages
schedult 上的 aws 自定义事件以触发 lambda 使用 Terraform
带有graphql和sqs的lambda在nodejs中向sqs发送2条消息?
如何定义AWS MetricFilter FilterPattern以匹配CloudWatch中的JSON格式的日志事件?