如何使用 AWS 上的 NAT 让我的私有子网访问互联网?

如何使用 AWS 上的 NAT 让我的私有子网访问互联网?

我正在尝试通过 AWS 上的 NAT 实例让我的私有子网访问互联网。我的云信息设置如下:

我的 VPC:

"VPC": {
  "Type": "AWS::EC2::VPC",
  "Properties": {
    "CidrBlock": { "Fn::FindInMap" : [ "SubnetConfig", "VPC", "CIDR" ]},
    "EnableDnsSupport": "true",
    "EnableDnsHostnames": "true",
    "InstanceTenancy": "default"
  }
},

"PublicRouteTable" : {
   "Type" : "AWS::EC2::RouteTable",
   "Properties" : {
      "VpcId" : { "Ref" : "VPC" }
   }
},

"PrivateRouteTable" : {
   "Type" : "AWS::EC2::RouteTable",
   "Properties" : {
      "VpcId" : { "Ref" : "VPC" }
   }
},

我的公共端互联网网关:

"InternetGateway" : {
   "Type" : "AWS::EC2::InternetGateway",
   "Properties" : {
     "Tags" : [
       {"Key": "Name", "Value": { "Fn::Join" : ["_", ["InternetGateway", { "Ref": "AWS::StackName" } ]]}},
       {"Key": "Domain", "Value": { "Ref": "DomainName" }}
     ]
   }
},

"AttachGateway": {
   "Type" : "AWS::EC2::VPCGatewayAttachment",
   "Properties" : {
      "VpcId" : { "Ref" : "VPC" },
      "InternetGatewayId" : { "Ref" : "InternetGateway" }
   }
},

"InternetRoute" : {
   "Type" : "AWS::EC2::Route",
   "DependsOn" : "InternetGateway",
   "Properties" : {
      "RouteTableId" : { "Ref" : "PublicRouteTable" },
      "DestinationCidrBlock" : "0.0.0.0/0",
      "GatewayId" : { "Ref" : "InternetGateway" }
   }
},

我的三个子网:

"SubnetPrivateA": {
  "Type": "AWS::EC2::Subnet",
  "DependsOn" : ["VPC"],
  "Properties": {
    "VpcId": { "Ref": "VPC" },
    "CidrBlock": { "Fn::FindInMap" : [ "SubnetConfig", "PrivateA", "CIDR" ]},
    "AvailabilityZone": { "Fn::Select": [ "0", { "Fn::GetAZs": { "Ref": "AWS::Region" } }]}
  }
},

"SubnetPrivateB": {
  "Type": "AWS::EC2::Subnet",
  "DependsOn" : ["VPC"],
  "Properties": {
    "VpcId": { "Ref": "VPC" },
    "CidrBlock": { "Fn::FindInMap" : [ "SubnetConfig", "PrivateB", "CIDR" ]},
    "AvailabilityZone": { "Fn::Select": [ "1", { "Fn::GetAZs": { "Ref": "AWS::Region" } }]}
  }
},

"SubnetPublic": {
  "Type": "AWS::EC2::Subnet",
  "DependsOn" : ["VPC"],
  "Properties": {
    "VpcId": { "Ref": "VPC" },
    "CidrBlock": { "Fn::FindInMap" : [ "SubnetConfig", "Public", "CIDR" ]},
    "AvailabilityZone": { "Fn::Select": [ "1", { "Fn::GetAZs": { "Ref": "AWS::Region" } }]}
  }
},

将子网与路由表关联

"SubnetPrivateARouteTableAssociation" : {
   "Type" : "AWS::EC2::SubnetRouteTableAssociation",
   "Properties" : {
      "SubnetId" : { "Ref" : "SubnetPrivateA" },
      "RouteTableId" : { "Ref" : "PrivateRouteTable" }
   }
},

"SubnetPrivateBRouteTableAssociation" : {
   "Type" : "AWS::EC2::SubnetRouteTableAssociation",
   "Properties" : {
      "SubnetId" : { "Ref" : "SubnetPrivateB" },
      "RouteTableId" : { "Ref" : "PrivateRouteTable" }
   }
},

"SubnetPublicRouteTableAssociation" : {
   "Type" : "AWS::EC2::SubnetRouteTableAssociation",
   "Properties" : {
      "SubnetId" : { "Ref" : "SubnetPublic" },
      "RouteTableId" : { "Ref" : "PublicRouteTable" }
   }
},

创建两个安全组,一个用于位于私有子网中的 lambda,一个用于位于公共子网中的 nat。

"LambdaSecurityGroup": {
  "Type": "AWS::EC2::SecurityGroup",
  "Properties": {
    "GroupDescription": "Security group for Lambda",
    "VpcId": {"Ref": "VPC"},
    "SecurityGroupEgress" : [
      { "IpProtocol" : "tcp", "FromPort" : "1",  "ToPort" : "65535",  "CidrIp" : "0.0.0.0/0"}
    ]
  }
},

"NatSecurityGroup" : {
  "DependsOn" : ["VPC"],
  "Type" : "AWS::EC2::SecurityGroup",
  "Properties" : {
    "GroupDescription" : "NAT Security Group",
    "VpcId" : { "Ref" : "VPC" },
    "SecurityGroupIngress" : [
      { "IpProtocol" : "tcp", "FromPort" : "1",  "ToPort" : "65535",  "SourceSecurityGroupId" : { "Ref" : "LambdaSecurityGroup" } }
    ],
    "SecurityGroupEgress" : [
      { "IpProtocol" : "tcp", "FromPort" : "1",  "ToPort" : "65535",  "CidrIp" : "0.0.0.0/0"}
    ]
  }
},

创建 NAT 并添加其路由:

"NAT" : {
  "DependsOn" : ["SubnetPublic", "NatSecurityGroup"],
  "Type" : "AWS::EC2::Instance",
  "Properties" : {
    "InstanceType" : "t2.nano",
    "SourceDestCheck" : "false",
    "ImageId" : { "Fn::FindInMap" : [ "NatRegionMap", { "Ref" : "AWS::Region" }, "AMI" ]},
    "NetworkInterfaces" : [{
      "GroupSet": [{ "Ref" : "NatSecurityGroup" }],
      "AssociatePublicIpAddress": "true",
      "DeviceIndex": "0",
      "DeleteOnTermination": "true",
      "SubnetId": { "Ref" : "SubnetPublic" }
    }],
    "UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
       "#!/bin/bash\n",
       "yum update -y && yum install -y yum-cron && chkconfig yum-cron on"
    ]]}}
  }
},

我的 Lambda 函数仍然无法访问互联网。它们只是超时了。我做错了什么?

更新以下是完整的云图,不包括body。swaggarAWS::ApiGateway::RestApi太大了,无法发布。

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Website",

  "Parameters": {
    "DomainName": {
      "Type": "String",
      "Description": "The DNS name of an Amazon Route 53 hosted zone e.g. server.com",
      "AllowedPattern": "(?!-)[a-zA-Z0-9-.]{1,63}(?<!-)",
      "ConstraintDescription": "must be a valid DNS zone name."
    },
    "DBUsername": {
      "Type": "String",
      "Description": "Master username",
      "AllowedPattern": "[a-zA-Z0-9]{1,20}(?<!-)",
      "ConstraintDescription": "must be a valid username."
    },
    "DBPassword": {
      "Type": "String",
      "Description": "Master password",
      "AllowedPattern": "[a-zA-Z0-9]{1,20}(?<!-)",
      "ConstraintDescription": "must be a valid password."
    }
  },

  "Mappings": {
    "SubnetConfig" : {
      "VPC"     : { "CIDR" : "10.0.0.0/16" },
      "Public"  : { "CIDR" : "10.0.100.0/24" },
      "PrivateA" : { "CIDR" : "10.0.10.0/24" },
      "PrivateB" : { "CIDR" : "10.0.20.0/24" }
    },
    "NatRegionMap" : {
      "us-east-1"      : { "AMI" : "ami-eccf48fa" },
      "us-west-1"      : { "AMI" : "ami-d9247eb9" },
      "us-west-2"      : { "AMI" : "ami-8c55c2ec" },
      "eu-west-1"      : { "AMI" : "ami-ea08368c" },
      "eu-central-1"   : { "AMI" : "ami-7604d419" },
      "sa-east-1"      : { "AMI" : "ami-2070134c" },
      "ap-southeast-1" : { "AMI" : "ami-21ba0542" },
      "ap-southeast-2" : { "AMI" : "ami-5cf4fb3f" },
      "ap-northeast-1" : { "AMI" : "ami-d599bdb2" }
    },
    "S3RegionMap": {
      "us-east-1": { "S3HostedZoneId": "Z3AQBSTGFYJSTF", "S3WebsiteEndpoint": "s3-website-us-east-1.amazonaws.com" },
      "us-west-1": { "S3HostedZoneId": "Z2F56UZL2M1ACD", "S3WebsiteEndpoint": "s3-website-us-west-1.amazonaws.com" },
      "us-west-2": { "S3HostedZoneId": "Z3BJ6K6RIION7M", "S3WebsiteEndpoint": "s3-website-us-west-2.amazonaws.com" },
      "eu-west-1": { "S3HostedZoneId": "Z1BKCTXD74EZPE", "S3WebsiteEndpoint": "s3-website-eu-west-1.amazonaws.com" },
      "ap-southeast-1": { "S3HostedZoneId": "Z3O0J2DXBE1FTB", "S3WebsiteEndpoint": "s3-website-ap-southeast-1.amazonaws.com" },
      "ap-southeast-2": { "S3HostedZoneId": "Z1WCIGYICN2BYD", "S3WebsiteEndpoint": "s3-website-ap-southeast-2.amazonaws.com" },
      "ap-northeast-1": { "S3HostedZoneId": "Z2M4EHUR26P7ZW", "S3WebsiteEndpoint": "s3-website-ap-northeast-1.amazonaws.com" },
      "sa-east-1": { "S3HostedZoneId": "Z31GFT0UA1I2HV", "S3WebsiteEndpoint": "s3-website-sa-east-1.amazonaws.com" }
    }
  },

  "Resources": {
    "LambdaExecutionRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [{
            "Effect": "Allow",
            "Principal": {
              "Service": "lambda.amazonaws.com"
            },
            "Action": [ "sts:AssumeRole" ]
          }]
        },
        "Path": "/",
        "Policies": [{
          "PolicyName": "execution",
          "PolicyDocument": {
            "Statement": [{
              "Effect": "Allow",
              "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
              ],
              "Resource": "*"
            }, {
              "Effect": "Allow",
              "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:ListBucket"
              ],
              "Resource": "*"
            }, {
              "Effect": "Allow",
              "Action": [
                "ec2:DescribeNetworkInterfaces",
                "ec2:CreateNetworkInterface",
                "ec2:DeleteNetworkInterface"
              ],
              "Resource": "*"
            }]
          }
        }]
      }
    },

    "APIGatewayExecutionRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [{
            "Effect": "Allow",
            "Principal": {
              "Service": "apigateway.amazonaws.com"
            },
            "Action": [ "sts:AssumeRole" ]
          }]
        },
        "Path": "/",
        "Policies": [{
          "PolicyName": "execution",
          "PolicyDocument": {
            "Statement": [{
              "Effect": "Allow",
              "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
              ],
              "Resource": "*"
            }, {
              "Effect": "Allow",
              "Action": [
                "lambda:InvokeFunction"
              ],
              "Resource": "*"
            }]
          }
        }]
      }
    },

    "VPC": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": { "Fn::FindInMap" : [ "SubnetConfig", "VPC", "CIDR" ]},
        "EnableDnsSupport": "true",
        "EnableDnsHostnames": "true",
        "InstanceTenancy": "default",
        "Tags" : [
          {"Key": "Name", "Value": { "Fn::Join" : ["_", ["VPC", { "Ref": "AWS::StackName" } ]]}},
          {"Key": "Domain", "Value": { "Ref": "DomainName" }}
        ]
      }
    },

    "PublicRouteTable" : {
       "Type" : "AWS::EC2::RouteTable",
       "Properties" : {
          "VpcId" : { "Ref" : "VPC" },
          "Tags" : [
            {"Key": "Name", "Value": { "Fn::Join" : ["_", ["PublicRouteTable", { "Ref": "AWS::StackName" } ]]}},
            {"Key": "Domain", "Value": { "Ref": "DomainName" }}
          ]
       }
    },

    "PrivateRouteTable" : {
       "Type" : "AWS::EC2::RouteTable",
       "Properties" : {
          "VpcId" : { "Ref" : "VPC" },
          "Tags" : [
            {"Key": "Name", "Value": { "Fn::Join" : ["_", ["PrivateRouteTable", { "Ref": "AWS::StackName" } ]]}},
            {"Key": "Domain", "Value": { "Ref": "DomainName" }}
          ]
       }
    },

    "InternetGateway" : {
       "Type" : "AWS::EC2::InternetGateway",
       "Properties" : {
         "Tags" : [
           {"Key": "Name", "Value": { "Fn::Join" : ["_", ["InternetGateway", { "Ref": "AWS::StackName" } ]]}},
           {"Key": "Domain", "Value": { "Ref": "DomainName" }}
         ]
       }
    },

    "AttachGateway": {
       "Type" : "AWS::EC2::VPCGatewayAttachment",
       "Properties" : {
          "VpcId" : { "Ref" : "VPC" },
          "InternetGatewayId" : { "Ref" : "InternetGateway" }
       }
    },

    "InternetRoute" : {
       "Type" : "AWS::EC2::Route",
       "DependsOn" : "InternetGateway",
       "Properties" : {
          "RouteTableId" : { "Ref" : "PublicRouteTable" },
          "DestinationCidrBlock" : "0.0.0.0/0",
          "GatewayId" : { "Ref" : "InternetGateway" }
       }
    },

    "SubnetPrivateA": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn" : ["VPC"],
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "CidrBlock": { "Fn::FindInMap" : [ "SubnetConfig", "PrivateA", "CIDR" ]},
        "AvailabilityZone": { "Fn::Select": [ "0", { "Fn::GetAZs": { "Ref": "AWS::Region" } }]},
        "Tags" : [
          {"Key": "Name", "Value": { "Fn::Join" : ["_", ["SubnetPrivateA", { "Ref": "AWS::StackName" } ]]}},
          {"Key": "Domain", "Value": { "Ref": "DomainName" }}
        ]
      }
    },

    "SubnetPrivateB": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn" : ["VPC"],
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "CidrBlock": { "Fn::FindInMap" : [ "SubnetConfig", "PrivateB", "CIDR" ]},
        "AvailabilityZone": { "Fn::Select": [ "1", { "Fn::GetAZs": { "Ref": "AWS::Region" } }]},
        "Tags" : [
          {"Key": "Name", "Value": { "Fn::Join" : ["_", ["SubnetPrivateB", { "Ref": "AWS::StackName" } ]]}},
          {"Key": "Domain", "Value": { "Ref": "DomainName" }}
        ]
      }
    },

    "SubnetPublic": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn" : ["VPC"],
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "CidrBlock": { "Fn::FindInMap" : [ "SubnetConfig", "Public", "CIDR" ]},
        "AvailabilityZone": { "Fn::Select": [ "1", { "Fn::GetAZs": { "Ref": "AWS::Region" } }]},
        "Tags" : [
          {"Key": "Name", "Value": { "Fn::Join" : ["_", ["SubnetPublic", { "Ref": "AWS::StackName" } ]]}},
          {"Key": "Domain", "Value": { "Ref": "DomainName" }}
        ]
      }
    },

    "SubnetPrivateARouteTableAssociation" : {
       "Type" : "AWS::EC2::SubnetRouteTableAssociation",
       "Properties" : {
          "SubnetId" : { "Ref" : "SubnetPrivateA" },
          "RouteTableId" : { "Ref" : "PrivateRouteTable" }
       }
    },

    "SubnetPrivateBRouteTableAssociation" : {
       "Type" : "AWS::EC2::SubnetRouteTableAssociation",
       "Properties" : {
          "SubnetId" : { "Ref" : "SubnetPrivateB" },
          "RouteTableId" : { "Ref" : "PrivateRouteTable" }
       }
    },

    "SubnetPublicRouteTableAssociation" : {
       "Type" : "AWS::EC2::SubnetRouteTableAssociation",
       "Properties" : {
          "SubnetId" : { "Ref" : "SubnetPublic" },
          "RouteTableId" : { "Ref" : "PublicRouteTable" }
       }
    },

    "DBSubnetGroup": {
      "Type": "AWS::RDS::DBSubnetGroup",
      "Properties": {
        "DBSubnetGroupDescription": "Database Access",
        "SubnetIds" : [{ "Ref": "SubnetPrivateA"}, {"Ref": "SubnetPrivateB" }],
        "Tags" : [
          {"Key": "Name", "Value": { "Fn::Join" : ["_", ["DBSubnetGroup", { "Ref": "AWS::StackName" } ]]}},
          {"Key": "Domain", "Value": { "Ref": "DomainName" }}
        ]
      }
    },

    "DBEC2SecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "Security group for RDS DB Instance",
        "VpcId": {"Ref": "VPC"},
        "SecurityGroupIngress" : [{
          "IpProtocol": "tcp",
          "FromPort": "3306",
          "ToPort": "3306",
          "CidrIp": "10.0.0.0/16"
        }],
        "Tags" : [
          {"Key": "Name", "Value": { "Fn::Join" : ["_", ["DBEC2SecurityGroup", { "Ref": "AWS::StackName" } ]]}},
          {"Key": "Domain", "Value": { "Ref": "DomainName" }}
        ]
      }
    },

    "LambdaSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "Security group for Lambda",
        "VpcId": {"Ref": "VPC"},
        "SecurityGroupEgress" : [
          { "IpProtocol" : "tcp", "FromPort" : "1",  "ToPort" : "65535",  "CidrIp" : "0.0.0.0/0"}
        ],
        "Tags" : [
          {"Key": "Name", "Value": { "Fn::Join" : ["_", ["LambdaSecurityGroup", { "Ref": "AWS::StackName" } ]]}},
          {"Key": "Domain", "Value": { "Ref": "DomainName" }}
        ]
      }
    },

    "NatSecurityGroup" : {
      "DependsOn" : ["VPC"],
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "NAT Security Group",
        "VpcId" : { "Ref" : "VPC" },
        "SecurityGroupIngress" : [
          { "IpProtocol" : "tcp", "FromPort" : "1",  "ToPort" : "65535",  "SourceSecurityGroupId" : { "Ref" : "LambdaSecurityGroup" } }
        ],
        "SecurityGroupEgress" : [
          { "IpProtocol" : "tcp", "FromPort" : "1",  "ToPort" : "65535",  "CidrIp" : "0.0.0.0/0"}
        ],
        "Tags" : [
          {"Key": "Name", "Value": { "Fn::Join" : ["_", ["NatSecurityGroup", { "Ref": "AWS::StackName" } ]]}},
          {"Key": "Domain", "Value": { "Ref": "DomainName" }}
        ]
      }
    },

    "NAT" : {
      "DependsOn" : ["SubnetPublic", "NatSecurityGroup"],
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "InstanceType" : "t2.nano",
        "SourceDestCheck" : "false",
        "ImageId" : { "Fn::FindInMap" : [ "NatRegionMap", { "Ref" : "AWS::Region" }, "AMI" ]},
        "NetworkInterfaces" : [{
          "GroupSet": [{ "Ref" : "NatSecurityGroup" }],
          "AssociatePublicIpAddress": "true",
          "DeviceIndex": "0",
          "DeleteOnTermination": "true",
          "SubnetId": { "Ref" : "SubnetPublic" }
        }],
        "Tags" : [
          {"Key": "Name", "Value": { "Fn::Join" : ["_", ["NAT", { "Ref": "AWS::StackName" } ]]}},
          {"Key": "Domain", "Value": { "Ref": "DomainName" }}
        ],
        "UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
           "#!/bin/bash\n",
           "yum update -y && yum install -y yum-cron && chkconfig yum-cron on"
        ]]}}
      }
    },

    "PrivateRoute" : {
      "DependsOn" : ["PrivateRouteTable", "NAT"],
      "Type" : "AWS::EC2::Route",
      "Properties" : {
        "RouteTableId" : { "Ref" : "PrivateRouteTable" },
        "DestinationCidrBlock" : "0.0.0.0/0",
        "InstanceId" : { "Ref" : "NAT" }
      }
    },

    "Database": {
      "Type": "AWS::RDS::DBInstance",
      "Properties": {
        "DBName": { "Fn::Join": ["", { "Fn::Split": [".", { "Ref": "DomainName" }]}]},
        "AllocatedStorage": "5",
        "DBInstanceClass": "db.t2.micro",
        "Engine": "MySQL",
        "EngineVersion": "5.5",
        "MasterUsername": { "Ref": "DBUsername" },
        "MasterUserPassword": { "Ref": "DBPassword" },
        "DBSubnetGroupName": { "Ref": "DBSubnetGroup" },
        "VPCSecurityGroups" : [{ "Fn::GetAtt": [ "DBEC2SecurityGroup", "GroupId" ] }],
        "Tags" : [
          {"Key": "Name", "Value": { "Fn::Join" : ["_", ["Database", { "Ref": "AWS::StackName" } ]]}},
          {"Key": "Domain", "Value": { "Ref": "DomainName" }}
        ]
      },
      "DeletionPolicy": "Snapshot"
    },

    "LambdaFunctionUpdate": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "ZipFile": "exports.handler = function (event, context) { context.succeed(\"Hello, World!\"); };"
        },
        "Description": "Used to create and or sync database tables to the application models",
        "Handler": "index.handler",
        "MemorySize": 128,
        "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn" ] },
        "Runtime": "nodejs4.3",
        "Timeout": 30,
        "VpcConfig": {
          "SecurityGroupIds": [{ "Fn::GetAtt": ["LambdaSecurityGroup", "GroupId"] }],
          "SubnetIds": [{"Ref": "SubnetPrivateA"}, {"Ref": "SubnetPrivateB"}]
        }
      }
    },

    "LambdaFunctionValidate": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "ZipFile": "exports.handler = function (event, context) { context.succeed(\"Hello, World!\"); };"
        },
        "Description": "Used to validate a users access token",
        "Handler": "index.handler",
        "MemorySize": 128,
        "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn" ] },
        "Runtime": "nodejs4.3",
        "Timeout": 30,
        "VpcConfig": {
          "SecurityGroupIds": [{ "Fn::GetAtt": ["LambdaSecurityGroup", "GroupId"] }],
          "SubnetIds": [{"Ref": "SubnetPrivateA"}, {"Ref": "SubnetPrivateB"}]
        }
      }
    },

    "LambdaFunctionPicture": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "ZipFile": "exports.handler = function (event, context) { context.succeed(\"Hello, World!\"); };"
        },
        "Description": "Picture resource handler.",
        "Handler": "index.handler",
        "MemorySize": 128,
        "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn" ] },
        "Runtime": "nodejs4.3",
        "Timeout": 30,
        "VpcConfig": {
          "SecurityGroupIds": [{ "Fn::GetAtt": ["LambdaSecurityGroup", "GroupId"] }],
          "SubnetIds": [{"Ref": "SubnetPrivateA"}, {"Ref": "SubnetPrivateB"}]
        }
      }
    },

    "LambdaFunctionReputation": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "ZipFile": "exports.handler = function (event, context) { context.succeed(\"Hello, World!\"); };"
        },
        "Description": "Reputation handler.",
        "Handler": "index.handler",
        "MemorySize": 128,
        "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn" ] },
        "Runtime": "nodejs4.3",
        "Timeout": 30,
        "VpcConfig": {
          "SecurityGroupIds": [{ "Fn::GetAtt": ["LambdaSecurityGroup", "GroupId"] }],
          "SubnetIds": [{"Ref": "SubnetPrivateA"}, {"Ref": "SubnetPrivateB"}]
        }
      }
    },

    "LambdaFunctionUser": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "ZipFile": "exports.handler = function (event, context) { context.succeed(\"Hello, World!\"); };"
        },
        "Description": "User handler.",
        "Handler": "index.handler",
        "MemorySize": 128,
        "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn" ] },
        "Runtime": "nodejs4.3",
        "Timeout": 30,
        "VpcConfig": {
          "SecurityGroupIds": [{ "Fn::GetAtt": ["LambdaSecurityGroup", "GroupId"] }],
          "SubnetIds": [{"Ref": "SubnetPrivateA"}, {"Ref": "SubnetPrivateB"}]
        }
      }
    },

    "APIGateway": {
      "Type": "AWS::ApiGateway::RestApi",
      "Properties": {
        "Body": [REMOVED FROM POST, ITS LONG],
        "FailOnWarnings": true,
        "Name": { "Fn::Join": ["-", { "Fn::Split": [".", { "Fn::Join": ["", ["api.", { "Ref": "DomainName" }]]}]}]}
      }
    },

    "APIDeployment": {
      "Type": "AWS::ApiGateway::Deployment",
      "Properties": {
        "RestApiId": { "Ref": "APIGateway" },
        "Description": "Deploy for live",
        "StageName": "Live"
      }
    },

    "WebsiteBucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": {"Ref":"DomainName"},
        "AccessControl": "PublicRead",
        "WebsiteConfiguration": {
          "IndexDocument": "index.html",
          "ErrorDocument": "404.html"
        },
        "Tags" : [
          {"Key": "Name", "Value": { "Fn::Join" : ["_", ["WebsiteBucket", { "Ref": "AWS::StackName" } ]]}},
          {"Key": "Domain", "Value": { "Ref": "DomainName" }}
        ]
      },
      "DeletionPolicy": "Retain"
    },

    "WWWBucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": {
          "Fn::Join": ["", ["www.", { "Ref":"DomainName" }]]
        },
        "AccessControl": "BucketOwnerFullControl",
        "WebsiteConfiguration": {
          "RedirectAllRequestsTo": {
            "HostName": {"Ref": "WebsiteBucket"}
          }
        },
        "Tags" : [
          {"Key": "Name", "Value": { "Fn::Join" : ["_", ["WWWBucket", { "Ref": "AWS::StackName" } ]]}},
          {"Key": "Domain", "Value": { "Ref": "DomainName" }}
        ]
      }
    },

    "WebsiteBucketPolicy": {
      "Type": "AWS::S3::BucketPolicy",
      "Properties": {
        "Bucket": {"Ref": "WebsiteBucket"},
        "PolicyDocument": {
          "Statement": [{
            "Action": [ "s3:GetObject" ],
            "Effect": "Allow",
            "Resource": { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref": "WebsiteBucket" } , "/*" ]]},
            "Principal": "*"
          }]
        }
      }
    },

    "WWWBucketPolicy": {
      "Type": "AWS::S3::BucketPolicy",
      "Properties": {
        "Bucket": {"Ref": "WWWBucket"},
        "PolicyDocument": {
          "Statement": [{
            "Action": [ "s3:GetObject" ],
            "Effect": "Allow",
            "Resource": { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref": "WWWBucket" } , "/*" ]]},
            "Principal": "*"
          }]
        }
      }
    },

    "DNS": {
      "Type": "AWS::Route53::HostedZone",
      "Properties": {
        "HostedZoneConfig": {
          "Comment": { "Fn::Join" : ["", ["Hosted zone for ", { "Ref": "DomainName" }]]}
        },
        "Name": { "Ref": "DomainName" },
        "HostedZoneTags" : [{
          "Key": "Application",
          "Value": "Blog"
        }]
      }
    },

    "DNSRecord": {
      "Type": "AWS::Route53::RecordSetGroup",
      "Properties": {
        "HostedZoneName": {
            "Fn::Join": [ "", [{ "Ref": "DomainName" }, "." ]]
        },
        "Comment": "Zone records.",
        "RecordSets": [
          {
            "Name": { "Ref": "DomainName" },
            "Type": "A",
            "AliasTarget": {
              "HostedZoneId": { "Fn::FindInMap" : [ "S3RegionMap", { "Ref": "AWS::Region" }, "S3HostedZoneId" ]},
              "DNSName": { "Fn::FindInMap" : [ "S3RegionMap", { "Ref": "AWS::Region" }, "S3WebsiteEndpoint" ]}
            }
          }, {
            "Name": { "Fn::Join" : ["", ["www.", { "Ref": "DomainName" }]]},
            "Type": "A",
            "AliasTarget": {
              "HostedZoneId": { "Fn::FindInMap" : [ "S3RegionMap", { "Ref": "AWS::Region" }, "S3HostedZoneId" ]},
              "DNSName": { "Fn::FindInMap" : [ "S3RegionMap", { "Ref": "AWS::Region" }, "S3WebsiteEndpoint" ]}
            }
          }
        ]
      }
    }
  },

  "Outputs": {
    "S3WebsiteURL": {
      "Value": { "Fn::GetAtt": ["WebsiteBucket", "WebsiteURL" ] },
      "Description": "URL for website hosted on S3"
    },
    "DatabaseEndpoint": {
      "Value": { "Fn::Join" : [":", [{ "Fn::GetAtt": ["Database", "Endpoint.Address" ] }, { "Fn::GetAtt": ["Database", "Endpoint.Port" ] }]]},
      "Description": "Database endpoint"
    },
    "NATIP" : {
      "Description" : "NAT IP address",
      "Value" : { "Fn::GetAtt" : [ "NAT", "PublicIp" ] }
    }
  }
}

答案1

您使用的是 AWS NAT 实例,它应该运行良好。我唯一怀疑的是您的 NAT 实例位于私有子网内,这意味着它无法访问互联网。

您需要使用 EIP 才能使 NAT 实例访问互联网。

您的 NAT 实例应位于公共网络中。另外,请检查源/目标,因为应禁用它以使 NAT 实例作为路由器工作。

答案2

请检查您的 Lambda 函数是否已连接到具有 NAT 实例或 NAT 网关的私有或公共子网,

检查子网的网络 ACL(传出规则),

还请检查安全组。

相关内容