evolv-ai / serverless-offline-edge-lambda

A plugin for the Serverless Framework that simulates the behavior of AWS CloudFront Edge Lambdas while developing offline
Other
13 stars 11 forks source link

does not handle list of distributions #7

Open hmoffatt opened 4 years ago

hmoffatt commented 4 years ago

If functions.<function>.lambdaAtEdge is a list of distributions, rather than a single distribution, the plugin does not handle it;

functions:
  lambda:
    handler: handlers.onViewerRequest
    lambdaAtEdge:
      - distribution: 'WebsiteDistribution'
        eventType: 'viewer-request'
        pathPattern: '*'

Results in:

$ sls offline start
Serverless: CloudFront Offline listening on port 8080
Serverless: Cache directory: file:///tmp/edge-lambda
Serverless: Files directory: file:///tmp/edge-lambda

Serverless: Lambdas for path pattern *: 
Serverless: viewer-request => 
Serverless: origin-request => 
Serverless: origin-response => 
Serverless: viewer-response => 

I am attaching the same Lambda to multiple different CloudFront paths (cache behaviours) so I need to list them all for each function.

mattstrom commented 4 years ago

I can correct the inability to define lambdaAtEdge as an array.

That begs the question, though, which you distribution would you expect the offline server to mock? In the live scenario, different distributions would be bound to different domains whereas with the offline server it only has localhost to bind to. Overlaying path patterns from separate distributions is more complexity than I wish to introduce.

hmoffatt commented 4 years ago

That is a fair point. I think it's an acceptable limitation.

In my case I am using a single distribution but it has multiple cache behaviours (different origins and different caching settings for different paths), and CloudFront requires the lambdas to be attached to each, they are not shared.

functions:
  headers:
    handler: handler.headers
    description: Set response headers
    memorySize: 128
    timeout: 1
    lambdaAtEdge:
      - distribution: WebsiteDistribution
        eventType: viewer-response
      - distribution: WebsiteDistribution
        eventType: viewer-response
        pathPattern: 'static/*'
      - distribution: WebsiteDistribution
        eventType: viewer-response
        pathPattern: 'locate/*'

resources:
  Resources:
    WebsiteDistribution:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          CacheBehaviors:
            - 
              PathPattern: 'static/*'
              TargetOriginId: S3Origin
              ViewerProtocolPolicy: redirect-to-https
              MinTTL: 604800
              DefaultTTL: 604800
              MaxTTL: 31536000
              Compress: true
              ForwardedValues:
                QueryString: true
                QueryStringCacheKeys:
                  - v
                Cookies:
                  Forward: 'none'
            - 
              PathPattern: 'locate/*'
              TargetOriginId: DbLocator
              ViewerProtocolPolicy: redirect-to-https
              ForwardedValues:
                QueryString: false
                Cookies:
                  Forward: 'none'

          DefaultCacheBehavior:
            TargetOriginId: S3Origin
            ViewerProtocolPolicy: redirect-to-https
            MinTTL: 604800
            DefaultTTL: 604800
            MaxTTL: 31536000
            Compress: true
            ForwardedValues:
              QueryString: true
              QueryStringCacheKeys:
                - v
              Cookies:
                Forward: 'none'
tstackhouse commented 1 year ago

I'm in a similar situation where I'm using the native cloudFront events to define my edge handlers, and attaching Origin information so they match up with my Resources stanza, like so:

  originRequest:
    handler: functions/origin-request.handler
    events:
      - cloudFront:
          eventType: origin-request
          isDefaultOrigin: true
          origin:
            DomainName: ${self:custom.webAppBucket}.s3.amazonaws.com

Would it be possible for this plugin to use the natives events form of configuration rather than requiring its own special syntax?