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からアクセスできないじゃん!! ということでお蔵入りになってしまったので成仏のために記事にした。