创建主题规则不会在lambda上创建触发器

问题描述 投票:1回答:2

这个问题看起来非常像一个错误,但我相信我的terraform文件肯定有问题,因为我找不到任何网络上有同样问题的人。

以下是我的terraform文件中为其创建lambda和主题规则的部分:

resource "aws_lambda_function" "rds_persist" {
  filename         = "${local.rds_persist_file_path}"
  function_name    = "RdsPersist-${var.env}"
  role             = "${aws_iam_role.lambda_role.arn}"
  handler          = "package.handler"
  source_code_hash = "${local.rds_persist_package_hash}"
  runtime          = "nodejs8.10"
  memory_size      = 128
  timeout          = 10

  vpc_config = {
    subnet_ids         = ["${var.private_subnet_ids}"]
    security_group_ids = ["${aws_security_group.all_vpc_access.id}"]
  }

  environment {
    variables = {
      DB             = "${var.database_url}"
      IOT_DEVICE_ARN = "${var.iot_device_v1_sns_arn}"
    }
  }
}

resource "aws_iot_topic_rule" "rds_push" {
  name        = "${var.env}_RdsPush"
  description = "Pushes events to a persistence lambda (rds store)"
  enabled     = true
  sql         = "SELECT * as payload, topic() as topic, timestamp() AS timestamp FROM '#' WHERE startswith(clientid(), '${var.env}-')"
  sql_version = "2016-03-23"

  lambda {
    function_arn = "${aws_lambda_function.rds_persist.arn}"
  }
}

以下是AWS控制台中的结果:

enter image description here

enter image description here

如果我在控制台中删除并重新添加规则,则触发器将出现在lambda上。

可能是您的主题使用的lambda函数在函数之前创建的情况。

我也通过单独修改主题规则来测试它,以便重新创建(参见下面的日志)。不幸的是,它没有解决问题。

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

-/+ module.lambda.aws_iot_topic_rule.rds_push (tainted) (new resource required)
      id:                             "dev_RdsPush" => <computed> (forces new resource)
      arn:                            "arn:aws:iot:eu-west-1:827689093226:rule/dev_RdsPush" => <computed>
      description:                    "Pushes events to a persistence lambda (rds store)" => "Pushes events to a persistence lambda (rds store)"
      enabled:                        "true" => "true"
      lambda.#:                       "1" => "1"
      lambda.1860721139.function_arn: "arn:aws:lambda:eu-west-1:827689093226:function:RdsPersist-dev" => "arn:aws:lambda:eu-west-1:827689093226:function:RdsPersist-dev"
      name:                           "dev_RdsPush" => "dev_RdsPush"
      sql:                            "SELECT * as payload, topic() as topic, timestamp() AS timestamp FROM '#' WHERE startswith(clientid(), 'dev-')" => "SELECT * as payload, topic() as topic, timestamp() AS timestamp FROM '#' WHERE startswith(clientid(), 'dev-')"
      sql_version:                    "2016-03-23" => "2016-03-23"


Plan: 1 to add, 0 to change, 1 to destroy.

更新:我刚刚在不同的地方发现了一个非常类似的问题:

在另一个lambda和SNS之间应该有一个SNS订阅。以下是terraform中的相关代码:

resource "aws_sns_topic_subscription" "conference_call" {
  topic_arn = "${module.sns.conference_call_arn}"
  protocol  = "lambda"
  endpoint  = "${module.lambda.messaging_arn}"
}

(显然我检查了资源,它们是正确的)

在控制台中我没有在lambda中看到触发器,但我确实在SNS中看到了订阅:

enter image description here

enter image description here

更新:使用AWS CLI创建资源时完全相同的问题

# For the first issue
$ aws iot create-topic-rule --rule-name dev_RdsPush --topic-rule-payload '{"sql":"SELECT * as payload, topic() as topic, timestamp() AS timestamp FROM \'#\' WHERE startswith(clientid(), \'dev-\')","actions":[{"lambda":{"functionArn":"arn:aws:lambda:eu-west-1:xxxxxxxxx:function:RdsPersist-dev"}}]}'

# For the second issue
$ aws sns subscribe --topic-arn arn:aws:sns:eu-west-1:xxxxxxxx:conference-call-v1-dev --protocol lambda --notification-endpoint arn:aws:lambda:eu-west-1:xxxxxxxxx:function:Messaging-dev

解:

添加这些:

物联网:

resource "aws_lambda_permission" "conference_call_sns" {
  statement_id  = "AllowExecutionFromSNS"
  action        = "lambda:InvokeFunction"
  function_name = "${aws_lambda_function.conference_call.function_name}"
  principal     = "sns.amazonaws.com"
  source_arn    = "${var.conference_call_sns_arn}"
}

SNS:

resource "aws_lambda_permission" "messaging_sns" {
  statement_id  = "AllowExecutionFromSNS"
  action        = "lambda:InvokeFunction"
  function_name = "${aws_lambda_function.messaging.function_name}"
  principal     = "sns.amazonaws.com"
  source_arn    = "${var.conference_call_sns_arn}"
}
amazon-web-services aws-lambda terraform iot terraform-provider-aws
2个回答
1
投票

您需要添加lambda权限以允许IoT调用lambda。 Lambda控制台使用该函数的权限来显示可以调用它的内容。

https://docs.aws.amazon.com/iot/latest/developerguide/iot-rule-actions.html#lambda-rule


1
投票

可能是您的主题使用的lambda函数在函数之前创建的情况。尝试在depends_on = ["aws_lambda_function.rds_persist"]上添加aws_iot_topic_rule,看看它是怎么回事。

© www.soinside.com 2019 - 2024. All rights reserved.