Cloudformation自定义资源失败

0

【以下的问题经过翻译处理】 在过去的两天里,下面这个CloudFormation模板启动失败了。该模板使用了cfn-response和NodeJS10运行时。Lambda函数没有成功发送cfn-response的成功或失败信号,导致模板在运行了三个小时后卡住了。请问SDK有做过任何更新吗?

AWSTemplateFormatVersion: '2010-09-09'

Description: ENI extraction template for API Gateway VPC Endpoint

Parameters:
  VPCId:
    Type: AWS::EC2::VPC::Id
    Description: VPC for the Lambda and VPC endpoint
  SecurityGroupIds:
    Type: List<AWS::EC2::SecurityGroup::Id>
    Description: Security group Ids for the Lambda and VPC endpoint
  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
    Description: Subnet Ids for the Lambda

Resources:

  # Get the VPCe ENI IPs using custom resource
  GetPrivateIPsRole:
    Type: AWS::IAM::Role
    Properties:
      Path: "/"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service: "lambda.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
      Policies:
        - PolicyName: "GetPrivateIPs"
          PolicyDocument:
            Statement:
              - Action:
                  - "ec2:DescribeNetworkInterfaces"
                  - "ec2:CreateNetworkInterface"
                  - "ec2:DeleteNetworkInterface"
                  - "ec2:DescribeInstances"
                  - "ec2:AttachNetworkInterface"
                Effect: "Allow"
                Resource: "*"

  GetPrivateIPsLambda:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ZipFile: |
          const AWS = require('aws-sdk');
          const response = require('cfn-response');

          exports.handler = function(event, context) {

            console.log("============================================================");
            console.log(event);
            console.log("============================================================");

            var networkInterfaceIdsList = event.ResourceProperties.NetworkInterfaceIds;
            var ec2 = new AWS.EC2();
            var params = {
              NetworkInterfaceIds: networkInterfaceIdsList
            };
            ec2.describeNetworkInterfaces(params, function(err, data) {
              if (err) {
                var responseData = {}
                responseData["IP0"] = "Fail";
                responseData["IP1"] = "Fail";
                responseData["IP2"] = "Fail";
                response.send(event, context, response.FAILED, responseData);
              } // an error occurred
              else {
                var networkInterfaceIPs = [];
                data.NetworkInterfaces.forEach(function getNetworkInterfaceIPs(item, index){
                  var ip = item.PrivateIpAddress;
                  networkInterfaceIPs.push(ip)
                });
                var responseData = {}
                responseData["IP0"] = networkInterfaceIPs[0];
                responseData["IP1"] = networkInterfaceIPs[1];
                responseData["IP2"] = networkInterfaceIPs[2];
                response.send(event, context, response.SUCCESS, responseData);
              }// successful response
            });
          };
      VpcConfig:
        SecurityGroupIds: !Ref SecurityGroupIds
        SubnetIds: !Ref SubnetIds
      Handler: index.handler
      Description: Extract the VPCe ENI private IPs
      Role: !GetAtt GetPrivateIPsRole.Arn
      Runtime: nodejs10.x
      Timeout: 60

  # Get the VPCe private IPs for the NLB target group
  GetPrivateIPs:
    Type: Custom::GetPrivateIPs
    Properties:
      ServiceToken: !GetAtt GetPrivateIPsLambda.Arn
      NetworkInterfaceIds: !GetAtt ApiGatewayVPCEndpoint.NetworkInterfaceIds

  ApiGatewayVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcEndpointType: Interface
      VpcId: !Ref VPCId
      SubnetIds: !Ref SubnetIds
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.execute-api'
      SecurityGroupIds: !Ref SecurityGroupIds
      PrivateDnsEnabled: false

profile picture
专家
已提问 5 个月前30 查看次数
1 回答
0

【以下的回答经过翻译处理】 为了增加安全性并确保顺利运行,我们在模板中添加了一个DependsOn条件,并延长了超时时间(因为VPC Lambda可能需要更长的时间)...

同时,在使用私有子网中的S3 gateway endpoint和EC2 interface endpoint时,一切都按预期运行。

AWSTemplateFormatVersion: '2010-09-09'
Description: ENI extraction template for API Gateway VPC Endpoint
Parameters:
  VPCId:
    Type: AWS::EC2::VPC::Id
    Description: VPC for the Lambda and VPC endpoint
    Default: "vpc-xxxxx"
  SecurityGroupIds:
    Type: List<AWS::EC2::SecurityGroup::Id>
    Description: Security group Ids for the Lambda and VPC endpoint
    Default: "sg-xxxx"
  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
    Description: Subnet Ids for the Lambda
    Default: "subnet-xxxx, subnet-yyyy"

Resources:

  # Get the VPCe ENI IPs using custom resource
  GetPrivateIPsRole:
    Type: AWS::IAM::Role
    Properties:
      Path: "/"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service: "lambda.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
      Policies:
        - PolicyName: "GetPrivateIPs"
          PolicyDocument:
            Statement:
              - Action:
                  - "ec2:DescribeNetworkInterfaces"
                  - "ec2:CreateNetworkInterface"
                  - "ec2:DeleteNetworkInterface"
                  - "ec2:DescribeInstances"
                  - "ec2:AttachNetworkInterface"
                Effect: "Allow"
                Resource: "*"

  GetPrivateIPsLambda:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ZipFile: |
          const AWS = require('aws-sdk');
          const response = require('cfn-response');

          exports.handler = function(event, context) {

            console.log("============================================================");
            console.log(event);
            console.log("============================================================");

            var networkInterfaceIdsList = event.ResourceProperties.NetworkInterfaceIds;
            var ec2 = new AWS.EC2();
            var params = {
              NetworkInterfaceIds: networkInterfaceIdsList
            };
            ec2.describeNetworkInterfaces(params, function(err, data) {
              if (err) {
                var responseData = {}
                responseData["IP0"] = "Fail";
                responseData["IP1"] = "Fail";
                responseData["IP2"] = "Fail";
                response.send(event, context, response.FAILED, responseData);
              } // an error occurred
              else {
                var networkInterfaceIPs = [];
                data.NetworkInterfaces.forEach(function getNetworkInterfaceIPs(item, index){
                  var ip = item.PrivateIpAddress;
                  networkInterfaceIPs.push(ip)
                });
                var responseData = {}
                responseData["IP0"] = networkInterfaceIPs[0];
                responseData["IP1"] = networkInterfaceIPs[1];
                responseData["IP2"] = networkInterfaceIPs[2];
                response.send(event, context, response.SUCCESS, responseData);
              }// successful response
            });
          };
      VpcConfig:
        SecurityGroupIds: !Ref SecurityGroupIds
        SubnetIds: !Ref SubnetIds
      Handler: index.handler
      Description: Extract the VPCe ENI private IPs
      Role: !GetAtt GetPrivateIPsRole.Arn
      Runtime: nodejs10.x
      Timeout: 360

  # Get the VPCe private IPs for the NLB target group
  GetPrivateIPs:
    Type: Custom::GetPrivateIPs
    DependsOn: [ApiGatewayVPCEndpoint]
    Properties:
      ServiceToken: !GetAtt GetPrivateIPsLambda.Arn
      NetworkInterfaceIds: !GetAtt ApiGatewayVPCEndpoint.NetworkInterfaceIds

  ApiGatewayVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcEndpointType: Interface
      VpcId: !Ref VPCId
      SubnetIds: !Ref SubnetIds
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.execute-api'
      SecurityGroupIds: !Ref SecurityGroupIds
      PrivateDnsEnabled: false
profile picture
专家
已回答 5 个月前

您未登录。 登录 发布回答。

一个好的回答可以清楚地解答问题和提供建设性反馈,并能促进提问者的职业发展。

回答问题的准则