AWS Lambda在大约12小时后使用带有EIP的NAT网关丢失与VPC中的SQS的连接

时间:2018-05-10 06:35:26

标签: amazon-web-services aws-lambda amazon-sqs amazon-sns

我已经设置了一个VPC,包括3个子网,1个互联网网关,1个NAT网关,1个RDS群集,SQS队列以及更多内容(请参阅下面的完整配置)。

部署后一切正常。我的云功能可以访问RDS,SQS并毫无问题地发布到SNS。但是,经过几个小时(我的猜测是12小时),一切都停止了工作!

在断开连接之后,调用几小时前工作正常的lambda会导致超时。删除NAT网关时获得的结果相同(因为Lambda将无法再访问VPC中的SQS或SNS)。

这是我的CloudFormation /无服务器模板:

ServerlessVPC:
  Type: AWS::EC2::VPC
  Properties:
    CidrBlock: '10.0.0.0/16'
    EnableDnsSupport: true
    EnableDnsHostnames: true
    Tags:
      - Key: Name
        Value: pulse-${self:provider.stage}

ElasticIP:
  Type: AWS::EC2::EIP
  DependsOn:
    - AttachInternetGateway
  Properties:
    Domain: vpc

InternetGateway:
  Type: AWS::EC2::InternetGateway
  Properties:
    Tags:
      - Key: Name
        Value: pulse-${self:provider.stage}

NATGateway:
  Type: AWS::EC2::NatGateway
  Properties:
    AllocationId:
      Fn::GetAtt: 'ElasticIP.AllocationId'
    SubnetId:
      Ref: SubnetAPublic
    Tags:
      - Key: Name
        Value: pulse-${self:provider.stage}

AttachInternetGateway:
  Type: AWS::EC2::VPCGatewayAttachment
  DependsOn:
    - InternetGateway
    - ServerlessVPC
  Properties:
    VpcId:
      Ref: ServerlessVPC
    InternetGatewayId:
      Ref: InternetGateway

RouteTableEC2Bastion:
  Type: AWS::EC2::RouteTable
  Properties:
    VpcId:
      Ref: ServerlessVPC
    Tags:
      - Key: Name
        Value: pulse-${self:provider.stage}-bastion

RouteTableLambda:
  Type: AWS::EC2::RouteTable
  Properties:
    VpcId:
      Ref: ServerlessVPC
    Tags:
      - Key: Name
        Value: pulse-${self:provider.stage}-lambda

InternetRoute:
  Type: AWS::EC2::Route
  DependsOn:
    - RouteTableEC2Bastion
    - InternetGateway
  Properties:
    RouteTableId:
      Ref: RouteTableEC2Bastion
    DestinationCidrBlock: '0.0.0.0/0'
    GatewayId:
      Ref: InternetGateway

NATRoute:
  Type: AWS::EC2::Route
  DependsOn:
    - RouteTableLambda
    - InternetGateway
  Properties:
    RouteTableId:
      Ref: RouteTableLambda
    DestinationCidrBlock: '0.0.0.0/0'
    NatGatewayId:
      Ref: NATGateway

PublicSubnetRouteTableAssociation:
  Type: AWS::EC2::SubnetRouteTableAssociation
  DependsOn:
    - SubnetAPublic
    - RouteTableEC2Bastion
  Properties:
    SubnetId:
      Ref: SubnetAPublic
    RouteTableId:
      Ref: RouteTableEC2Bastion

LambdaSubnetRouteTableAssociationA:
  Type: AWS::EC2::SubnetRouteTableAssociation
  DependsOn:
    - SubnetBPrivate
    - RouteTableLambda
  Properties:
    SubnetId:
      Ref: SubnetBPrivate
    RouteTableId:
      Ref: RouteTableLambda

LambdaSubnetRouteTableAssociationB:
  Type: AWS::EC2::SubnetRouteTableAssociation
  DependsOn:
    - SubnetCPrivate
    - RouteTableLambda
  Properties:
    SubnetId:
      Ref: SubnetCPrivate
    RouteTableId:
      Ref: RouteTableLambda

SubnetAPublic:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::Subnet
  Properties:
    VpcId:
      Ref: ServerlessVPC
    AvailabilityZone: ${self:provider.region}a
    CidrBlock: '10.0.0.0/24'
    Tags:
      - Key: Name
        Value: pulse-${self:provider.stage}-publicA

SubnetBPrivate:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::Subnet
  Properties:
    VpcId:
      Ref: ServerlessVPC
    AvailabilityZone: ${self:provider.region}b
    CidrBlock: '10.0.1.0/24'
    Tags:
      - Key: Name
        Value: pulse-${self:provider.stage}-privateB

SubnetCPrivate:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::Subnet
  Properties:
    VpcId:
      Ref: ServerlessVPC
    AvailabilityZone: ${self:provider.region}c
    CidrBlock: '10.0.2.0/24'
    Tags:
      - Key: Name
        Value: pulse-${self:provider.stage}-privateC

BastionServer:
  Type: AWS::EC2::Instance
  Properties:
    ImageId: ami-3bfab942
    InstanceType: t2.nano
    KeyName: remente-pulse-${self:provider.stage}-bastion
    NetworkInterfaces:
      - AssociatePublicIpAddress: true
        DeleteOnTermination: true
        DeviceIndex: 0
        GroupSet:
          - Ref: BastionSecurityGroup
        SubnetId:
          Ref: SubnetAPublic
    Tags:
      - Key: Name
        Value: pulse-${self:provider.stage}-bastion

ServerlessSecurityGroup:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: Serverless Functions security group
    VpcId:
      Ref: ServerlessVPC

BastionSecurityGroup:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: Bastion EC2 instance security group
    VpcId:
      Ref: ServerlessVPC
    SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        CidrIp: '0.0.0.0/0'

RDSSecurityGroup:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: Ingress for RDS Instance
    VpcId:
      Ref: ServerlessVPC
    SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 3306
        ToPort: 3306
        Description: Lambda access
        SourceSecurityGroupId:
          Ref: ServerlessSecurityGroup
      - IpProtocol: tcp
        FromPort: 3306
        ToPort: 3306
        Description: Bastion access
        SourceSecurityGroupId:
          Ref: BastionSecurityGroup

ServerlessRDSSubnetGroup:
  Type: AWS::RDS::DBSubnetGroup
  Properties:
    DBSubnetGroupDescription: RDS Subnet Group
    SubnetIds:
    - Ref: SubnetBPrivate
    - Ref: SubnetCPrivate

ServerlessRDSCluster:
  DependsOn:
    - ServerlessVPC
    - RDSSecurityGroup
  Type: AWS::RDS::DBInstance
  Properties:
    Engine: ${self:custom.dbClient}
    DBName: ${self:custom.dbName}
    MasterUsername: ${self:custom.dbUser}
    MasterUserPassword: ${self:custom.dbPassword}
    DBInstanceClass: ${file(./serverless.env.yml):${self:provider.stage}.db.instance}
    AllocatedStorage: ${file(./serverless.env.yml):${self:provider.stage}.db.storage}
    DBSubnetGroupName:
      Ref: ServerlessRDSSubnetGroup
    VPCSecurityGroups:
      - Ref: RDSSecurityGroup

# -----------------------------------------------------------------
# Users & Groups

PublishTopicUser:
  Type: AWS::IAM::User

PublishTopicGroup:
  Type: AWS::IAM::Group
  Properties:
    Policies:
      - PolicyName: ${self:custom.iamSurveySend}
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Resource:
                Ref: SendSurveyTopic
              Action:
                - sns:Publish

AddUserToPublishTopicGroup:
  Type: AWS::IAM::UserToGroupAddition
  Properties:
    GroupName:
      Ref: PublishTopicGroup
    Users:
      - Ref: PublishTopicUser

QueuePolicy:
  Type: AWS::SQS::QueuePolicy
  Properties:
    Queues:
      - Ref: SendSurveyEmailQueue
      - Ref: SendSurveySMSQueue
    PolicyDocument:
      Id: sqs-policy
      Version: '2012-10-17'
      Statement:
        - Sid: Allow-SendMessage-to-queues-from-SNS-Topic
          Effect: Allow
          Principal: '*'
          Resource: '*'
          Action:
            - sqs:SendMessage
          Condition:
            ArnEquals:
              aws:SourceArn:
                Ref: SendSurveyTopic

# -----------------------------------------------------------------
# SNS Topics & SQS Queues

SendSurveyTopic:
  Type: AWS::SNS::Topic
  Properties:
    TopicName: ${self:custom.snsSendSurveyTopic}
    Subscription:
      - Protocol: sqs
        Endpoint:
          Fn::GetAtt: [SendSurveyEmailQueue, Arn]
      - Protocol: sqs
        Endpoint:
          Fn::GetAtt: [SendSurveySMSQueue, Arn]

SendSurveyEmailQueue:
  Type: AWS::SQS::Queue
  Properties:
    QueueName: ${self:custom.sqsSurveySendEmail}
    MessageRetentionPeriod: 300
    VisibilityTimeout: 60
    RedrivePolicy:
      deadLetterTargetArn:
        Fn::GetAtt: [SendSurveyEmailQueueDead, Arn]
      maxReceiveCount: 10

SendSurveyEmailQueueDead:
  Type: AWS::SQS::Queue
  Properties:
    QueueName: ${self:custom.sqsSurveySendEmail}-dead
    MessageRetentionPeriod: 300

SendSurveySMSQueue:
  Type: AWS::SQS::Queue
  Properties:
    QueueName: ${self:custom.sqsSurveySendSMS}
    MessageRetentionPeriod: 300
    VisibilityTimeout: 60
    RedrivePolicy:
      deadLetterTargetArn:
        Fn::GetAtt: [SendSurveyEmailQueueDead, Arn]
      maxReceiveCount: 10

SendSurveySMSQueueDead:
  Type: AWS::SQS::Queue
  Properties:
    QueueName: ${self:custom.sqsSurveySendSMS}-dead
    MessageRetentionPeriod: 300

我唯一的猜测是它与弹性IP有关,但我真的不知道如何避免这种脱节。

0 个答案:

没有答案