TreasureDataのtdコマンドをAWS Lambdaで動かす


TreasureDataはtd コマンドでいろいろな作業ができて便利。AWSのLambdaから動かせればもっと便利かな?と思ったのでトライしてみる。

Lambdaの中身

Lambda 実行環境と利用できるライブラリによれば、Lambdaは amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2 というAMIをベースに動いている。
AWS Lambdaをいろいろ暴くでも書かれているように、ファイルが展開される /var/task などはRead Onlyで、書き込みできるのは /tmp 、のようになっている。

tdを動かしたい...

tdコマンドはRubyで書かれているのだが、現時点でLambdaはRubyをサポートしていない。
なので /var/task 内にRubyの実行環境を含めて構築する必要がある。

が、ポータブルなRubyとしてよく例のでてくるTraveling Rubyは2.2.2と古い。それに、Ruby力の低い僕にはmsgpackをビルドすることができなかった…

行き詰まりつつあったが、TreasureDataがオフィシャルに配布しているパッケージをよく見てみたところ、Ruby含めて全て/opt/td-agent に同梱されてるじゃん! これでいいじゃん!

Dockerfile

Lambda用のzipを作るにはDockerを使うのが便利です。
配布されているスクリプトはLinux上でsudo出来ること前提につくられているので、Dockerfile用にばらしてあげる必要がある。

 FROM amazonlinux:2017.03

 RUN rpm --import https://packages.treasuredata.com/GPG-KEY-td-agent
 RUN echo $'[treasuredata]\n\
 name=TreasureData\n\
 baseurl=http://packages.treasuredata.com/3/amazon/1/\$releasever/\$basearch\n\
 gpgcheck=1\n\
 gpgkey=https://packages.treasuredata.com/GPG-KEY-td-agent\n\
 ' > /etc/yum.repos.d/td.repo
 RUN yum update -y \
   && yum install -y td-agent

 RUN mkdir -p /var/task/opt \
   && cp -r /opt/td-agent /var/task/opt

こんなかんじ。
$ docker run --rm -v \pwd`/work:/work -it td-lambda:latest /bin/shのようにしてコンテナ内に入って$ cp -r /var/task/* /work/` とかやればtd-agent一式が手に入る。

PythonなりNodeなりのスクリプトから動かすことになるのだが、Rubyのライブラリのパスを /opt/...から/var/task に変える方法がようわからんかったので、下のような残念なラッパを書いた。

 set -ex

 export GEM_HOME="/var/task/opt/td-agent/embedded/lib/ruby/gems/2.4.0/"
 export GEM_PATH="/var/task/opt/td-agent/embedded/lib/ruby/gems/2.4.0/"
 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/var/task/opt/td-agent/embedded/lib

 exec ./opt/td-agent/embedded/bin/ruby \
   -I./opt/td-agent/embedded/lib/ruby/2.4.0/ \
   -I./opt/td-agent/embedded/lib/ruby/2.4.0/x86_64-linux \
   ./opt/td-agent/embedded/bin/td "$@"

とりあえずここまでで td db:list はできたっぽい。良かったね。

後日談

クライアントの案件にぶちこんで楽しようと思ったのだけど、よくよく考えると接続元IPにホワイトリスト制限があるからLambdaからアクセスできないじゃん!! ということでお蔵入りになってしまったので成仏のために記事にした。