dherault / serverless-offline

Emulate AWS λ and API Gateway locally when developing your Serverless project
MIT License
5.19k stars 795 forks source link

New ALB feature #1623

Closed vangyyy closed 11 months ago

vangyyy commented 1 year ago

I was delighted, when I saw the support for ALB being added with recent update.

When I tried it however, I got an error like this:

Error:
TypeError: Cannot read properties of undefined (reading '0')
    at HttpServer.createRoutes (file:///home/ec2-user/environment/apollo-x/api/node_modules/serverless-offline/src/events/alb/HttpServer.js:310:46)
    at Alb.#createEvent (file:///home/ec2-user/environment/apollo-x/api/node_modules/serverless-offline/src/events/alb/Alb.js:46:22)
    at file:///home/ec2-user/environment/apollo-x/api/node_modules/serverless-offline/src/events/alb/Alb.js:51:24
    at Array.forEach (<anonymous>)
    at Alb.create (file:///home/ec2-user/environment/apollo-x/api/node_modules/serverless-offline/src/events/alb/Alb.js:50:12)
    at ServerlessOffline.#createAlb (file:///home/ec2-user/environment/apollo-x/api/node_modules/serverless-offline/src/ServerlessOffline.js:238:15)
    at async Promise.all (index 0)
    at async ServerlessOffline.start (file:///home/ec2-user/environment/apollo-x/api/node_modules/serverless-offline/src/ServerlessOffline.js:97:5)
    at async ServerlessOffline.#startWithExplicitEnd (file:///home/ec2-user/environment/apollo-x/api/node_modules/serverless-offline/src/ServerlessOffline.js:151:5)
    at async PluginManager.runHooks (/home/ec2-user/environment/apollo-x/api/node_modules/serverless/lib/classes/plugin-manager.js:530:9)
    at async PluginManager.invoke (/home/ec2-user/environment/apollo-x/api/node_modules/serverless/lib/classes/plugin-manager.js:564:9)
    at async PluginManager.run (/home/ec2-user/environment/apollo-x/api/node_modules/serverless/lib/classes/plugin-manager.js:604:7)
    at async Serverless.run (/home/ec2-user/environment/apollo-x/api/node_modules/serverless/lib/serverless.js:170:5)
    at async /home/ec2-user/environment/apollo-x/api/node_modules/serverless/scripts/serverless.js:787:9

We are defining our ALB with cloud formation syntax from within serverless config itself and attatching the event by the reference:

functions:
  handler:
    handler: src/app.handler
    timeout: 300
    layers:
      - Ref: NodeLambdaLayer
    events:
      - alb:
          listenerArn:
            Ref: HTTPSListener
          priority: 1
          conditions:
            path: /

[...more functions]

resources:
  Resources:
    SecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties:
        GroupName: ${self:custom.prefix}-sg
        GroupDescription: 'HTTP/HTTPS inbound; All outbound'
        VpcId: ${param:vpcId}
        SecurityGroupIngress:
          - IpProtocol: tcp
            FromPort: 80
            ToPort: 80
            CidrIp: 10.0.0.0/8
          - IpProtocol: tcp
            FromPort: 443
            ToPort: 443
            CidrIp: 10.0.0.0/8
        SecurityGroupEgress:
          - IpProtocol: -1 # All protocols
            FromPort: -1 # All ports
            ToPort: -1 # All ports
            CidrIp: 0.0.0.0/0
          - IpProtocol: -1 # All protocols
            FromPort: -1 # All ports
            ToPort: -1 # All ports
            CidrIpv6: ::/0

    LoadBalancer:
      Type: AWS::ElasticLoadBalancingV2::LoadBalancer
      Properties:
        Type: application
        Name: ${self:custom.prefix}-alb
        Scheme: internal
        IpAddressType: ipv4
        Subnets: ${param:subnetIds}
        SecurityGroups:
          - Ref: SecurityGroup
        LoadBalancerAttributes:
          - Key: 'idle_timeout.timeout_seconds'
            Value: 300
          - Key: 'routing.http.drop_invalid_header_fields.enabled'
            Value: true

    TargetGroup:
      Type: AWS::ElasticLoadBalancingV2::TargetGroup
      Properties:
        Name: ${self:custom.prefix}-tg
        TargetType: lambda
        Targets:
          - Id: { Fn::GetAtt: ['HandlerLambdaFunction', 'Arn'] }

    HTTPSListener:
      Type: AWS::ElasticLoadBalancingV2::Listener
      Properties:
        DefaultActions:
          - Type: forward
            TargetGroupArn:
              Ref: TargetGroup
        LoadBalancerArn:
          Ref: LoadBalancer
        Port: 443
        Protocol: HTTPS
        SslPolicy: ELBSecurityPolicy-FS-1-2-Res-2020-10
        # Certificates:
        #   - CertificateArn: ${param:certArn}

I have noticed, that in tests the load balancer is always being referenced by its ARN.

Is this kind of ALB definition supported, or do I need to have it already deployed and reference its ARN?

dnalborczyk commented 1 year ago

thank you for filing the issue @vangyyy

ALB support was recently added as experimental feature as we anticipated some missing features or bugs.

it seems the current ALB code expects a method to be defined, but according to the serverless docs it's not required.