AWS:从 Lambda 通过 SES 发送电子邮件
AWS: Sending email through SES from Lambda
每当我尝试从 Lambda(使用 Java)发送带有 SES 的电子邮件时,它都会失败 - 连接超时。
我已经在与 Lambda 函数相同的 VPC 中测试了来自 EC2 实例的完全相同的代码,它从那里开始工作(它们分配了相同的角色)。我还尝试了 运行 Lambda 函数,但它不在 VPC 中(尽管它无论如何都需要在一个 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 不工作吗?
我最终从这方面的某个人那里得到了帮助——我的问题中缺少解决问题所必需的信息,所以这里是关于如何进行设置以使其正常工作的指南。还要注意的是,我实际上无法 运行 VPC 外部的 Lambda 函数 - 当您删除自己的函数时,它只是分配了一个默认函数,我没有意识到这一点。
首先,这是附加到发送电子邮件所需的 Lambda 函数角色的最低策略(您可以删除其中一个发送选项,具体取决于您实际使用的内容,当然您也可以限制资源)。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail",
"ec2:CreateNetworkInterface"
],
"Resource": "*"
}
]
}
我将尝试引导您完成您现在需要创建的资源。首先,您需要一个用于 NAT 网关的子网。
打开 VPC 仪表板并创建一个子网,给它一个有用的标签,这样您就知道它是您的 NAT 的子网。将它放在与您的 Lambda 函数相同的 VPC 中。
接下来,您需要设置路由 table 使其具有(已经存在的)本地路由,这取决于您的 VPC,以及默认路由 0.0.0.0/0互联网网关。如果您没有,只需转至 Internet 网关部分并创建一个。
现在,您需要创建一个 NAT 网关。您可以在 EC2 上进行设置,但我使用了 VPC 仪表板的 NAT 网关部分来避免管理另一个 EC2 实例。放到刚刚创建的子网中,分配一个public IP(新建一个EIP即可)。
为 Lambda 函数再设置两个子网(一个就够了,但 AWS 建议使用两个以确保可用性)。这两个将与本地路由(当然)和针对您刚刚创建的 NAT 网关的默认路由共享路由 table。
您现在应该可以从 Lambda 函数发送电子邮件了!上述步骤是必需的,因为 Lambda 函数只有私有 IP - 要访问 SES,您需要一个 public 一个,NAT 网关为您的 Lambda 函数提供。
每当我尝试从 Lambda(使用 Java)发送带有 SES 的电子邮件时,它都会失败 - 连接超时。
我已经在与 Lambda 函数相同的 VPC 中测试了来自 EC2 实例的完全相同的代码,它从那里开始工作(它们分配了相同的角色)。我还尝试了 运行 Lambda 函数,但它不在 VPC 中(尽管它无论如何都需要在一个 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 不工作吗?
我最终从这方面的某个人那里得到了帮助——我的问题中缺少解决问题所必需的信息,所以这里是关于如何进行设置以使其正常工作的指南。还要注意的是,我实际上无法 运行 VPC 外部的 Lambda 函数 - 当您删除自己的函数时,它只是分配了一个默认函数,我没有意识到这一点。
首先,这是附加到发送电子邮件所需的 Lambda 函数角色的最低策略(您可以删除其中一个发送选项,具体取决于您实际使用的内容,当然您也可以限制资源)。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail",
"ec2:CreateNetworkInterface"
],
"Resource": "*"
}
]
}
我将尝试引导您完成您现在需要创建的资源。首先,您需要一个用于 NAT 网关的子网。
打开 VPC 仪表板并创建一个子网,给它一个有用的标签,这样您就知道它是您的 NAT 的子网。将它放在与您的 Lambda 函数相同的 VPC 中。
接下来,您需要设置路由 table 使其具有(已经存在的)本地路由,这取决于您的 VPC,以及默认路由 0.0.0.0/0互联网网关。如果您没有,只需转至 Internet 网关部分并创建一个。
现在,您需要创建一个 NAT 网关。您可以在 EC2 上进行设置,但我使用了 VPC 仪表板的 NAT 网关部分来避免管理另一个 EC2 实例。放到刚刚创建的子网中,分配一个public IP(新建一个EIP即可)。
为 Lambda 函数再设置两个子网(一个就够了,但 AWS 建议使用两个以确保可用性)。这两个将与本地路由(当然)和针对您刚刚创建的 NAT 网关的默认路由共享路由 table。
您现在应该可以从 Lambda 函数发送电子邮件了!上述步骤是必需的,因为 Lambda 函数只有私有 IP - 要访问 SES,您需要一个 public 一个,NAT 网关为您的 Lambda 函数提供。