AWS Lambda 连接到互联网
AWS Lambda connecting to Internet
TL;TR
我正在尝试从 AWS Lambda 连接到互联网,我有一个带有 NAT 网关的私有子网,但该功能仍然无法连接到互联网...
完整问题
所以我正在尝试使用我的 AWS Lambda 函数访问互联网。我试过 Java 和 NodeJS 4 都没有成功。
我有一个带有子网的私有 VPC:10.0.10.0/24
如您所见,我已将规则添加到我的 NAT 网关:
我这样配置我的 AWS Lambda:
选择该子网 (10.0.10.0) 并使用对所有内容(入站和出站)开放的安全组
但是当我尝试从 Internet 下载内容时,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 Task timed out after 55.00
seconds"
}
这是一个错误吗?
注意:如果我不 select 我的 VPC
,同样的功能可以工作
我发现错误,NAT 网关应该添加到 public 子网(不是私有子网)。
public 子网是具有关联到 0.0.0.0/0
的 Internet 网关路由的子网
因为我遇到了同样的问题,所以对上面的答案进行了更清晰的说明 -
- 将 NAT 网关或 NAT 实例添加到 public 子网(具有
0.0.0.0/0
相应 (public) 个子网路由 table) 中的互联网网关条目
- 编辑私有子网的路由 table(您所在的位置 运行 您的 lambda),为
0.0.0.0/0
到 public 子网中的 NAT 网关添加一个条目。
- 确保分配给 lambda 的安全组允许出站连接。
默认情况下,lambda 函数不绑定 VPC,这使其可以访问 Internet,但会阻止它访问 VPC 中的资源,例如 RDS 实例。
如果您将 lambda 附加到 VPC,您将失去 Internet 访问权限,这会阻止您访问 S3 和 Dynamo 等资源,也无法发出 HTTP 请求。
如果你两者都需要,那么我将不得不设置 VPC 以访问互联网,这是一团糟(嘿 AWS 伙计们,如果你有一个明确定义的过程,请简单点:转将其放入复选框或按钮中 ;)
新建VPC
我发现最好单独保留默认 VPC,这样您就不会冒破坏该 VPC 中已经运行的东西的风险(以防您那里已经有资源),而且还因为您可以使用默认VPC作为以后的配置参考。
使用向导创建 VPC。
创建路线 Tables
- 命名第一个
public-subnet
(如果尚不存在);
- 命名第二个
private-lambda
。 AWS 支持建议只为 lambda 设置一个单独的子网,并且此路由 Table 将附加到它。
创建子网
默认情况下,当您创建 VPC 时,它会为您创建一个 public 子网。如果您使用默认值,其名称应为 Public subnet
。就这样吧。
现在您要创建私有子网。如果您希望 Lambda 具有高可用性,建议为您的 Lambda 设置多个私有子网。
这些私有子网中的每一个都将链接到您刚刚创建的 VPC。现在,假设您将 VPC IP 保留为 10.0.0.0/16
,并且您 运行 您在弗吉尼亚州的资源 (us-east-1
),这是一个用于创建六个私有子网的模板,每个子网的可用性不同区域(高可用性):
private-lambda-us-east-1a
,可用区 us-east-1a
,IP 块 10.0.16.0/24
private-lambda-us-east-1b
,可用区 us-east-1b
,IP 块 10.0.32.0/24
private-lambda-us-east-1c
,可用区 us-east-1c
,IP 块 10.0.48.0/24
private-lambda-us-east-1d
,可用区 us-east-1d
,IP 块 10.0.64.0/24
private-lambda-us-east-1e
,可用区 us-east-1e
,IP 块 10.0.80.0/24
private-lambda-us-east-1f
,可用区 us-east-1f
,IP 块 10.0.92.0/24
但是你可以看到模式:
- IP块的第3位增加了16位;
- 名称表示您所在地区的 selected 可用性区域。
确保路由 Table 与子网关联
- 转到路线 Table 面板;
- Select public-子网 table,检查其关联并确保它关联到 Public 子网;
- Select private-lambda table,检查其关联并确保它与您刚刚创建的所有
private-lambda-*
子网关联。
创建互联网网关
只需创建一个并将其附加到 VPC。
配置 Public 子网
的路由
在我的例子中,它已配置好,但只需确保您的 Public 子网的路由 Table 有一个从 0.0.0.0/0
到您刚刚创建的 Internet 网关的条目。
创建 NAT(网络地址转换器)
创建一个新的 NAT 和 select 您的 Public 子网。分配一个新的EIP。
配置私有子网的路由
确保您的私有子网的路由 Table 具有从 0.0.0.0/0
到您的新 NAT 的条目。
通过这些步骤,您现在应该拥有一个支持 Internet 的 VPC。
用例:为 Internet 和 RDS 访问配置 Lambda
为 lambda 创建一个安全组
- 新建 SG 并配置出站 -> 所有流量 -> 到
0.0.0.0/0
和 ::/0
修改您的 RDS 实例的安全组以允许
- 入站 -> 所有流量 -> 来自 lambda SG
配置 lambda
- 创建一个新的 lambda 或 select 一个现有的;
- Select 您的新 VPC;
- Select 您所有的私有子网 (
private-lambda-*
) 以实现高可用性;
- Select 你的 lambda 安全组。
就是这样。您现在应该有一个可以访问 VPC 和 Internet 资源的 lambda 函数:)
如果您要使用 Terraform 执行此操作,以下是您需要配置的资源(除了 Lambda 资源):
aws_vpc
aws_subnet
(public 和私有;多个以实现高可用性)
aws_internet_gateway
用于出站连接到互联网
aws_route_table
(public 和私有子网的 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
政策
如果您刚开始,请使用 VPC 主页上的 VPC 启动模板来部署 VPC。这将创建 public 子网、私有子网、NAT GW、IGW 以及从私有子网访问互联网所需的所有路由。
If you need both, then I'll have to set up the VPC for internet access, which is a mess (hey AWS guys, if you have a well-defined process for it, please make it simple: turn it into a checkbox or button ;)
您的祈祷已被听到,AWS 现在有一个“要创建的资源”->“VPC、子网等”。创建新 VPC 时的选项,您可以在向导中选择子网、AZ、NAT 网关等的数量,它会创建您为您描述的所有内容:
Create VPC
TL;TR
我正在尝试从 AWS Lambda 连接到互联网,我有一个带有 NAT 网关的私有子网,但该功能仍然无法连接到互联网...
完整问题
所以我正在尝试使用我的 AWS Lambda 函数访问互联网。我试过 Java 和 NodeJS 4 都没有成功。
我有一个带有子网的私有 VPC:10.0.10.0/24
如您所见,我已将规则添加到我的 NAT 网关:
我这样配置我的 AWS Lambda:
选择该子网 (10.0.10.0) 并使用对所有内容(入站和出站)开放的安全组
但是当我尝试从 Internet 下载内容时,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 Task timed out after 55.00 seconds" }
这是一个错误吗?
注意:如果我不 select 我的 VPC
,同样的功能可以工作我发现错误,NAT 网关应该添加到 public 子网(不是私有子网)。
public 子网是具有关联到 0.0.0.0/0
因为我遇到了同样的问题,所以对上面的答案进行了更清晰的说明 -
- 将 NAT 网关或 NAT 实例添加到 public 子网(具有
0.0.0.0/0
相应 (public) 个子网路由 table) 中的互联网网关条目
- 编辑私有子网的路由 table(您所在的位置 运行 您的 lambda),为
0.0.0.0/0
到 public 子网中的 NAT 网关添加一个条目。 - 确保分配给 lambda 的安全组允许出站连接。
默认情况下,lambda 函数不绑定 VPC,这使其可以访问 Internet,但会阻止它访问 VPC 中的资源,例如 RDS 实例。
如果您将 lambda 附加到 VPC,您将失去 Internet 访问权限,这会阻止您访问 S3 和 Dynamo 等资源,也无法发出 HTTP 请求。
如果你两者都需要,那么我将不得不设置 VPC 以访问互联网,这是一团糟(嘿 AWS 伙计们,如果你有一个明确定义的过程,请简单点:转将其放入复选框或按钮中 ;)
新建VPC
我发现最好单独保留默认 VPC,这样您就不会冒破坏该 VPC 中已经运行的东西的风险(以防您那里已经有资源),而且还因为您可以使用默认VPC作为以后的配置参考。
使用向导创建 VPC。
创建路线 Tables
- 命名第一个
public-subnet
(如果尚不存在); - 命名第二个
private-lambda
。 AWS 支持建议只为 lambda 设置一个单独的子网,并且此路由 Table 将附加到它。
创建子网
默认情况下,当您创建 VPC 时,它会为您创建一个 public 子网。如果您使用默认值,其名称应为 Public subnet
。就这样吧。
现在您要创建私有子网。如果您希望 Lambda 具有高可用性,建议为您的 Lambda 设置多个私有子网。
这些私有子网中的每一个都将链接到您刚刚创建的 VPC。现在,假设您将 VPC IP 保留为 10.0.0.0/16
,并且您 运行 您在弗吉尼亚州的资源 (us-east-1
),这是一个用于创建六个私有子网的模板,每个子网的可用性不同区域(高可用性):
private-lambda-us-east-1a
,可用区us-east-1a
,IP 块10.0.16.0/24
private-lambda-us-east-1b
,可用区us-east-1b
,IP 块10.0.32.0/24
private-lambda-us-east-1c
,可用区us-east-1c
,IP 块10.0.48.0/24
private-lambda-us-east-1d
,可用区us-east-1d
,IP 块10.0.64.0/24
private-lambda-us-east-1e
,可用区us-east-1e
,IP 块10.0.80.0/24
private-lambda-us-east-1f
,可用区us-east-1f
,IP 块10.0.92.0/24
但是你可以看到模式: - IP块的第3位增加了16位; - 名称表示您所在地区的 selected 可用性区域。
确保路由 Table 与子网关联
- 转到路线 Table 面板;
- Select public-子网 table,检查其关联并确保它关联到 Public 子网;
- Select private-lambda table,检查其关联并确保它与您刚刚创建的所有
private-lambda-*
子网关联。
创建互联网网关
只需创建一个并将其附加到 VPC。
配置 Public 子网
的路由在我的例子中,它已配置好,但只需确保您的 Public 子网的路由 Table 有一个从 0.0.0.0/0
到您刚刚创建的 Internet 网关的条目。
创建 NAT(网络地址转换器)
创建一个新的 NAT 和 select 您的 Public 子网。分配一个新的EIP。
配置私有子网的路由
确保您的私有子网的路由 Table 具有从 0.0.0.0/0
到您的新 NAT 的条目。
通过这些步骤,您现在应该拥有一个支持 Internet 的 VPC。
用例:为 Internet 和 RDS 访问配置 Lambda
为 lambda 创建一个安全组
- 新建 SG 并配置出站 -> 所有流量 -> 到
0.0.0.0/0
和::/0
修改您的 RDS 实例的安全组以允许
- 入站 -> 所有流量 -> 来自 lambda SG
配置 lambda
- 创建一个新的 lambda 或 select 一个现有的;
- Select 您的新 VPC;
- Select 您所有的私有子网 (
private-lambda-*
) 以实现高可用性; - Select 你的 lambda 安全组。
就是这样。您现在应该有一个可以访问 VPC 和 Internet 资源的 lambda 函数:)
如果您要使用 Terraform 执行此操作,以下是您需要配置的资源(除了 Lambda 资源):
aws_vpc
aws_subnet
(public 和私有;多个以实现高可用性)aws_internet_gateway
用于出站连接到互联网aws_route_table
(public 和私有子网的 x2)aws_route_table_association
aws_eip
(NAT 网关的弹性 IP)aws_nat_gateway
aws_default_network_acl
使用 Terraform 管理默认 NACLaws_default_security_group
使用 Terraform 管理默认安全组
aws_iam_role_policy_attachment
附加AWSLambdaVPCAccessExecutionRole
政策
如果您刚开始,请使用 VPC 主页上的 VPC 启动模板来部署 VPC。这将创建 public 子网、私有子网、NAT GW、IGW 以及从私有子网访问互联网所需的所有路由。
If you need both, then I'll have to set up the VPC for internet access, which is a mess (hey AWS guys, if you have a well-defined process for it, please make it simple: turn it into a checkbox or button ;)
您的祈祷已被听到,AWS 现在有一个“要创建的资源”->“VPC、子网等”。创建新 VPC 时的选项,您可以在向导中选择子网、AZ、NAT 网关等的数量,它会创建您为您描述的所有内容: Create VPC