VPC中的AWS Lambda在NAT后面没有互联网访问权限

时间:2017-03-01 09:00:09

标签: amazon-web-services aws-lambda amazon-vpc amazon-cloudformation

我的问题是我在带有IGW的VPC内部NAT后面运行的Lambda函数无法访问Internet中的任何内容。

我要做的是创建一个具有以下内容的VPC:

  • Internet Gateway;
  • 可用区PrivateAPrivateB中的2个私有子网(AB);
  • 可用区PublicA
  • 中的1个公有子网(A
  • PublicA子网中的NAT网关
  • PrivateAPrivateB有一个路由表,可以将0.0.0.0/0路由到NAT网关。
  • PublicA有一个路由表,可将0.0.0.0/0路由到Internet网关。
  • 私有子网以及公有子网都有访问控制列表,允许所有Ingress和Egress流量。

那部分是有效的。

接下来,我想在VPC中创建一个Lambda函数。我将其放入PrivateAPrivateB并为其分配一个允许所有Egress和Ingress流量的安全组。

下面是一个重现问题的自包含示例(整个模板)。我已经阅读了互联网上所有可能的文档和文章,如果有人能指出我正确的方向,我将非常感激。

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {

    "Vpc": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": "10.0.0.0/16",
        "EnableDnsSupport": true,
        "EnableDnsHostnames": true,
        "InstanceTenancy": "default"
      }
    },

    "InternetGateway": {
      "Type": "AWS::EC2::InternetGateway"
    },

    "VpcGatewayAttachment": {
      "Type": "AWS::EC2::VPCGatewayAttachment",
      "Properties": {
        "VpcId": { "Ref": "Vpc" },
        "InternetGatewayId": { "Ref": "InternetGateway" }
      }
    },

    "ElasticIP":{
      "Type": "AWS::EC2::EIP",
      "Properties": {
        "Domain": "vpc"
      }
    },

    "NatGateway": {
      "Type": "AWS::EC2::NatGateway",
      "DependsOn": [ "VpcGatewayAttachment" ],
      "Properties": {
        "AllocationId": { "Fn::GetAtt": [ "ElasticIP", "AllocationId" ] },
        "SubnetId": { "Ref": "SubnetAPublic" }
      }
    },

    "SubnetAPublic": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "AvailabilityZone": { "Fn::Select" : [ "0", { "Fn::GetAZs" : "" } ] },
        "CidrBlock": "10.0.0.0/19",
        "MapPublicIpOnLaunch": true,
        "VpcId": { "Ref": "Vpc" }
      }
    },

    "SubnetAPrivate": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "AvailabilityZone": { "Fn::Select" : [ "0", { "Fn::GetAZs" : "" } ] },
        "CidrBlock": "10.0.64.0/19",
        "VpcId": { "Ref": "Vpc" }
      }
    },

    "SubnetBPrivate": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "AvailabilityZone": { "Fn::Select" : [ "1", { "Fn::GetAZs" : "" } ] },
        "CidrBlock": "10.0.96.0/19",
        "VpcId": { "Ref": "Vpc" }
      }
    },

    "RouteTablePublic": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": { "Ref": "Vpc" }
      }
    },

    "RouteTablePrivate": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": { "Ref": "Vpc" }
      }
    },

    "RouteTableAssociationAPublic": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": { "Ref": "SubnetAPublic" },
        "RouteTableId": { "Ref": "RouteTablePublic" }
      }
    },

    "RouteTableAssociationAPrivate": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": { "Ref": "SubnetAPrivate" },
        "RouteTableId": { "Ref": "RouteTablePrivate" }
      }
    },

    "RouteTableAssociationBPrivate": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": { "Ref": "SubnetBPrivate" },
        "RouteTableId": { "Ref": "RouteTablePrivate" }
      }
    },

    "RouteTablePrivateInternetRoute": {
      "Type": "AWS::EC2::Route",
      "DependsOn": [ "VpcGatewayAttachment" ],
      "Properties": {
        "RouteTableId": { "Ref": "RouteTablePrivate" },
        "DestinationCidrBlock": "0.0.0.0/0",
        "NatGatewayId": { "Ref": "NatGateway" }
      }
    },

    "RouteTablePublicInternetRoute": {
      "Type": "AWS::EC2::Route",
      "DependsOn": [ "VpcGatewayAttachment" ],
      "Properties": {
        "RouteTableId": { "Ref": "RouteTablePublic" },
        "DestinationCidrBlock": "0.0.0.0/0",
        "GatewayId": { "Ref": "InternetGateway" }
      }
    },

    "NetworkAclPublic": {
      "Type": "AWS::EC2::NetworkAcl",
      "Properties": {
        "VpcId": { "Ref": "Vpc" }
      }
    },

    "NetworkAclPrivate": {
      "Type": "AWS::EC2::NetworkAcl",
      "Properties": {
        "VpcId": { "Ref": "Vpc" }
      }
    },

    "SubnetNetworkAclAssociationAPublic": {
      "Type": "AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId": { "Ref": "SubnetAPublic" },
        "NetworkAclId": { "Ref": "NetworkAclPublic" }
      }
    },

    "SubnetNetworkAclAssociationAPrivate": {
      "Type": "AWS::EC2::SubnetNetworkAclAssociation",
      "Properties":{
        "SubnetId": { "Ref": "SubnetAPrivate" },
        "NetworkAclId": { "Ref": "NetworkAclPrivate" }
      }
    },

    "SubnetNetworkAclAssociationBPrivate": {
      "Type": "AWS::EC2::SubnetNetworkAclAssociation",
      "Properties": {
        "SubnetId": { "Ref": "SubnetBPrivate" },
        "NetworkAclId": { "Ref": "NetworkAclPrivate" }
      }
    },

    "NetworkAclEntryInPublicAllowAll": {
      "Type": "AWS::EC2::NetworkAclEntry",
      "Properties": {
        "NetworkAclId": { "Ref": "NetworkAclPublic" },
        "RuleNumber": 99,
        "Protocol": -1,
        "RuleAction": "allow",
        "Egress": false,
        "CidrBlock": "0.0.0.0/0"
      }
    },

    "NetworkAclEntryOutPublicAllowAll": {
      "Type": "AWS::EC2::NetworkAclEntry",
      "Properties": {
        "NetworkAclId": { "Ref": "NetworkAclPublic" },
        "RuleNumber": 99,
        "Protocol": -1,
        "RuleAction": "allow",
        "Egress": true,
        "CidrBlock": "0.0.0.0/0"
      }
    },

    "NetworkAclEntryInPrivateAllowVpc": {
      "Type": "AWS::EC2::NetworkAclEntry",
      "Properties": {
        "NetworkAclId": { "Ref": "NetworkAclPrivate" },
        "RuleNumber": 99,
        "Protocol": -1,
        "RuleAction": "allow",
        "Egress": false,
        "CidrBlock": "0.0.0.0/16"
      }
    },

    "NetworkAclEntryOutPrivateAllowVpc": {
      "Type": "AWS::EC2::NetworkAclEntry",
      "Properties": {
        "NetworkAclId": { "Ref": "NetworkAclPrivate" },
        "RuleNumber": 99,
        "Protocol": -1,
        "RuleAction": "allow",
        "Egress": true,
        "CidrBlock": "0.0.0.0/0"
      }
    },

    "LambdasSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "Lambdas security group",
        "SecurityGroupEgress": [
          { "CidrIp": "0.0.0.0/0", "IpProtocol": "-1" }
        ],
        "SecurityGroupIngress": [
          { "CidrIp": "0.0.0.0/0", "IpProtocol": "-1" }
        ],
        "VpcId": { "Ref": "Vpc" }
      }
    },

    "LambdaFunctionExecutionRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": { "Service": "lambda.amazonaws.com" },
              "Action": "sts:AssumeRole"
            }
          ]
        },
        "ManagedPolicyArns": [
          "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
          "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
        ]
      }
    },

    "LambdaFunction": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Handler": "index.lambda_handler",
        "Runtime": "python2.7",
        "Role": {
          "Fn::GetAtt": ["LambdaFunctionExecutionRole", "Arn"]
        },
        "Code": {
          "ZipFile": {
            "Fn::Join": ["\n", [
              "import urllib2",
              "def lambda_handler(event, context):",
              "\tresponse = urllib2.urlopen('http://python.org/')",
              "\treturn response.read()"
            ]]
          }
        },
        "VpcConfig": {
          "SecurityGroupIds": [
            { "Fn::GetAtt": [ "LambdasSecurityGroup", "GroupId"] }
          ],
          "SubnetIds": [
            { "Ref": "SubnetAPrivate" },
            { "Ref": "SubnetBPrivate" }
          ]
        }
      }
    }
  }
}

1 个答案:

答案 0 :(得分:5)

连接失败的原因在于您的ACL配置" NetworkAclEntryInPrivateAllowVpc"和" NetworkAclEntryOutPrivateAllowVpc"。

如果您从" 0.0.0.0/16"打开该CIDR块;到" 0.0.0.0/0&#34 ;, Lambda可以访问互联网。

我对NAT知之甚少,但似乎NAT流量被该ACL规则阻止。