AWS Lambda function to connect to a Postgresql database - node.js

Does anyone know how I can connect to a PostgreSQL database through an AWS Lambda function. I searched it up online but I couldn't find anything about it. If you could tell me how to go about it that would be great.
If you can find something wrong with my code (node.js) that would be great otherwise can you tell me how to go about it?
exports.handler = (event, context, callback) => {
"use strict"
const pg = require('pg');
const connectionStr =
"postgres://username:password#host:port/db_name";
var client = new pg.Client(connectionStr);
client.connect(function(err){
if(err) {
callback(err)
}
callback(null, 'Connection established');
});
context.callbackWaitsForEmptyEventLoop = false;
};
The code throws an error:
cannot find module 'pg'
I wrote it directly on AWS Lambda and didn't upload anything if that makes a difference.

I wrote it directly on AWS Lambda and didn't upload anything if that makes a difference.
Yes this makes the difference! Lambda doesnt provide 3rd party libraries out of the box. As soon as you have a dependency on a 3rd party library you need to zip and upload your Lambda code manually or with the use of the API.
Fore more informations: Lambda Execution Environment and Available Libraries

You need to refer Creating a Deployment Package (Node.js)
Simple scenario – If your custom code requires only the AWS SDK library, then you can use the inline editor in the AWS Lambda console. Using the console, you can edit and upload your code to AWS Lambda. The console will zip up your code with the relevant configuration information into a deployment package that the Lambda service can run.
and
Advanced scenario – If you are writing code that uses other resources, such as a graphics library for image processing, or you want to use the AWS CLI instead of the console, you need to first create the Lambda function deployment package, and then use the console or the CLI to upload the package.
Your case like mine falls under Advanced scenario. So we need to create a deployment package and then upload it. Here what I did -
mkdir deployment
cd deployment
vi index.js
write your lambda code in this file. Make sure your handler name is index.handler when you create it.
npm install pg
You should see node_modules directory created in deployment directory which has multiple modules in it
Package the deployment directory into a zip file and upload to Lambda.
You should be good then
NOTE : npm install will install node modules in same directory under node_modules directory unless it sees a node_module directory in parent directory. To be same first do npm init followed by npm install to ensure modules are installed in same directory for deployment.

Related

Running eleventy build (via npm run) as AWS Lambda function

I have a eleventy Node project, which renders HTML from a JSON file.
Currently, I run this locally using npm run (which runs the eleventy CLI)
Here's the workflow I have in my head:
put the JSON file in a S3 bucket
on each file change, run the HTML build
push the output to a different S3 bucket, which serves the web page
Conceptually, I feel like this would be a standard FaaS use case.
Practically, I stumble over the fact that the Node.js-Lambda runtime always expects an explicit function handler to be invoked. It seems Eleventy does not provide a standard way to be invoked from code (or I have not discovered this yet).
I found that I could build my package into a Docker container and run the npm run as Entrypoint. This would surely work, but seems unnecessary, since the Lambda-provided Node.js runtimes should be capable of running my npm build command if I put my packages in the deployment artifact.
Do I have a knot in my brain? Anything I'm overlooking?
Would be happy about any input.
I'm not sure this is supported as I don't see it documented, but I looked at the unit tests for Eleventy and saw many examples of this (https://github.com/11ty/eleventy/tree/master/test). I tried the following and it worked. Note that init an write are both async and I do NOT properly await them, I was just trying to get a simple example:
const Eleventy = require('#11ty/eleventy');
const elev = new Eleventy('./input', './output');
elev.init();
elev.write();
console.log('done');

GCP Cloud Functions not looking for function.js

According to GCP doc
Cloud Functions will look for files with specific names for deployable functions. For Node.js, these filenames are index.js or function.js.
Source: https://cloud.google.com/sdk/gcloud/reference/functions/deploy#--source
In my function.js file, I have:
exports.myFunction = async (req, res) => {}
And I am deploying with this command:
gcloud functions deploy myFunction --entry-point=myFunction \
--region=us-central1 --project=my-gcp-project
This causes this error
Function 'myFunction' is not defined in the provided module.
Did you specify the correct target function to execute?
Could not load the function, shutting down.
Error: function terminated. Recommended action: inspect logs for termination reason.
Curiously enough, the deployment works if I rename function.js to index.js.
Does anyone know what I might be missing here?
Following the recommended structure, you need to import all methods from relevant modules and re-export them in the index.js file so that the Virtual image can find and bind them to the appropriate functions. Without this, your functions could be simply additional code that is used in other methods as Firebase has no way to tell the difference.
I suggest checking out the following documentation:
https://firebase.google.com/docs/functions/organize-functions#write_functions_in_multiple_files

Error while invoking the AWS Lambda function

I am trying to integrate AWS S3 with Lambda, based on this AWS tutorial. When an image is added to S3, it will trigger a Lambda function which will get the image from S3, resize it and upload the same to S3 back again.
After copying the function to the AWS Lambda Management, I do get the below message. I am not sure how to handle it. I am using Node.js 8.10 as the runtime. The complete code can be found here. The file name is index.js, the Lambda handler is index.handler and exports.handler is defined in the Lambda function.
Upon saving the Lambda function and triggering the same by putting an image in S3, I do get the below message in the CloudWatch Logs.
I am not familiar with Node.js and am stuck here. Any solution would be appreciated.
Update: Here is the folder structure or the tree.
The problem is that you have not deployed the Lambda function correctly. This code has dependencies on the GraphicsMagick and Async libraries, and you have not uploaded either of them to Lambda so your require() calls are failing. You should re-read the Tutorial, but basically you need to:
npm init
npm install gm async --save
zip -r function.zip .
aws lambda create-function ... (per the tutorial)
Your deployed Lambda function should look like this (note the inclusion of a package.json file as well as node_modules subfolders for the dependent NPM packages):

Firebase functions - Failed to retrieve function source code

I get the error: "Failed to retrieve function source code" when I try and deploy a function.
This is all from the command line. I am using node 6.11.5 (but in the firebase-admin package.json file in the nodes folder it is says node 6.9.1 is used to download that). I am using firebase-admin#5.8.1 and firebase-functions#0.8.1.
This is the code in my index.js file that I am trying to deploy:
const functions = require('firebase-functions');
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
I have also tried to deploy many different things.
Two interesting things:
- I used to be able to deploy any function without problem. This changed about a month ago and now every function I try gets this error. I can't remember making any change that would be related to this.
- Also I can deploy functions from my computer (with the exact same set up and firebase versions) to other projects in the same google account and different google accounts without any problem.
Thanks
I think you should check your billing settings in google cloud. I got the same problem and after updating billing information then redeploy the function, the error is gone.

Serverless Framework with Azure functions

I am writing services with Serverless Framework & Azure Functions. Examples out there are very simple. But when I try to take a step further, I run into problem. Currently learning from AWS Lambda and then trying to implement it on Azure Functions.
The goal of doing so is:
1) Implement functions as es6 classes and then building the project with webpack.
2) Find a right project structure, which makes more sense.
3) Follow SoC pattern.
I have created a github project https://github.com/GeekOnGadgets/serverless-azure-settings and when I try to build this project serverless package it creates .serverless folder and inside it there is .zip file (the compiled version). Which I understand gets deployed to azure when you run serverless deploy. But when I check on Azure the function is just development code and not the compiled one (please refer to the code below).
Can someone please help with this. Any suggestions is appreciated.
import Settings from './src/Settings/Settings'
module.exports.settings = (event, context, callback) => {
let settings = new Settings();
const response = {
statusCode: 200,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(settings.dev()),
};
callback(null, response);
}
Indeed javascript azure functions run on nodejs so commonjs modules are the natural format. Node also natively supports much of ES6, though the Functions version of node might not be the latest.
however, there is a current speed issue with loading all the dependencies in node_modules. This is due to file access so a workaround exists to bundle everything into a single script which package.json -> main points to.
I cant comment on how that fits in with serverless, but perhaps this will help clarify.
As far as I know, Node.js still does not support import/export ES6 syntax for modules. See also here.
Try a new deploy changing from
import Settings from './src/Settings/Settings'
to
const Settings = require('./src/Settings/Settings')

Resources