Web制作・開発会社 プレスマンのスタッフブログ

PRESSMAN*Tech

AWS Lambda上でcanvasを使いたい【後編】

AWS Lambda上でcanvasを使いたい【前編】の続きです。

色々と面倒なので全てrootユーザーで作業しています。ホームディレクトリは/rootです。適宜読み替えて下さい。

前回、AmazonLinux上のnode.jsでcanvasを動かしてみました。
今回はこれをAWS Lambda上で動かしてみます。まずは、Lambda上でのモジュールの使い方です。

モジュールをLambdaで使う場合zipファイルにまとめてからデプロイします。
その際に注意する点としてはzipファイルのルート直下に置かないと上手く動きません。

例えば下記の様な構造だったとします。

これをディレクトリごと圧縮してデプロイしても動きません。下記の様にtestディレクトリの中身だけをzipファイルにします。

一つ簡単なサンプルを作ってみます。

これでunderscoreのモジュールがインストールされました。このモジュールはPure JSなのでこのままlambda上で動くはずです。
そして、Lambda用の関数を作ります。

index.js
[javascript]
exports.handler = function(event, context) {
var _ = require("underscore");
var a = [];
console.log(_.isArray(a)); //true
};
[/javascript]

underscore.jsで変数が配列かどうかを調べるだけの簡単なものです。しかも配列を作って配列かどうか調べるアホみたいな関数ですw
これをAWSコンソールでLambda関数を作って、コピペして実行してもモジュールが読み込めないのでエラーになります。

として、zipファイルにしてアップロードします。ファイルはAWSのコンソールから直接アップロードしてもいいのですが、EC2サーバー上から上げるときは面倒なのでAWS CLIを使って一度S3にあげるか、直接LambdaのAPIを使ってデプロイしてしまいます。サンプルコマンドのAWS CLIのバージョンは1.7.36です。lambdaのコマンドはバージョンによって結構変わっています。

testというprofileでAWSのキーとリージョンを設定してあります。このユーザーにはLambdaとS3の全権限を与えてあります。CLIのユーザー設定方法はこちらを参照。

S3に上げる場合。S3に上げた場合はAWSのコンソールから"Upload a .ZIP from S3"を選択してURLを貼り付けて下さい。S3のバケットがあるリージョンとLambdaを実行しているリージョンが違うと上手くいきません。

直接デプロイする場合。underscoreという名前で既に関数は作ってある前提です。

その後実行しますが、これはAWSのコンソールからした方が楽だし、わかりやすいですがコマンドだと下記の様になります。result.txtは出力が書き込まれるファイルです。

実行するとファイルの中身が true になっているはずです。

これでcanvasをLambdaで動かす準備が整いました。
まずは、Lambdaで動くかどうかわからないですが、前編で作ったサンプルスクリプトをローカルファイルでなく、S3に出力するよう変更してみます。

前編でのexampleディレクトリに移動して下記のファイルを作ります。その後zipにしてcanvasという名のlambdaを作ってアップロード、実行してみます。(AWSコンソールからでも、CLIでもどちらでもいいですが、関数を作るのはコンソール、アップロードはコマンドでやるのが楽なのでそうしています。)

index.js
[javascript]
exports.handler = function(event, context) {
var AWS = require('aws-sdk');
var s3 = new AWS.S3({apiVersion: '2006-03-01'});
var Canvas = require('canvas')
, Image = Canvas.Image
, canvas = new Canvas(200, 200)
, ctx = canvas.getContext('2d');

ctx.font = '30px Impact';
ctx.rotate(.1);
ctx.fillText("Awesome!", 50, 100);

var te = ctx.measureText('Awesome!');
ctx.strokeStyle = 'rgba(0,0,0,0.5)';
ctx.beginPath();
ctx.lineTo(50, 102);
ctx.lineTo(50 + te.width, 102);
ctx.stroke();

canvas.toBuffer(function (err, buf) {
if (err) throw err;
var params = {
Bucket: 'bucketName',
Key: 'test.png',
Body: buf ,
ContentType: 'image/png',
ACL: 'public-read'

};
s3.putObject(params, function(err, data) {
if (err) {
context.done(null, err);
} else {
context.done(null, "done");
}
});
});
};
[/javascript]

さて、実行結果ですが、これで動くならこんな記事を書いていません。当然エラーがでます。

なので、動くようにしてみます。
まずインストールに使用するライブラリ等をコピーしてきてこれらのみを使ってモジュールをビルド出来るようにします。

これで準備完了です。cairoのパッケージは削除して下さい。
このあとcanvasをインストールして、lambdaにアップロードします。

これで実行するとS3上にファイルが出来ているはずです。
タイムアウトになってしまうときはlambdaのタイムアウト時間を10秒程度にしてみて下さい。
nchartなんかのモジュールを使うとlambda上でcanvasを使ってグラフを書けたりします。