AWS Lambda连接到Internet

时间:2016-05-10 10:23:37

标签: java node.js amazon-web-services aws-lambda

TL; TR

我正在尝试从AWS Lambda连接到互联网,我有一个带有NAT网关的私有子网但是该功能仍然无法连接到互联网......

完整问题

所以我尝试使用AWS Lambda函数访问互联网。我已经尝试过Java和NodeJS 4而没有运气。

我有一个子网的私有VPC:10.0.10.0/24

enter image description here

如您所见,我已将规则添加到NAT网关:

enter image description here

我将AWS Lambda配置为:

enter image description here

选择该子网(10.0.10.0)并使用对所有内容(入站和出站)开放的安全组

但是当我尝试从互联网上下载内容时,lambda超时了:

'use strict';
console.log('Loading function');

var http = require("http");

exports.handler = (event, context, callback) => {
    //console.log('Received event:', JSON.stringify(event, null, 2));
    console.log('value1 =', event.key1);
    console.log('value2 =', event.key2);
    console.log('value3 =', event.key3);

    var options = {
      host: 'www.virgilio.it',
      port: 80,
      path: '/'
    };

    http.get(options, function(res) {
      console.log("Got response: " + res.statusCode);
    }).on('error', function(e) {
      console.log("Got error: " + e.message);
    });

    callback(null, event.key1);  // Echo back the first key value
    // callback('Something went wrong');
};
  

{    " errorMessage":" 2016-05-10T10:11:46.936Z 79968883-1697-11e6-9e17-1f46a366f324任务在55.00后超时   秒"    }

这是一个错误吗?

注意:同样的功能有效如果我没有选择我的VPC

4 个答案:

答案 0 :(得分:5)

我发现错误,NAT网关应该添加到公共子网(而不是私有子网) 公有子网是与0.0.0.0/0

关联的Internet Gatway路由的子网

答案 1 :(得分:5)

默认情况下,lambda函数未绑定到VPC,这使它能够访问Internet,但阻止其访问VPC中的资源,例如RDS实例。

如果将lambda附加到VPC,则会失去Internet访问,这将阻止您访问S3和Dynamo之类的资源以及发出HTTP请求。

如果两者都需要,那么我将不得不设置VPC进行互联网访问(这很麻烦(AWS伙计们,如果您有一个明确定义的流程,请简化一下:将其变成复选框或按钮;)

创建新的VPC

我发现最好不使用默认VPC,这样您就不会冒险破坏该VPC中已经在工作的某些内容(如果您在那里已有资源),并且还因为可以使用默认VPC作为将来的配置参考。

使用向导创建VPC。

enter image description here

创建路由表

  1. 命名第一个public-subnet(如果尚未命名);
  2. 命名第二个private-lambda。 AWS支持建议仅为lambda提供一个单独的子网,并且此路由表将附加到该子网。

enter image description here

创建子网

默认情况下,创建VPC时,它将为您创建一个公共子网。如果使用默认值,则其名称应为Public subnet。留在那里。

现在,您将创建专用子网。如果您希望Lambda具有高可用性,建议您为其使用多个专用子网。

每个专用子网都将链接到您刚创建的VPC。现在,假设您将VPC IP保留为10.0.0.0/16,并在弗吉尼亚州(us-east-1)运行资源,这是一个模板,用于创建六个专用子网,每个专用子网都位于不同的可用性区域(可用性):

  1. private-lambda-us-east-1a,可用区us-east-1a,IP块10.0.16.0/24
  2. private-lambda-us-east-1b,可用区us-east-1b,IP块10.0.32.0/24
  3. private-lambda-us-east-1c,可用区us-east-1c,IP块10.0.48.0/24
  4. private-lambda-us-east-1d,可用区us-east-1d,IP块10.0.64.0/24
  5. private-lambda-us-east-1e,可用区us-east-1e,IP块10.0.80.0/24
  6. private-lambda-us-east-1f,可用区us-east-1f,IP块10.0.92.0/24

但是您可以看到模式: -IP块的第3个位置增加了16; -名称表示您所在地区的所选可用区域。

enter image description here

确保路由表与子网关联

  • 转到“路由表”面板;
  • 选择公共子网表,查看其关联并确保其与公共子网相关联;
  • 选择private-lambda表,查看其关联并确保其与您刚创建的所有private-lambda-*子网相关。

enter image description here

创建Internet网关

只需创建一个并将其附加到VPC。

配置公共子网的路由

就我而言,它已经配置好了,但是只需确保您的公共子网的路由表中有一个从0.0.0.0/0到刚创建的Internet网关的条目。

enter image description here

创建NAT(网络地址转换器)

创建一个新的NAT并选择您的公共子网。分配新的EIP。

配置专用子网的路由

确保专用子网的路由表具有从0.0.0.0/0到新NAT的条目。

enter image description here

通过这些步骤,您现在应该拥有一个启用Internet的VPC。


用例:配置Lambda以访问Internet和RDS

为lambda创建安全组

  • 新建SG并将“出站->所有流量->配置为0.0.0.0/0::/0

修改RDS实例的安全组以允许

  • 入站->所有交通->来自lambda SG

配置lambda

  • 创建一个新的lambda或选择一个现有的lambda;
  • 选择新的VPC;
  • 选择所有专用子网(private-lambda-*)以获得高可用性;
  • 选择您的lambda安全组。

就是这样。现在,您应该具有可以访问VPC和Internet资源的lambda函数:)

答案 2 :(得分:4)

由于我遇到了同样的问题,为上述答案增加了一点清晰度 -

  1. 将NAT网关或NAT实例添加到公有子网(具有 0.0.0.0/0在相应的(公共)子网路由表中进入互联网网关)
  2. 编辑私有子网(运行lambda的路径)的路由表,以便为公共子网中的NAT网关提供0.0.0.0/0条目。
  3. 确保分配给lambda的安全组允许出站连接。

答案 3 :(得分:0)

如果您要使用 Terraform 执行此操作,以下是您需要配置的资源(除了 Lambda 资源):

  • aws_vpc
  • aws_subnet(公共和私有;多个用于高可用性)
  • aws_internet_gateway 用于出站互联网连接
  • aws_route_table(公共和私有子网的 x2)
  • aws_route_table_association
  • aws_eip(NAT 网关的弹性 IP)
  • aws_nat_gateway
  • aws_default_network_acl 使用 Terraform 管理默认 NACL
  • aws_default_security_group 使用 Terraform 管理默认安全组
  • aws_iam_role_policy_attachment 附加 AWSLambdaVPCAccessExecutionRole 政策

Deploy AWS Lambda to VPC with Terraform