DEV Community

Cover image for Generate a PDF & upload to S3 using AWS Lambda & Puppeteer.
Dan Stanhope
Dan Stanhope

Posted on • Updated on

Generate a PDF & upload to S3 using AWS Lambda & Puppeteer.

I've put together a working project that'll take all of your posts, create a .pdf and upload it to S3. Ba-boom.

Head over to GitHub to grab the code.

First, a little bit about the project. It's run using sam cli and CloudFormation(make sure you've got your sam/aws cli installed and configured properly. Here's how to do this).

Modules and custom code will be compiled into a Lambda Layer. This is where all the requisite node_modules will live, as well as some custom code and our html templates. Cool thing about layers is once you've built it you can share it amongst your other functions. We're also going to be including another layer(chrome-aws-lambda), which will be used to run puppeteer inside the Lambda environment.

Here's what the .pdf looks like with my data(I know, not great. It's a .pdf and I'm no designer. Let's move on).

Image description

Show me the code!

I briefly mentioned layers before, it's a pretty cool feature of AWS Lambda. If you've got a bunch of functions running and you want to share node_modules or custom code(i.e. adapters, helper functions, templates etc.) you can create 1 or more layers and attach them to your functions.

When importing anything other than a node_module you need to reference a different path(/opt/). Here you can see the modules being included vs. the custom code.

Image description

The function is quite simple, we start off by ingesting our html template from our layer and initializing a few variables(*note: change the bucket name to something other than my name). Next, we pull down some posts and compile our template.

Image description

Then we initialize puppeteer and pass in our template string. We'll create a buffer and give this to our S3 upload method.

Image description

Guys. That's it. It's done. We made a .pdf.

How do I run this?

Once you've cloned the repo, head into /layers/shared/nodejs and run yarn. This will install all the packages we need. You can add this to a build step at some point, too. When creating a layer, it's important to note that you need to include the function's runtime as part of the folder structure in order for lambda to recognize it(in this case nodejs).

Jump back into the root of the project and run:

sam local invoke PuppeteerFunction --no-event

If you've configured everything properly, you should have a nice .pdf created & waiting for you in S3.

One thing to note, there is some strange bug with the aws chrome package and it's not working with Nodejs14. That's why all the runtimes are set to Nodejs12. If you can get it working with a more up-to-date runtime, please let me know and I'll update the repo.

Thanks so much for reading! Hope this helps someone.

Top comments (2)

renaud profile image

I had a lot of troubles with html to pdf in dozens of projects myself. I ended up creating a micro-saas for that purpose :

danstanhope profile image
Dan Stanhope

Thats really cool! Well done.