I have been trying for a day to configure automating a lambda@Edge to be associated with a Distribution through the serverless framework but things aren't working well.
Here is the documentation and they said we can use a predefined cloud front distribution from resources but not shown how?
Here is my Resources.yml that include the S3 bucket and associated two distribution's origins to it:
Resources:
ResourcesBucket:
    Type: AWS::S3::Bucket
    Properties:
        BucketName: ${self:custom.resourcesBucketName}
        AccessControl: Private
        CorsConfiguration:
            CorsRules:
            -   AllowedHeaders: ['*']
                AllowedMethods: ['PUT']
                AllowedOrigins: ['*']
ResourcesBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
        Bucket:
            Ref: ResourcesBucket
        PolicyDocument:
            Statement:
            # Read permission for CloudFront
            -   Action: s3:GetObject
                Effect: "Allow"
                Resource: 
                    Fn::Join: 
                        - ""
                        - 
                            - "arn:aws:s3:::"
                            - 
                                Ref: "ResourcesBucket"
                            - "/*"
                Principal:
                    CanonicalUser: !GetAtt CloudFrontOriginAccessIdentity.S3CanonicalUserId
CloudFrontOriginAccessIdentity:
    Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
    Properties:
        CloudFrontOriginAccessIdentityConfig:
            Comment:
                Fn::Join: 
                    - ""
                    -
                            - "Identity for accessing CloudFront from S3 within stack "
                            - 
                                Ref: "AWS::StackName"
                            - ""
                # I can use this instead of Fn::Join !Sub 'Identity for accessing CloudFront from S3 within stack #{AWS::StackName}' Getting benefit of
                # serverless-pseudo-parameters plugin
# Cloudfront distro backed by ResourcesBucket
ResourcesCdnDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
        DistributionConfig:
            Origins:
                # S3 origin for private resources
                -   DomainName: !Sub '${self:custom.resourcesBucketName}.s3-${self:provider.region}.amazonaws.com'
                    Id: S3OriginPrivate
                    S3OriginConfig:
                        OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/#{CloudFrontOriginAccessIdentity}'
                # S3 origin for public resources           
                -   DomainName: !Sub '${self:custom.resourcesBucketName}.s3-${self:provider.region}.amazonaws.com'
                    Id: S3OriginPublic
                    S3OriginConfig:
                        OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/#{CloudFrontOriginAccessIdentity}'
            Enabled: true
            Comment: CDN for public and provate static content.
            DefaultRootObject: index.html
            HttpVersion: http2
            DefaultCacheBehavior:
                AllowedMethods:
                    - DELETE
                    - GET
                    - HEAD
                    - OPTIONS
                    - PATCH
                    - POST
                    - PUT
                Compress: true
                TargetOriginId: S3OriginPublic
                ForwardedValues:
                    QueryString: false
                    Headers:
                    - Origin
                    Cookies:
                        Forward: none
                ViewerProtocolPolicy: redirect-to-https
            CacheBehaviors:
                - 
                    PathPattern: 'private/*'
                    TargetOriginId: S3OriginPrivate
                    AllowedMethods:
                    - DELETE
                    - GET
                    - HEAD
                    - OPTIONS
                    - PATCH
                    - POST
                    - PUT
                    Compress: true
                    ForwardedValues:
                        QueryString: false
                        Headers:
                            - Origin
                        Cookies:
                            Forward: none
                    ViewerProtocolPolicy: redirect-to-https
                - 
                    PathPattern: 'public/*'
                    TargetOriginId: S3OriginPublic
                    AllowedMethods:
                    - DELETE
                    - GET
                    - HEAD
                    - OPTIONS
                    - PATCH
                    - POST
                    - PUT
                    Compress: true
                    ForwardedValues:
                        QueryString: false
                        Headers:
                            - Origin
                        Cookies:
                            Forward: none
                    ViewerProtocolPolicy: redirect-to-https
            PriceClass: PriceClass_200
Now I have all set regarding the CloudFront and I just want to add a lambda at the edge to authenticate my private content (The Origin with Id: S3OriginPrivate). So here is my serverless.yml file:
        service: mda-app-uploads
    
    plugins:
      - serverless-offline
      - serverless-pseudo-parameters
      - serverless-iam-roles-per-function
    
    custom:
      stage: ${opt:stage, self:provider.stage}
      resourcesBucketName: ${self:custom.stage}-mda-resources-bucket
    
    
        provider:
          name: aws
          runtime: nodejs12.x
          stage: ${opt:stage, 'dev'}
          region: us-east-1
          versionFunctions: true
        
        
        
        resources:
          - ${file(resources/s3-cloudfront.yml)}
          
        # functions:
        functions: 
          mdaAuthEdge:
            handler: mda-edge-auth.handler
            events:
              - cloudFront:
                  eventType: viewer-request
                  origin:
                    Id: S3OriginPrivate
When deploying I am getting this issue:
TypeError: Cannot read property 'replace' of undefined
This telling that this id already exists and can't be replaced as I think. My main focus is to get the lambda at edge deployed and associated with the cloud front within the serverless framework, so I made another trial to add almost everything to the cloud formation resources and depend only on the serverless framework in deploying the function and here was my serverless.yml and the resources file:
service: mda-app-uploads
plugins:
  - serverless-offline
  - serverless-pseudo-parameters
  - serverless-iam-roles-per-function
custom:
  stage: ${opt:stage, self:provider.stage}
  resourcesBucketName: ${self:custom.stage}-mda-resources-bucket
provider:
  name: aws
  runtime: nodejs12.x
  stage: ${opt:stage, 'dev'}
  region: us-east-1
  versionFunctions: true
resources:
  # Buckets
  - ${file(resources/s3-cloudfront.yml)}
  
# functions:
functions: 
  mdaAuthEdge:
    handler: mda-edge-auth.handler
    role: LambdaEdgeFunctionRole
The resources:
Resources:
    LambdaEdgeFunctionRole:
        Type: "AWS::IAM::Role"
        Properties:
            Path: "/"
            ManagedPolicyArns:
                - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
            AssumeRolePolicyDocument:
                Version: "2012-10-17"
                Statement:
                -
                    Sid: "AllowLambdaServiceToAssumeRole"
                    Effect: "Allow"
                    Action: 
                        - "sts:AssumeRole"
                    Principal:
                        Service: 
                            - "lambda.amazonaws.com"
                            - "edgelambda.amazonaws.com"
    LambdaEdgeFunctionPolicy:
        Type: "AWS::IAM::Policy"
        Properties:
            PolicyName: MainEdgePolicy
            PolicyDocument:
                Version: "2012-10-17"
                Statement:
                    Effect: "Allow"
                    Action: 
                        - "lambda:GetFunction"
                        - "lambda:GetFunctionConfiguration"
                    Resource: !Ref MdaAuthAtEdgeLambdaFunction.Version #!Join [':', [!GetAtt MdaAuthAtEdgeLambdaFunction.Arn, '2']]
            Roles:
                - !Ref LambdaEdgeFunctionRole
    ResourcesBucket:
        Type: AWS::S3::Bucket
        Properties:
            BucketName: ${self:custom.resourcesBucketName}
            AccessControl: Private
            CorsConfiguration:
                CorsRules:
                -   AllowedHeaders: ['*']
                    AllowedMethods: ['PUT']
                    AllowedOrigins: ['*']
    ResourcesBucketPolicy:
        Type: AWS::S3::BucketPolicy
        Properties:
            Bucket:
                Ref: ResourcesBucket
            PolicyDocument:
                Statement:
                # Read permission for CloudFront
                -   Action: s3:GetObject
                    Effect: "Allow"
                    Resource: 
                        Fn::Join: 
                            - ""
                            - 
                                - "arn:aws:s3:::"
                                - 
                                    Ref: "ResourcesBucket"
                                - "/*"
                    Principal:
                        CanonicalUser: !GetAtt CloudFrontOriginAccessIdentity.S3CanonicalUserId
    
    CloudFrontOriginAccessIdentity:
        Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
        Properties:
            CloudFrontOriginAccessIdentityConfig:
                Comment:
                    Fn::Join: 
                        - ""
                        -
                                - "Identity for accessing CloudFront from S3 within stack "
                                - 
                                    Ref: "AWS::StackName"
                                - ""
                    # I can use this instead of Fn::Join !Sub 'Identity for accessing CloudFront from S3 within stack #{AWS::StackName}' Getting benefit of
                    # serverless-pseudo-parameters plugin
    # Cloudfront distro backed by ResourcesBucket
    ResourcesCdnDistribution:
        Type: AWS::CloudFront::Distribution
        Properties:
            DistributionConfig:
                Origins:
                    # S3 origin for private resources
                    -   DomainName: !Sub '${self:custom.resourcesBucketName}.s3-${self:provider.region}.amazonaws.com'
                        Id: S3OriginPrivate
                        S3OriginConfig:
                            OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/#{CloudFrontOriginAccessIdentity}'
                    # S3 origin for public resources           
                    -   DomainName: !Sub '${self:custom.resourcesBucketName}.s3-${self:provider.region}.amazonaws.com'
                        Id: S3OriginPublic
                        S3OriginConfig:
                            OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/#{CloudFrontOriginAccessIdentity}'
                Enabled: true
                Comment: CDN for public and provate static content.
                DefaultRootObject: index.html
                HttpVersion: http2
                DefaultCacheBehavior:
                    AllowedMethods:
                        - DELETE
                        - GET
                        - HEAD
                        - OPTIONS
                        - PATCH
                        - POST
                        - PUT
                    Compress: true
                    TargetOriginId: S3OriginPublic
                    ForwardedValues:
                        QueryString: false
                        Headers:
                        - Origin
                        Cookies:
                            Forward: none
                    ViewerProtocolPolicy: redirect-to-https
                CacheBehaviors:
                    - 
                        PathPattern: 'private/*'
                        TargetOriginId: S3OriginPrivate
                        AllowedMethods:
                        - DELETE
                        - GET
                        - HEAD
                        - OPTIONS
                        - PATCH
                        - POST
                        - PUT
                        Compress: true
                        LambdaFunctionAssociations:
                            - 
                                EventType: origin-request
                                LambdaFunctionARN: !Ref MdaAuthEdgeLambdaFunction.Version
                                    #!Join [':', [!GetAtt MdaAuthAtEdgeLambdaFunction.Arn, '2']]
            #    arn:aws:lambda:eu-west-1:219511374676:function:mda-aws-functions-dev-authLambdaAtEdge:1
                        ForwardedValues:
                            QueryString: false
                            Headers:
                                - Origin
                            Cookies:
                                Forward: none
                        ViewerProtocolPolicy: redirect-to-https
                    - 
                        PathPattern: 'public/*'
                        TargetOriginId: S3OriginPublic
                        AllowedMethods:
                        - DELETE
                        - GET
                        - HEAD
                        - OPTIONS
                        - PATCH
                        - POST
                        - PUT
                        Compress: true
                        ForwardedValues:
                            QueryString: false
                            Headers:
                                - Origin
                            Cookies:
                                Forward: none
                        ViewerProtocolPolicy: redirect-to-https
                PriceClass: PriceClass_200
But I've faced many errors related to defining the version and so on. I searched, debugged, and investigated that for many hours but seems hard configuration. Any help on how to get lambda edge works with predefined cloud front through the serverless framework?