汎用のLambda FunctionをデプロイするLambda Functionを作りました。
汎用のLambda Function?
そもそも、汎用のLambda Functionって何?という話ですが、自分はLambda Functionを作っていて常々疑問に思うことがありました。
例えばサムネイルを生成するLambda Functionで
var params = {
srcData: data.Body,
format: extension,
width: 256,
height: 256
};
im.resize(params, callback);
のようにリサイズするサイズをマジックナンバー指定しますが、別のサイズでサムネイルを生成したいときはプロジェクトをコピーしてマジックナンバーを書き換えて別コードとして管理する必要があります。
それが凄い嫌だったので自分はnode-configを使って、設定ファイルを使ってマジックナンバーを置き換えるようにしています。
{
"width": 256,
"height": 256
}
var params = {
srcData: data.Body,
format: extension,
width: config.get('width'),
height: config.get('height')
};
im.resize(params, callback);
こうすることでコードの管理自体は一元化しつつ。デプロイ時に設定ファイルを書き換えることで複数のサイズのリサイズに対応したLambda Functionを作成することができます。
プロジェクト独自のLambda Functionならこういったことをする必要はありませんが、よくあるLambda Functionなら汎用的に扱えるようにすると車輪の再発明をする必要がなくなるので楽をできます。
(環境変数とかを注入できればこんなことしなくても良かったんですけどね・・・)
モチベーション
とはいえ、汎用のLambda Functionにもデメリットがあります。
デプロイフローが
- プロジェクトを取得
- 設定ファイルを生成
- 設定ファイルを含んでZIP化
- 作成したZIPファイルをアップロード
という手順に固定化されてしまうため、このフローに載せれてないエコシステムに乗せることができなくなります。
ついでに、S3以外のところ(GitHub releaseとか)に配置したファイルとかを直接アップロードしたいなというモチベーションでlambda-deploy-custom-resource-functionを作りました。
蛇足ですが1箇所にデプロイするだけならTravisCIがデプロイの前処理を挟んだりしやすいのでオススメです。
使い方
事前にlambda-deploy-custom-resource-function
をデプロイするか、AWS::Lambda::Function
で依存系として定義します。
"LambdaExampleFunction": {
"Type": "AWS::CloudFormation::CustomResource",
"Version" : "1.0",
"Properties" : {
"ServiceToken": "[lambda-deploy-custom-resource-function ARN]",
"URL": "[Your Lambda function URL]",
"FunctionName": "example-function",
"Handler": "src/index.handler",
"Role": { "Fn::GetAtt": ["LambdaExampleExecuteRole", "Arn"] },
"Runtime": "nodejs",
"Description": "Example function.",
"MemorySize": 128,
"Publish": true,
"Timeout": 3,
"Config": {
"key1": 1,
"key2": "str",
"key3": [1, 2, 3]
}
}
}
}
基本的にはAWS::Lambda::Function
と同じ形ですが、独自のプロパティとしてURL
に汎用のLambda FunctionのZIPのURLを、Config
に汎用のLambda Functionに設定する値を埋め込みます。
まとめ
これでCloudFormationを使えばコードの一元管理をしつつ、設定を変えた複数のLambda Functionをデプロイすることができるようになりました。
これで汎用のLambda Functionの作り方から、テスト、デプロイまで一通り見えたなという感じです。
そのあたりの話はLambdaのAdvent Calendar 2015で書こうかなとか思います。
関係ないですが、AWS LambdaでのCustomResourceの作り方を久しぶりに調べてみたらCloudFormationに直接コードを埋め込めるようになっていて笑えました。
やりたい放題できるのでAPI GatewayのCloudFormationのサポートまだかなとか考えてる間に自作した方が話早そうですね。