使用boto3从AWS Lambda启动EC2实例时超时

7

我希望用户只在需要时启动EC2实例。

因此,我创建了一个Lambda函数来实现这一点:

import boto3

def lambda_handler(event, context):
    ec2 = boto3.resource('ec2', region_name='eu-central-1')
    return ec2.instances.filter(InstanceIds=['i-abc123']).start()

我已添加以下IAM权限:

    {
        "Effect": "Allow",
        "Action": [
            "ec2:StartInstances"
        ],
        "Resource": "arn:aws:ec2:*"
    },
    {
        "Effect": "Allow",
        "Action": [
            "ec2:DescribeInstances"
        ],
        "Resource": "*"
    }

问题是当我执行 Lambda 时,它会超时。

顺便提一下,在同一 VPC 和相同权限的 EC2 中运行完全相同的代码会立即返回。

有什么想法吗?


你是否为Lambda函数启用了VPC访问? - Mark B
你是否在Lambda中设置了适当的IAM角色和用户? http://docs.aws.amazon.com/lambda/latest/dg/setting-up.html您可能需要将资源arn更改为"arn:aws:ec2:accoun-id:user-name"Lambda脚本还需要特定的用户凭据来确定资源。 - mootmoot
我已将 Lambda 的 VPC 配置为与 EC2 实例相同。 - Michael
我设置了正确的IAM角色。不确定如何设置Lambda的用户? - Michael
2个回答

3
如果凭据是问题,你不会遇到超时的情况。更可能的是,你在使用小内存模型,而 boto 占用了大量内存,即使进行简单的操作也是如此。试着使用更大的内存模型或更长的超时时间来运行。
如果这确实是问题所在,考虑在类初始化代码中创建 ec2 资源或使用单例模式,以便后续调用可以使用同一个资源。但是,请确保设置函数超时时间,使其有足够的时间进行初始化和正常职责,即使这似乎没有必要。如果你的函数出现错误,下一次运行可能包含类初始化时间。

1
我曾经面对过完全相同的问题。我的情况是一个私有子网中有1个Lambda和一个公共子网中有1个EC2实例。而且这两个子网都在同一个VPC内。
我的安全组允许这两个资源之间的入站和出站流量。
我的Lambda函数调用了EC2函数,比如describeInstances()、startInstances()、stopInstances()。
这段代码在本地运行正常,但是当部署为Lambda函数时,总是抛出函数超时错误。我增加了函数超时时间和内存,但问题没有解决。
事实证明,在没有访问互联网的情况下,Lambda函数无法直接访问/调用/启动/停止位于VPC内的EC2实例。
要解决这个问题,你需要使用NAT网关/实例或VPC终端节点。
对于小规模项目来说,最便宜的解决方案是使用一个NAT实例,它将允许你的私有子网中的Lambda函数与互联网连接。所以对我来说,生成一个NAT实例解决了超时问题,Lambda函数可以正常调用EC2实例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接