【问题标题】:AWS: Sending email through SES from LambdaAWS:通过 SES 从 Lambda 发送电子邮件
【发布时间】:2016-11-17 15:51:45
【问题描述】:

每当我尝试从 Lambda(使用 Java)发送带有 SES 的电子邮件时,它都会失败 - 连接超时。

我已经在与 Lambda 函数相同的 VPC 中测试了来自 EC2 实例的完全相同的代码,并且它可以从那里工作(它们分配了相同的角色)。我也尝试过在 VPC 中不运行 Lambda 函数(尽管无论如何它都需要在一个 VPC 中),但这也不起作用。

这是相关的代码

    SendEmailRequest request = new SendEmailRequest().withSource(from)
                                                     .withDestination(destination)
                                                     .withMessage(message);

    try {
        System.out.println("Attempting to send an email through Amazon SES by using the AWS SDK for Java...");

        if (client == null) {
            client = new AmazonSimpleEmailServiceClient();
            client.setRegion(Region.getRegion(Regions.EU_WEST_1));
        }

        client.sendEmail(request); // this is where the exception is thrown
        System.out.println("Email sent!");
    } catch (Exception ex) {
        ex.printStackTrace();
        System.err.println(ex.getMessage());
    }
}

错误消息指出,由于超时,它无法连接(到 email.eu-west-1...)。

任何想法为什么它不能在 Lambda 中工作?

【问题讨论】:

  • 如果您将 Lambda 函数放置在 VPC 中,则它无法访问 VPC 之外的任何内容,包括 AWS API,除非您还将 NAT 网关添加到您的 VPC。
  • @MarkB 我确实在问题中注意到我也在 VPC 之外尝试过它,但它并没有以完全相同的方式工作。
  • 如果它在没有进入 VPC 的情况下仍然出现超时,那么您确定是与 SES 的连接超时,而不是 Lambda 函数用完了分配的时间吗?可能显示实际的错误消息?代码在本地运行吗?
  • @MarkB 我从在这个领域工作的人那里得到了关于我的确切案例的帮助。我会让它工作,然后写一个答案来记录该怎么做。谢谢您的帮助!为了回答您的问题,它确实在我自己的机器以及 EC2 机器上成功运行。

标签: java amazon-web-services aws-lambda amazon-ses


【解决方案1】:

我最终从该领域的某个人那里获得了帮助 - 我的问题中缺少一些信息,这些信息对于找出问题是必要的,因此这里是有关如何设置以使其正常工作的指南。另外需要注意的是,我实际上无法在 VPC 之外运行 Lambda 函数 - 当您删除自己的函数时,它只是分配了一个默认函数,我没有意识到这一点。

首先,这是附加到您的 Lambda 函数角色的最小策略,仅用于发送电子邮件(您可以根据您实际使用的内容删除其中一个发送选项,当然您也可以限制资源)。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail",
                "ec2:CreateNetworkInterface"
            ],
            "Resource": "*"
        }
    ]
}

我将尝试引导您完成您现在需要按顺序创建的资源。首先,您需要一个用于 NAT 网关的子网。

打开 VPC 仪表板并创建一个子网,给它一个有用的标签,以便您知道它是您的 NAT 的子网。将它放在与您的 Lambda 函数相同的 VPC 中。

接下来,您需要设置路由表,使其具有(已经存在的)本地路由,这取决于您的 VPC,以及以 Internet 网关为目标的默认路由 0.0.0.0/0。如果您没有,只需转到 Internet 网关部分并创建一个。

现在,您需要创建一个 NAT 网关。您可以在 EC2 上进行设置,但我使用 VPC 仪表板的 NAT 网关部分来避免管理另一个 EC2 实例。把它放在你刚刚创建的子网中,并为其分配一个公共IP(你可以创建一个新的EIP)。

为 Lambda 函数再设置两个子网(一个就足够了,但 AWS 建议使用两个以提高可用性)。这两个将与本地路由(当然)和针对您刚刚创建的 NAT 网关的默认路由共享一个路由表。

您现在应该可以从您的 Lambda 函数发送电子邮件了!上述步骤是必需的,因为 Lambda 函数只有私有 IP - 要访问 SES,您需要一个公共 IP,NAT 网关会为您的 Lambda 函数提供该 IP。

【讨论】:

    猜你喜欢
    • 2020-11-25
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 2019-03-05
    相关资源
    最近更新 更多