2016-07-14 115 views
2

每当我尝试从Lambda(使用Java)向SES发送电子邮件时,它都会失败 - 连接超时。AWS:通过SES从Lambda发送电子邮件

我测试了与Lambda函数相同的VPC中的EC2实例的完全相同的代码,并且它从那里工作(它们具有相同的角色分配)。我也试着运行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西-1 ...)由于超时。

任何想法,为什么它不是从Lambda工作?

+0

如果您将Lambda函数放入VPC中,那么它将无法访问VPC之外的任何内容(包括AWS API),除非您还为您的VPC添加了NAT网关。 –

+0

@MarkB我在问题中注意到我在VPC之外尝试了它,并且它没有以完全相同的方式工作。 –

+1

如果它仍然没有进入VPC超时,那么您确定它是连接到SES的超时,而不是Lambda函数耗尽分配时间吗?可能显示实际的错误信息?代码是否在本地运行? –

回答

2

我最终从这个领域的某个人那里得到了帮助 - 我的问题中有一些信息缺失,有必要找出问题所在,所以这里有关于如何设置它以使其正常工作的指南。另外需要注意的是,我实际上无法在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,您需要一个公用密码,NAT网关为您的Lambda函数提供了公共密码。