Serverless framework - Deploying a function with a different runtime - aws-lambda

I'm using a Serverless framework to deploy multiple Lambda functions in which all of them runs on NodeJS. Now I need to create a new lambda function that runs on Java11 and I want its configuration to be in the same yaml file along with my other lambda functions. My jar file is uploaded to an S3 bucket and I'm referencing that bucket in my Serverless config to fetch the package from there and deploy it to the function, however, it seems like a wrong package is being deployed to my function as I noticed that the file size is larger than the actual size of my JAR file. Therefore, when I run my lambda function it fails as it cannot find the handler due to incorrect package deployed. I verified it by uploading manually the jar file to my Java lambda function and it worked.
Below is the code snippet of my yaml file:
---
service: api
provider:
name: aws
stackName: ${self:custom.prefix}-${opt:stage}-${self:service.name}
runtime: nodejs14.x
stage: ${opt:custom_stage, opt:stage}
tracing:
lambda: Active
timeout: 30
logRetentionInDays: 180
environment:
STAGE: ${opt:stage, opt:stage}
ENVIRONMENT: ${self:provider.stage}
SUPPRESS_NO_CONFIG_WARNING: true
ALLOW_CONFIG_MUTATIONS: true
functions:
sample-function-1:
role: arn:aws:iam::#{AWS::AccountId}:role/${self:custom.prefix}-${self:provider.stage}-sample-function-1
name: ${self:custom.prefix}-${opt:stage}-sample-function-1
handler: authorizers/handler.authHandler1
sample-function-2:
role: arn:aws:iam::#{AWS::AccountId}:role/${self:custom.prefix}-${self:provider.stage}-sample-function-2
name: ${self:custom.prefix}-${opt:stage}-sample-function-2
handler: authorizers/handler.authHandler1
myJavaFunction:
role: arn:aws:iam::#{AWS::AccountId}:role/${self:custom.prefix}-${self:provider.stage}-myJavaFunction-role
name: ${self:custom.prefix}-${opt:stage}-myJavaFunction
runtime: java11
package:
artifact: s3://myBucket/myJarFile.jar
handler: com.myFunction.LambdaFunctionHandler
memorySize: 512
timeout: 900
How can I deploy the correct package to my lambda function by fetching the jar file from S3 bucket?

Related

how i can add a http api stage in serverless

I am trying to deploy a serverless application to different stages (prod and dev). I want to deploy it to a single API gateway on two different stages
like:-
http://vfdfdf.execute-api.us-west-1.amazonaws.com/dev/
http://vfdfdf.execute-api.us-west-1.amazonaws.com/prod/
I have written a code in serverless -
provider:
name: aws
runtime: nodejs14.x
region: ${self:custom.${self:custom.stage}.lambdaRegion}
httpApi:
id: ${self:custom.${self:custom.stage}.httpAPIID}
stage: ${opt:stage, 'dev'}
Edited to reflect the comments
That can be done during the serverless deployment phase.
I would just have the dev by default in the serverless yml file
provider:
name: aws
runtime: nodejs14.x
stage: dev
region: eu-west-1
httpApi:
# Attach to an externally created HTTP API via its ID:
id: w6axy3bxdj
# or commented on the very first deployment so serverless creates the HTTP API
custom:
stage: ${opt:stage, self:provider.stage}
functions:
hello:
handler: handler.hello
events:
- httpApi:
path: /${self:custom.stage}/hello
method: get
Then, the command:
serverless deploy
deploys in stage dev and region here eu-west-1. It's using the default values.
endpoint: GET - https://w6axy3bxdj.execute-api.eu-west-1.amazonaws.com/dev/hello
While for production, the default values can be overridden on the command line. Then I would use the command:
serverless deploy --stage prod
endpoint: GET - https://w6axy3bxdj.execute-api.eu-west-1.amazonaws.com/prod/hello
In my understanding, you do not change the region between dev and prod; but in case you would want to do that. The production deployment could be:
serverless deploy --stage prod --region eu-west-2
to deploy in a different region than the default one from the serverless yml file.

Cannot add lambda layer via GUI or programmatically, but works via cloud formation. Failed to unzip archive: Zip file contains invalid files/folders;

I'm following this excellent article: https://github.com/vittorio-nardone/selenium-chromium-lambda/
End to end the example works correctly - I just want to re-use the layers that are created in my own function.
Whatever method I use to try and add the layer fails. Manually using GUI,Boto3 in python or the AWS CLI, although it is working on the function setup up by the cloud formation script.
aws lambda update-function-configuration --function-name='test_headless' --layers='arn:aws:lambda:eu-west-1:366134052888:layer:SeleniumChromiumLayer:1'
An error occurred (InvalidParameterValueException) when calling the UpdateFunctionConfiguration operation: Failed to unzip archive: Zip file contains invalid files/folders;
Clearly I'm missing something here:
Partial Extract from cloud formation script:
ScreenshotFunction:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.7
Description: Function to take a screenshot of a website.
Handler: src/lambda_function.lambda_handler
Role:
Fn::GetAtt: [ "ScreenshotFunctionRole", "Arn" ]
Environment:
Variables:
PYTHONPATH: "/var/task/src:/opt/python"
PATH: "/opt/bin:/opt/bin/lib"
URL:
Ref: WebSite
BUCKET:
Ref: BucketName
DESTPATH:
Ref: ScreenshotsFolder
Timeout: 60
MemorySize: 2048
Code:
S3Bucket:
Ref: BucketName
S3Key:
Fn::Sub: '${SourceFolder}/ScreenshotFunction.zip'
Layers:
- Ref: SeleniumChromiumLayer
SeleniumChromiumLayer:
Type: AWS::Lambda::LayerVersion
Properties:
CompatibleRuntimes:
- python3.7
- python3.6
Content:
S3Bucket:
Ref: BucketName
S3Key:
Fn::Sub: '${SourceFolder}/SeleniumChromiumLayer.zip'
Description: Selenium and Chromium Layer for Python3.6
How is it that the contents of the zip used can be OK to add via cloudformation but not in any other manner?
Seems there was some corruption on a function - add the layer to another function worked successfully

how to include secret.json files in SAM template.yml

In my previous application, I work with a serverless framework but now I want to use sam template.
when I used serverless I include secret.json in one section and used multiple places like this way ${self:custom.secrets.AWS_ID}.
My sample code:
custom:
secrets: ${file(secrets.json)}
tableName: ${self:custom.secrets.DB_TABLE_NAME}
provider:
name: aws
runtime: nodejs12.x
environment:
JWT_SECRET: ${self:custom.secrets.JWT_SECRET}
AWS_ID: ${self:custom.secrets.AWS_ID}
DB_TABLE_NAME: ${self:custom.secrets.DB_TABLE_NAME}
Now my question is, how can I include secret.json and use multiple places in sam template.yml file

Serverless.yml config to deploy one lambda function to a service without removing the others

I have the following serverless.yml:
service: my-service
provider:
name: aws
runtime: python3.7
package:
individually: true
functions:
main:
handler: src/main.lambda_handler
name: my-new-func
package:
individually: true
But deploying this will purge all other functions in my-service apparently, even though I use the individually: true option.
Is it possible to deploy one lambda function without change to the other functions?

lambda#edge cloudfront resource creation

I'm a little lost here, I'm trying to deploy a simple function that uses Lambda#edge but I having some problems creating the Cloudfront resource and attaching that CF to the lambda function.
Here is an example of the serverless.yml
service: some-service
plugins:
- serverless-pseudo-parameters
provider:
name: aws
runtime: nodejs10.x
stage: ${env:STAGE}
region: us-east-1
resources:
- ${file(./resources.yml):resources}
functions:
- ${file(./lambda-at-edge/function.yml):functions}
The function definition:
functions:
lambda-at-edge-function:
description: Lambda at edge authentication
handler: serverless/index.handler
events:
- cloudFront:
eventType: viewer-response
origin: s3://some.s3.amazonaws.com/
One thing if I don't define the Cloudfront resources it's not created and If I define the resource and attach that to the serverless definition it's create the resource, but then I don' know how to attach that cloudfront to the function.
Edit:
So I'm deploying everithing with sls deploy, so my question now is how can I attach the funtion name to be used in LambdaFunctionAssociations from cloudfront distribution.
When using Lambda#edge you have to respect the limits.
Check them out here:
Requirements and Restrictions on Lambda Functions
This should work:
service: some-service
plugins:
- serverless-pseudo-parameters
provider:
name: aws
runtime: nodejs10.x
stage: ${env:STAGE}
region: us-east-1
memorySize: 128
timeout: 5
resources:
- ${file(./resources.yml):resources}
functions:
- ${file(./lambda-at-edge/function.yml):functions}

Resources