LoginSignup
2

More than 3 years have passed since last update.

PuppeteerをAWS Lambda上で動かすためのテンプレートを作った

Posted at

何がしたいか

  • PuppeteerをAWS Lambdaで動かしたい
  • Lambda Layerを使ったり、
  • Cloudformationを使って
  • 再現性のある状態にしたい、かつ変更時は最小限に抑えたい
  • というのを今後も使い回せるようにテンプレート用意したい

ということで出来たのがこちら↓
https://github.com/nsk917/aws-lambda-puppeteer-template

動作確認環境

$ node -v
v8.10.0

$ aws --version
aws-cli/1.16.106 Python/3.6.7 Linux/4.4.0-17134-Microsoft botocore/1.12.96

Windows Subsystem on Linuxにて実行

とりあえず動かしたい

コピペで動くはず

git clone https://github.com/nsk917/aws-lambda-puppeteer-template.git
cd aws-lambda-puppeteer-template

RAND=$(openssl rand -hex 10)
aws s3 mb s3://aws-lambda-layer-$RAND --region ap-northeast-1

npm run zip-layer

aws cloudformation package \
 --template-file template.yaml \
 --s3-bucket aws-lambda-layer-$RAND \
 --output-template-file deploy.yaml

aws cloudformation deploy \
 --stack-name aws-lambda-puppeteer \
 --template-file deploy.yaml \
 --capabilities CAPABILITY_IAM \
 --no-fail-on-empty-changeset

としたあと、マネジメントコンソールから該当のLambda Functionにテストイベントを作成して、テストを行ってみると、以下のような成功結果が得られるはず
"GitHub - nsk917/aws-lambda-puppeteer-template: AWS Lambdaでpuppeteerを動かすためのテンプレート"

Puppeteerやchrome-aws-lambdaについては割愛

ポイント

  • RAND=$(openssl rand -hex 10)を使う必要はまったくなくて、コピペで動かすために用意しただけ
  • Lambda Layerで使用するモジュールはpackage.jsondependenciesのみ使うようにする
    • Lambda Layer用に別のディレクトリ用意したりするのは面倒なので、シェルスクリプトにした
    • 他にいい方法あれば知りたい
  • IAM RoleをCloudformationで作成するので、deployするときに--capabilities CAPABILITY_IAMをつける
  • --no-fail-on-empty-changesetについてはこちらの記事を参考に
  • S3へファイルアップロードをするということを手動で行わなくても良い

少し解説

蛇足感

index.js

ほぼchrome-aws-lambdaのサンプルのまま。URLだけ変更

template.yaml

MemorySize: 512 # 1600 is recommended.と書いているのは、chrome-aws-lambdaのドキュメントでは1600MBを推奨しているため

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31

Resources:
  LambdaLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: aws-lambda-puppeteer
      CompatibleRuntimes:
        - nodejs8.10
      ContentUri: lambda-layer.zip

  LambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      Runtime: nodejs8.10
      CodeUri: ./src/
      Handler: index.handler
      Layers:
        - !Ref LambdaLayer
      MemorySize: 512 # 1600 is recommended.
      Timeout: 120
      Role: !GetAtt LambdaExecutionRole.Arn

  #以下略

zip.sh

npm run zip-layerで実行されるスクリプト
開発で使っているnode_modulesをそのまま使うのではなく、一旦別ディレクトリでnpm installしたものをZIP化する
その際--productionを指定すると、dependenciesのモジュールのみインストールされるようになる

#!/bin/bash -x

DIR=$(cd $(dirname $0); pwd)
mkdir -p $DIR/nodejs
rm -rf $DIR/lambda-layer.zip $DIR/nodejs/node_modules
cp $DIR/package*.json $DIR/nodejs/

npm isntall --production --prefix nodejs
rm -rf $DIR/nodejs/package*.json

zip -9 -r lambda-layer.zip nodejs

ローカルでのテスト

テストには docker-lambda を使う
Linux のほうは動作するかどうか確かめたことはない

# WSL (Windows Subsystem for Linux)
docker run --rm --mount type=bind,src=C:/<path>/aws-lambda-puppeteer-template,dst=/var/task lambci/lambda:nodejs8.10 index.handler

# Linux
docker run --rm --mount type=bind,src=$(pwd),dst=/var/task lambci/lambda:nodejs8.10 index.handler

参考URLなど

AWS Serverless Application Model (SAM)
https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md

chrome-aws-lambda
https://github.com/alixaxel/chrome-aws-lambda

chrome-aws-lambdaを使う理由
https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-puppeteer-on-aws-lambda

AWS Lambda ( Typescript ) の Lambda Layers 活用、開発、デプロイ考察
https://dev.classmethod.jp/server-side/serverless/aws-lambda-typescript-lambda-layers-deploy/

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2