きっかけ
数ヶ月前に尊敬するパイセンから Python をお勧めされたので、最近 Python であれこれ作っています。
最初に以下のような動画トランスコードの流れを作りました。 Python と boto は楽でいいですね。一言でいうと「Python は私をクリアに保ってくれる...」という感じです。
AWS Pipeline で時間を見てジョブを実行していたのですが、バケットにファイルを投入するタイミングとエンコードの終了のタイミングとジョブ開始時間の調整が難しくて、気がつくとたまにジョブがこけてることが...
この際なので EC2 上で動かしていた Python のスクリプトをさっくりと AWS Lambda に置き換えようと思いました。上の図の EC2 と Data Pipeline を Lambda に切り替えるイメージです。
しかし結構土俵が違うというか、いろんなことが一筋縄では行かなかったのでメモしておこうと思います。
EC2 上との違い
- Python2.6 の site-package は入ってるけど Python2.7 の site-package がない(2.6が入っていることだけでもありがたいと思うべきか...)
- aws cli は入ってない
- 外部コマンドとして呼び出されたスクリプトには "lambda_exec_role" で定義したロールの権限がつかない
- パスが通ってないところがある
どう対応したか
- 仕方ないので Python2.6 ベースに書き直した (例: subprocess.check_output とか使ってしまっていたので subprocess.Popen に修正など...)
- 一部手抜きで aws cli 呼び出してごまかしていたところを直した(ぉぃ)
- 必要な権限だけつけた user の credentials を export コマンドでセットしてからスクリプトを実行(結構無理矢理感があるので真似しない方がいいかもしれません...)
- なるべく絶対パスで記述
exports.handler = function(event, context) {
var exec = require('child_process').exec;
var cmd = "export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXX;export AWS_SECRET_ACCESS_KEY=XXXX;unset AWS_SESSION_TOKEN;curl -s http://xxxxxx.s3.amazonaws.com/sns_notification_bl.py > /tmp/sns_notification_bl.py;chmod 755 /tmp/sns_notification_bl.py;python26 /tmp/sns_notification_bl.py"
var child = exec(cmd, function(error, stdout, stderr) {
if (!error) {
console.log('standard out: ' + stdout);
console.log('standard error: ' + stderr);
context.done();
} else {
console.log("error code: " + error.code + ", err: " + error);
context.done(error,'lambda');
}
});
};
ここまでやるなら JavaScript/Node.js で書けばと言われそうですが...
まとめ
紆余曲折ありましたが、ファイルをバケットに入れてから通知までするするとワンストップで行けるようになりました。そしてなんとなく Lambda が可愛く思えて来ました。とある巨匠の「こう見えても、僕、テクノロジー的には○リコンなんですよ」という言葉の意味が見えてきた気がしました。
免責
こちらは個人の意見で、所属する企業や団体は関係ありません。
パイセンや巨匠はフィクションです。