Serverless reference variable from file cannot used twice - serverless-framework

Hi I'm implementing a custom CORS for all of my functions and I used an external file to define the CORS object.
service: user
provider:
name: aws
runtime: go1.x
region: us-east-1
functions:
create:
runtime: go1.x
handler: create/bin/main
package:
include:
- ./create/bin/**
events:
- http:
path: user
method: post
cors: ${file(../../serverless-cors.yml):custom.cors}
list:
runtime: go1.x
handler: list/bin/main
package:
include:
- ./list/bin/**
events:
- http:
path: user
method: get
cors: ${file(../../serverless-cors.yml):custom.cors}
show:
runtime: go1.x
handler: show/bin/main
package:
include:
- ./show/bin/**
events:
- http:
path: user/{user-id}
method: get
cors: ${file(../../serverless-cors.yml):custom.cors}
update:
runtime: go1.x
handler: update/bin/main
package:
include:
- ./update/bin/**
events:
- http:
path: user/{user-id}
method: post
cors: ${file(../../serverless-cors.yml):custom.cors}
delete:
runtime: go1.x
handler: delete/bin/main
package:
include:
- ./delete/bin/**
events:
- http:
path: user/{user-id}
method: delete
cors: ${file(../../serverless-cors.yml):custom.cors}
The first reference went ok but the subsequent ones will have when I use sls print
'$["functions"]["create"]["events"][0]["http"]["cors"]'
And it resulted in failure in deploying
Is this a known issue? How can I get past this?
EDIT
here's the content of serverless-cors.yml
custom:
cors:
origin: '*' # <-- Specify allowed origin
headers: # <-- Specify allowed headers
- Content-Type
- X-Amz-Date
- Authorization
- X-Api-Key
- X-Amz-Security-Token
- X-Amz-User-Agent
- TZ
allowCredentials: false
I also tried using a single level (file(../../serverless-cors.yml):cors) variable instead of two level like above with no luck

Try referencing the serverless-cors.yml file relative from the directory that the serverless.yml file is in. For example:
serverless.yml
path/
├──to/
└──└──serverless-cors.yml
# serverless-cors.yml
cors:
origin: '*'
headers:
- Content-Type
- X-Amz-Date
- Authorization
- X-Api-Key
- X-Amz-Security-Token
- X-Amz-User-Agent
- TZ
allowCredentials: false
# serverless.yml
...
events:
- http:
path: something
method: post
cors: ${file(path/to/serverless-cors.yml):cors}

Related

"X-Cache: Miss from cloudfront" as a result of a call to AWS API Gateway

When I send a GET request to AWS APIGateway's URL "https://blablabla.execute-api.us-east-1.amazonaws.com/dev/crs/blablabla.png" or Custom Domain's URL "devblablabla.bla.com" via browser or POSTMAN I receive a 200 response with the "X-Cache: Miss from cloudfront" header:
GET request to AWS APIGateway
Do you have any idea how I can rewrite the serverless.yml file for receiving 200 response with the "X-cache:HIT" header?
This is the configuration that I deploy:
# serverless.yml
service: s3-blablabla-service
provider:
name: aws
stage: dev
region: us-east-1
environment:
SERVICE_NAME: ${self:service}
apiGateway:
binaryMediaTypes: "*/*"
plugins:
- serverless-apigateway-service-proxy
- serverless-domain-manager
- serverless-finch
custom:
c3launchBucketName: "blabla-pl-${self:provider.stage}"
c3scormBucketName: "blabla-crs-${self:provider.stage}"
domainName: "${self:provider.stage}blablabla.bla.com" # Change this to your domain.
basePath: "" # This will be prefixed to all routes
apiGatewayServiceProxies:
- s3:
path: /pl/{myKey+} # use path param
method: get
action: GetObject
bucket:
# ${self:custom.c3launchBucketName}
Ref: S3Bucket
key:
pathParam: myKey
requestParameters:
"integration.request.header.cache-control": "'public, max-age=31536000, immutable'"
- s3:
path: /crs/{myKey+} # use path param
method: get
action: GetObject
bucket:
# ${self:custom.c3scormBucketName}
Ref: S3ScormBucket
key:
pathParam: myKey
requestParameters:
"integration.request.header.cache-control": "'public, max-age=31536000, immutable'"
customDomain:
domainName: ${self:custom.domainName}
basePath: ${self:custom.basePath}
stage: ${self:provider.stage}
createRoute53Record: true
autoDomain: true
client:
bucketName: ${self:custom.c3launchBucketName}
resources:
Resources:
S3Bucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: ${self:custom.c3launchBucketName}
S3ScormBucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: ${self:custom.c3scormBucketName}
After the deployment I receive this result:
endpoints:
GET - https://blablabla.execute-api.us-east-1.amazonaws.com/dev/pl/{myKey+}
GET - https://blablabla.execute-api.us-east-1.amazonaws.com/dev/crs/{myKey+}
Service deployed to stack s3-blablabla-service-dev
Serverless Domain Manager:
Domain Name: devblablabla.bla.com
Target Domain: abrakadabra.cloudfront.net
Hosted Zone Id: BARBARBAR

Lambda is returning headers in body of request

I am using serverless to deploy my express js application in lambda. The weird thing is that some apis are returning headers in the body of the response I am not sure why this is happening. Here is my serverless YAML file:
org: test
app: test-api
# serverless.yml
service: test-api
package:
exclude:
#- node_modules/**
- __tests__/**
provider:
name: aws
runtime: nodejs10.x
region: us-east-1
environment:
SERVICE_NAME: ${self:service}
plugins:
- serverless-domain-manager
custom:
stage: ${opt:stage, dev}
domains:
prod: api.test.com
dev: dev-api.test.com
customDomain:
basePath: "${self:provider.environment.SERVICE_NAME}"
domainName: ${self:custom.domains.${self:custom.stage}}
stage: "${self:custom.stage}"
createRoute53Record: true
functions:
test-api:
handler: build/app.handler
environment:
stage: ${self:custom.stage}
events:
- http:
path: v1/s
method: GET
cors: true
- http:
path: v1/sc
method: GET
cors: true
- http:
path: v1/s/{s}
method: GET
cors: true
- http:
path: v1/cs
method: POST
cors: true
- http:
path: v1/s
method: POST
cors: true
- http:
path: v1/s/{s}
method: DELETE
cors: true
- http:
path: v1/s/{s}
method: PUT
cors: true
Here is what the response looks like:
curl -d '{"c":"test"}' -H "Content-Type: application/json" -X POST https://dev-api.test.com/test-api/v1/cs
HTTP/1.1 200 Not Modified
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: sessionId
Vary: Origin
Content-Type: application/json; charset=utf-8
Content-Length: 55
ETag: W/"37-vmzwGqI9Wb8ACGS7qhhE3/JBqt4"
Date: Fri, 24 Apr 2020 12:30:41 GMT
Connection: keep-alive
{"rsp":{"msg":{"s":[],"c":{}},"err":null}
Any idea if its the serverless yaml or some other configuration?
I was able to fix this, contacted serverless support and they said there was a bug and now it has been fixed. Just need to update serverless and it was resolved!
Looks like you enabled the -i option of curl? Has curl an alias?

Deploying cube.js using serverless framework results in an error

I am trying to deploy cube.js project using serverless framework on aws and when I access the endpoint produced by serverless, it results in the following error on the browser
Cannot GET /
Here is my serverless.yml file
service: cloud-analytics
provider:
name: aws
stage: production
runtime: nodejs8.10
iamRoleStatements:
- Effect: "Allow"
Action:
- "sns:*"
- "athena:*"
- "s3:*"
- "glue:*"
Resource:
- "*"
vpc:
securityGroupIds:
- sg-xxxxxxxxx # Your DB and Redis security groups here
subnetIds:
- subnet-xxxxxxxxx
environment:
CUBEJS_AWS_KEY: ${opt:awsKey}
CUBEJS_AWS_SECRET: ${opt:awsSecret}
CUBEJS_AWS_REGION: us-east-1
CUBEJS_AWS_S3_OUTPUT_LOCATION: ${opt:location}
REDIS_URL: ${opt:redis_url_with_port}
CUBEJS_DB_TYPE: athena
CUBEJS_API_SECRET:XXXXXX
CUBEJS_APP: "${self:service.name}-${self:provider.stage}"
NODE_ENV: ${self:provider.stage}
AWS_ACCOUNT_ID:
Fn::Join:
- ""
- - Ref: "AWS::AccountId"
functions:
cubejs:
handler: cube.api
timeout: 30
events:
- http:
path: /
method: GET
- http:
path: /{proxy+}
method: ANY
cubejsProcess:
handler: cube.process
timeout: 630
events:
- sns: "${self:service.name}-${self:provider.stage}-process"
plugins:
- serverless-express
I have followed this steps in this blog to set up NAT https://medium.com/#philippholly/aws-lambda-enable-outgoing-internet-access-within-vpc-8dd250e11e12
Cube.js file is as follows with server core options
const AWSHandlers = require('#cubejs-backend/serverless-aws');
const AthenaDriver = require('#cubejs-backend/athena-driver');
module.exports = new AWSHandlers({
externalDbType: 'athena',
externalDriverFactory: () => new AthenaDriver({
accessKeyId: process.env.CUBEJS_AWS_KEY,
secretAccessKey: process.env.CUBEJS_AWS_SECRET,
region: process.env.CUBEJS_AWS_REGION,
S3OutputLocation: process.env.CUBEJS_AWS_S3_OUTPUT_LOCATION
})
});
When I run the endpoint
https://xxxxx.execute-api.us-east-1.amazonaws.com/production/
which is produced by the serverless api gateway I get the error
Cannot GET /
On Cloudwatch I see the cubejs lambda being invoked and see logs for start and end request id. I dont see any logs on cubejsProcess lambda.
Where/How can I debug this to see where the issue is?
By default in production mode Cube.js disables dev server capability and it's why you don't see any Playground working at / path: https://cube.dev/docs/deployment#production-mode. Please use REST API to test your deployment: https://cube.dev/docs/rest-api.

Cognito permission to lambda function using serverless framework

I tried giving my lambda function permission to access Cognito and also to invoke another lambda function using the following code in my serverless.yml file.
The code :
# NOTE: update this with your service name
service: xxxx
# Use the serverless-webpack plugin to transpile ES6
plugins:
- serverless-webpack
- serverless-offline
# serverless-webpack configuration
# Enable auto-packing of external modules
custom:
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
provider:
name: aws
runtime: nodejs8.10
stage: dev
region: ap-south-1
environment:
MYSQLHOST: 'xxxx'
MYSQLPORT: 'xxxx'
MYSQLUSER: 'xxxx'
MYSQLPASS: 'xxxx'
MYSQLDATABASE: 'xxxx'
USERPOOLID: 'xxxx'
USERPOOLREGION: 'xxxx'
# To load environment variables externally
# rename env.example to env.yml and uncomment
# the following line. Also, make sure to not
# commit your env.yml.
#
#environment: ${file(env.yml):${self:provider.stage}}
Version: "2012-10-17"
iamRoleStatements:
- Effect: "Allow"
Action:
-cognito-identity:*
-cognito-sync:*
-cognito-idp:*
-lambda:*
Resource:
-"*"
functions:
# Defines an HTTP API endpoint that calls the main function in create.js
# - path: url path is /notes
# - method: POST request
# - cors: enabled CORS (Cross-Origin Resource Sharing) for browser cross
# domain api call
# - authorizer: authenticate using the AWS IAM role
createUser:
handler: createUser.main
events:
- http:
path: users/create
method: post
cors: true
authorizer: aws_iam
getUsers:
handler: getUsers.main
events:
- http:
path: getUsers
method: get
cors: true
authorizer: aws_iam
When I added the permissions for dynamodb , those got added to my lambda Role.But the cognito permissions arent getting attached to the role.
The Serverless Framework , handles the creation of role on its own , based on the yml file.
Once the role gets created , I can add the policy through the AWS console.
But the framework doesn't create them even after specifying.

Serverless Framework: Request must be smaller than 69905067 bytes for the UpdateFunctionCode operation

I am using package uploading zipped file like
frameworkVersion: "=1.27.3"
service: recipes
provider:
name: aws
endpointType: REGIONAL
runtime: python3.6
stage: dev
region: eu-central-1
memorySize: 512
deploymentBucket:
name: dfki-meta
versionFunctions: false
stackTags:
Project: DFKIAPP
# Allows updates to all resources except deleting/replacing EC2 instances
stackPolicy:
- Effect: Allow
Principal: "*"
Action: "Update:*"
Resource: "*"
- Effect: Deny
Principal: "*"
Action:
- Update: Replace
- Update: Delete
Resource: "*"
Condition:
StringEquals:
ResourceType:
- AWS::EC2::Instance
# Access to RDS and S3 Bucket
iamRoleStatements:
- Effect: "Allow"
Action: "s3:ListBucket"
Resource: "*"
package:
individually: true
functions:
# get_recipes:
# handler: handler.get_recipes
# module: recipes_crud
# package:
# individually: true
# timeout: 30
# events:
# - http:
# path: recipes
# method: get
# request:
# parameters:
# querystring:
# persona: true
get_recommendation:
handler: handler.get_recommendation
module: recipes_ml
package:
artifact: zipped_dir.zip
timeout: 30
events:
- http:
path: recipes/{id}
method: get
request:
parameters:
paths:
id: true
querystring:
schaerfe_def: true
saettig_def: true
erfahrung_def: true
schaerfe_wunsch: true
saettig_wunsch: true
erfahrung_wunsch: true
gericht_wunsch: true
stimmung_wunsch: true
Can not understand this error, isn't 52.18 under 69905067 bytes ?
(node:50928) ExperimentalWarning: The fs.promises API is experimental
Serverless: Packaging function: get_recommendation...
Serverless: Uploading function: get_recommendation (52.18 MB)...
Serverless Error ---------------------------------------
Request must be smaller than 69905067 bytes for the UpdateFunctionCode operation
Get Support --------------------------------------------
Docs: docs.serverless.com
Bugs: github.com/serverless/serverless/issues
Issues: forum.serverless.com
Your Environment Information -----------------------------
OS: darwin
Node Version: 10.1.0
Serverless Version: 1.27.3
The package size should be lower than 50MB according to the docs
https://docs.aws.amazon.com/lambda/latest/dg/limits.html
from this blog post
The 20 MB addition presumably is there there to account for request
overhead involved with the AWS API (e.g. base64 encoding of the zip
file data). So far the 50 MB limit holds true-ish. But, we’re not
defeated yet.
This seems to be an issue only while uploading individual lambda function using serverless but if you don't give --function parameter and deploy full stack then it works fine!!!