gpt4 book ai didi

amazon-web-services - aws Lambda 创建的 ENI 在删除堆栈时未删除

转载 作者:行者123 更新时间:2023-12-03 23:22:49 27 4
gpt4 key购买 nike

CloudFormation 创建 Lambda 函数。当执行该函数时,lambda 会自动配置 ENI。 ENI 似乎在函数执行后仍然存在,以加快后续函数的执行速度。 CloudFormation 删除 lambda 函数。 EN 仍然落后。尝试删除 VPC CloudFormation 堆栈 时,堆栈删除失败,因为 ENI 正在使用安全组和子网

在我的lambda角色中,有删除权限

"Effect": "Allow", "Action": [ "ec2:CreateNetworkInterface", "ec2:DeleteNetworkInterface", "ec2:DescribeNetworkInterfaces" ], "Resource": "*"

我正在使用自定义资源从 CloudFormation 模板运行 lambda,因此 lambda 将被称为堆栈创建和删除。 ENI 将用于创建堆栈和删除堆栈。现在如何处理 eni 删除?

最佳答案

在 VPC 中使用 Lambda 函数时存在一个已知问题,如 Configuring a Lambda Function to Access Resources in an Amazon VPC 中所述。 :

There is a delay between the time your Lambda function executes and ENI deletion. If you do delete the role immediately after function execution, you are responsible for deleting the ENIs.

文档没有具体说明这个“延迟”会持续多久,但是 forum post by Richard@AWS建议它可持续长达6 小时(!)。 (根据我使用 AWS CloudTrail 的观察,Lambda 执行和 ENI 删除之间的延迟约为一小时。)

在 AWS 进一步解决此问题之前,您可以通过在删除 Lambda 函数和删除关联的安全组和子网之间分离和删除剩余的 ENI 来解决此问题。就是这样Terraform目前handles这个issue在其框架中。

您可以通过将 VPC/子网/SG 层和 Lambda 函数层分离到两个不同的 CloudFormation 堆栈中来手动执行此操作,也可以通过实现自定义资源来使用 AWS 开发工具包删除 ENI 来自动执行此操作。

以下是一个完整的工作示例,该示例创建 VPC-Lambda 自定义资源,并在使用 VPCDestroyENI 自定义资源删除其 ENI 时清理其 ENI:

Launch Stack

Description: Creates a VPC-Lambda Custom Resource, cleaning up ENIs when deleted.
Parameters:
VPCId:
Description: VPC Id
Type: AWS::EC2::VPC::Id
SubnetId:
Description: Private Subnet Id
Type: AWS::EC2::Subnet::Id
Resources:
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Lambda VPC security group
VpcId: !Ref VPCId
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: {Service: [lambda.amazonaws.com]}
Action: ['sts:AssumeRole']
Path: "/"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
Policies:
- PolicyName: DetachNetworkInterface
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: ['ec2:DetachNetworkInterface']
Resource: '*'
AppendTest:
Type: Custom::Split
DependsOn: VPCDestroyENI
Properties:
ServiceToken: !GetAtt AppendItemToListFunction.Arn
List: [1, 2, 3]
AppendedItem: 4
AppendItemToListFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: !Sub |
var response = require('cfn-response');
exports.handler = function(event, context) {
var responseData = {Value: event.ResourceProperties.List};
responseData.Value.push(event.ResourceProperties.AppendedItem);
response.send(event, context, response.SUCCESS, responseData);
};
Timeout: 30
Runtime: nodejs4.3
VpcConfig:
SecurityGroupIds: [!Ref SecurityGroup]
SubnetIds: [!Ref SubnetId]
VPCDestroyENIFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: !Sub |
var response = require('cfn-response');
var AWS = require('aws-sdk');
exports.handler = function(event, context) {
console.log("REQUEST RECEIVED:\n", JSON.stringify(event));
if (event.RequestType != 'Delete') {
response.send(event, context, response.SUCCESS, {});
return;
}
var ec2 = new AWS.EC2();
var params = {
Filters: [
{
Name: 'group-id',
Values: event.ResourceProperties.SecurityGroups
},
{
Name: 'description',
Values: ['AWS Lambda VPC ENI: *']
}
]
};
console.log("Deleting attachments!");
// Detach all network-interface attachments
ec2.describeNetworkInterfaces(params).promise().then(function(data) {
console.log("Got Interfaces:\n", JSON.stringify(data));
return Promise.all(data.NetworkInterfaces.map(function(networkInterface) {
var networkInterfaceId = networkInterface.NetworkInterfaceId;
var attachmentId = networkInterface.Attachment.AttachmentId;
return ec2.detachNetworkInterface({AttachmentId: attachmentId}).promise().then(function(data) {
return ec2.waitFor('networkInterfaceAvailable', {NetworkInterfaceIds: [networkInterfaceId]}).promise();
}).then(function(data) {
console.log("Detached Interface, deleting:\n", networkInterfaceId);
return ec2.deleteNetworkInterface({NetworkInterfaceId: networkInterfaceId}).promise();
});
}));
}).then(function(data) {
console.log("Success!");
response.send(event, context, response.SUCCESS, {});
}).catch(function(err) {
console.log("Failure:\n", JSON.stringify(err));
response.send(event, context, response.FAILED, {});
});
};
Timeout: 300
Runtime: nodejs4.3
VPCDestroyENI:
Type: Custom::VPCDestroyENI
Properties:
ServiceToken: !GetAtt VPCDestroyENIFunction.Arn
SecurityGroups: [!Ref SecurityGroup]
Outputs:
Output:
Description: output
Value: !Join [",", !GetAtt AppendTest.Value]

注意:要创建上例中所需的 VPC 和私有(private)子网,您可以使用 AWS Quick Start Amazon VPC Architecture template .

关于amazon-web-services - aws Lambda 创建的 ENI 在删除堆栈时未删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41299662/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com