RustでAWS lambda functionの関数を作れなかった話

最近、Rustを勉強しているので、勉強がてら簡単なLambda Functionを作ったら、うまく動作させることが出来ずに終わった話
※ 惜しいところまではいったと思うので、参考になればと思い、記録に残す

ローカル環境

  • Ubuntu 17.10
  • Apex version 1.0.0-rc2
  • rustc 1.23.0 (766bd11c8 2018-01-01)

Apex

github.com

AWS Lambda function を簡単に作れて、コマンドラインでデプロイ出来るアプリケーション

2018/02/18現在以下の言語サポートをしている

作ったもの

github.com

好きなキーワードを設定しておけば、Twitterで検索して、自動でいいねをしてくれるツール
機能自体は動きます(mainのrust_apex::run:を外して、環境変数を設定すればOK)

デプロイまででハマった点

ロスコンパイル版(rust musl)

Apexでrustを利用するためには、クロスコンパイルしなければいけない(デプロイ時に以下のようなエラーが発生)

$ apex deploy lambda_auto_likes
   ⨯ Error: function lambda_auto_likes: build hook:    Compiling lambda_auto_likes v0.1.0 (file:///home/snicmakino/projects/apex/tools/functions/lambda_auto_likes)
error[E0463]: can't find crate for `std`
  |
  = note: the `x86_64-unknown-linux-musl` target may not be installed

error: aborting due to previous error

error: Could not compile `lambda_auto_likes`.

To learn more, run the command again with --verbose.

以下のコマンドで、Apexで利用するためのクロスコンパイル版をインストールできます
$ rustup target add x86_64-unknown-linux-musl

OpenSSLをソースからインストール

Apexでrustを利用する際に、rust-opensslが依存関係にあるが
これをクロスコンパイル版で利用するためには、OenSSLをソースからインストールする必要がある
やらずにデプロイした時のエラーは以下の通り

$ apex deploy lambda_auto_likes
・・・
   Compiling openssl-sys v0.9.24
error: failed to run custom build command for `openssl-sys v0.9.24`
process didn't exit successfully: `/home/snicmakino/projects/apex/lambda_auto_likes/functions/lambda_auto_likes/target/release/build/openssl-sys-5ee2bfe045b42a7a/build-script-build` (exit code: 101)
--- stdout
cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_LIB_DIR
cargo:rerun-if-env-changed=OPENSSL_LIB_DIR
cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_INCLUDE_DIR
cargo:rerun-if-env-changed=OPENSSL_INCLUDE_DIR
cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_DIR
cargo:rerun-if-env-changed=OPENSSL_DIR
run pkg_config fail: "Cross compilation detected. Use PKG_CONFIG_ALLOW_CROSS=1 to override"

--- stderr
thread 'main' panicked at '

Could not find directory of OpenSSL installation, and this `-sys` crate cannot
proceed without this knowledge. If OpenSSL is installed and this crate had
trouble finding it,  you can set the `OPENSSL_DIR` environment variable for the
compilation process.

If you're in a situation where you think the directory *should* be found
automatically, please open a bug at https://github.com/sfackler/rust-openssl
and include information about your system as well as this message.

    $HOST = x86_64-unknown-linux-gnu
    $TARGET = x86_64-unknown-linux-musl
    openssl-sys = 0.9.24

', /home/snicmakino/.cargo/registry/src/github.com-1ecc6299db9ec823/openssl-sys-0.9.24/build.rs:210:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.

warning: build failed, waiting for other jobs to finish...
error: build failed

以下の手順でソースからOpenSSLをインストールを行う

curl -O https://www.openssl.org/source/openssl-1.1.0g.tar.gz
tar xf openssl-1.1.0g.tar.gz
cd openssl-1.1.0g
./Configure --prefix=/usr/local/openssl --openssldir=/usr/local/openssl linux-x86_64 -fPIC
make -j$(nproc)
sudo make install

Apexを利用する際に、環境変数でソース版OpenSSLの利用を指定する
export OPENSSL_DIR=/usr/local/openssl

やったぜ!!

デプロイ出来るようになった

$ apex deploy
   • creating function         env= function=lambda_auto_likes
   • created alias current     env= function=lambda_auto_likes version=1
   • function created          env= function=lambda_auto_likes name=lambda_auto_likes_lambda_auto_likes version=1

動作しない問題(未解決)

Lambdaのログを見たら、どうやら動いていない模様
手元でクロスコンパイルして動かしてみると、以下のようなエラーが発生

$ cargo run --target=x86_64-unknown-linux-musl --release
   Compiling lambda_auto_likes v0.1.0 (file:///home/snicmakino/projects/apex/tools/functions/lambda_auto_likes)
    Finished release [optimized] target(s) in 10.72 secs
     Running `target/x86_64-unknown-linux-musl/release/lambda_auto_likes`
error: could not execute process `target/x86_64-unknown-linux-musl/release/lambda_auto_likes` (never executed)

作られたバイナリを実行しようとしてもうまく動かない

$ ./target/x86_64-unknown-linux-musl/release/lambda_auto_likes
bash: ./target/x86_64-unknown-linux-musl/release/lambda_auto_likes: そのようなファイルやディレクトリはありません

まとめ

自分が作ったプログラムはクロスコンパイルすると動作させれないし、この現象は今の実力だと原因が全くわからないので解決できていないが、RustでApexデプロイをする手順は、他の人もハマる可能性があるので、とりあえず残す
ここまできて一旦終わらせるのは正直悔しいけど、このツール自体はPythonで書き直す予定

苦し紛れのツイートはこちら

社内LT会を開催した

社内でLT会を開催した。
テーマは自由、制限時間は5分間で参加したい人が参加する。
業界の慣例に習って、ピザ、寿司、酒を準備。
14人発表して、全体の参加者は30人強。結構盛り上がったし、成功したなと感じるので振り返る。

LT会の狙い

アウトプット機会の創出と文化の醸成

メンバーがあるトピックについて不特定多数に向けて話したり、見知ったこと共有する文化がそこまで無いため、そういう場を作ることによって、 今後のアウトプットのハードルを下げることと、アウトプットする文化につなげたかった。

良かった点

テーマ設定を自由にした

テーマを自由に設定したので、発表者のハードルが下がって、結構な人数が発表してくれた。
コンテンツがバラバラだったので、見る側も飽きないで聞けたし、かなり盛り上がった。

自分が好きなことについて話す人が多かったので、発表していない人からも、次回は自分も話したいと言う声が多かった。

タイムテーブル

5人発表 → 休憩 → 5人発表 → 休憩 → 4人発表
という感じでやったが、丁度良かった。

1人5分なので、発表の内容に関してだれることは無い。

今気づいたけど、30分くらい発表が続いて、10分休憩するっていうリズムになっていて、聴衆がポモドーロ的な集中が自然に出来ていたのではないか。

イマイチだった点

学習のきっかけにはならない(気がする)

これは、テーマを自由に設定した副作用な気もするけどエンジニアとして、モチベーションが上がるとかっていうのはあまり無かった。
(テーマをTechに絞っても、LTくらいのボリュームだとそこまでの内容にはならない可能性もある)

ただ、学習になることを目的とはしていないので、仕方がないし、勉強した内容や、技術的な成果をアウトプットするのであれば、LTという形式は適していないのかもしれない。

自分のLT内容について

リバプロの話をした。
5分だったので「リバプロ入れて動的コンテンツと静的リソースの責任をバラバラにしないとね!!」
的な話をしたが、対象のレベルを低く設定しすぎた感がある。

参加者は新人も多かったので、知らない人もいたかもしれないけど、 もっと技術的に深い部分の話(リバプロならCDNで使われている技術や事例の話とか)をしたほうが、自分の学習にもつながるし、聞いてる人もモチベーション出たのではないだろうか。

自分ならちょっと勉強すれば理解できる事を知りたいとは思わないし、しっかり勉強した人が、そこで得た知識をある程度噛み砕いて話してくれることのほうが価値がある。
こういう発表は基本的に、参加者が知らない話ほど価値があることに気づけた。

まとめ

  • フリーテーマであれば、アウトプットに対するハードルはかなり下げれる
  • コミュニケーションのトリガーとしては、非常に良い
  • 発表5人(30分) → 休憩(10分) の流れが聴衆にポモドーロ的な集中力を生んでいた可能性がある
  • 技術的な内容をアウトプットする場としては少し物足りないので、技術者のアウトプットに関してはLT以外のものも検討したい
  • 発表内容は、聞いている人が知らない話をすることが価値となる
  • 運営は大変

クソコードを書く

プログラミングの学習

IT業界に入り、システム開発を生業とし、技術力を向上するために学習をする。
自分にとってプログラミングは技術の学習の中でも、力を入れて行ってきたものの一つだ。
アルゴリズムオブジェクト指向テスト駆動開発の学習も自分の書くプログラムをシンプルで、構造的で、柔軟なものにするためのものだ。

学習の中で、こんなコードは筋が悪い糞コードで、こんなコードは美しいコードだという基準が生まれる。おそらく、プログラミングを自分なりに学習してきたエンジニアであれば皆持っているものだろう。
そのプログラムに対する基準はとても素敵なもので、自分のエンジニアとしてのプライドであり、自信であり、実績である。
しかしそれが、思いついたものを思いついたままに書くという行為を妨げるものになっていないだろうか。

クソコードを書く

もちろん、業務の成果物としては出来る限りクソコードは書かないほうが良い。
1ヶ月後の自分に迷惑がかかるし、周りのメンバーにも影響するかもしれない。

プライベートな時間を使って何かを作る時、使い捨ての軽く動かしてみるコードを書く時、美しいコードはこうあるべきという基準が手を止める。 クソコードを書く前に、もっと良い実装があるはずと頭の中の引き出しを開け、時間をかけて構成を考える。

もちろん、自分が未熟だから、美しくない実装を思いついてしまうのかもしれない。
だからといって、思いついたコードを書くこともせずに、頭を悩ませるのはもったいない。

クソコードを書くべきだ。

ハッカーと画家」という有名なエッセイ集の一説には以下のようにある。

例えば、大学で私は、コンピュータに手を触れる前に 紙の上でプログラムを完全に理解しなければならないと教わった。 でも私はそういうふうにはプログラムできなかった。 私が好んだやりかたは、紙の前ではなく、コンピュータの前に座って プログラミングすることだった。もっと悪いことに、 辛抱強く全てのプログラムを書き上げて正しいことを確認するなんてことは せずに、私はめちゃくちゃなコードをおっぴろげて、 それを次第に形にしてゆくのだった。 私が教わったのは、デバッグとは書き間違いや見逃しをつかまえる 最終段階の工程だということだったが、 実際に私がやっていたのは、プログラミングそのものがデバッグという具合だった。

随分長い間、私はそのことを後ろめたく思っていたものだ。 ちょうど、小学校で教わった鉛筆の持ち方と違う持ち方をしていることを 後ろめたく思っていたのと同じように。 他のものを創る人々、画家や建築家がどうやっているかを見れば、 私は自分のやっていることにちゃんと名前がついていると気づいていただろう。 スケッチだ。 私が言えるのは、大学で教わったプログラミングのやりかたは全部間違っていた ということだ。 作家や画家や建築家が、創りながら作品を理解してゆくのと同じで、 プログラマはプログラムを書きながら理解してゆくべきなんだ。

クソコードを書くことを恐れてはならない。書きながら、または書いたあとに洗練させていけば良い。
クソコードを書く心はエンジニアにとって大切なものだと思う。

https://www.amazon.co.jp/exec/obidos/ASIN/4274065979/nakazye-22/www.amazon.co.jp

言語化力とアウトプット

自分の思考を言語化、一般化する能力が非常に重要だと感じた話。


先日、会社でプレゼンをする機会があった。

そのプレゼンの内容は、普段の自分の思考や、行動指針を伝えるような内容であったのだけれども、資料に思考を落とし込み、全体の構成を整えるのにかなり難儀させられた。

普段、同僚と似たようなテーマで会話する時には、言葉に詰まったり、全く伝えることが出来ないなんてことは殆どなく、割とスラスラ話が出来るので、これだけ苦労するのは正直予想外だった。

反省する中で、まつもとりーさんのエントリで、知識の一般化について言及されていたことを思い出した。

hb.matsumoto-r.jp

このエントリを読んだ当時は「確かにそれって大事だよね〜」と、自分が出来ていないことを分かっていながら、どこかでまだ自分には必要ないだとか思っていたのかもしれない。


今回の件で、自分には思考の言語化力と、アウトプットの量がまだまだ足りていないなと感じたので、今後はそれらを強化するべく、思考をなるべく言語化してアウトプットすることを心がけようと思う。

どれだけ良い考えを持っていても、それを伝えることが出来なければ、それ以上の広がりは生まれない。アウトプットすることによって、洗練され、拡散され、新しい考えへ連なっていく。


幸い、世の中は情報が多く、アウトプットが得意な方々が書いた文章やスライドには比較的楽にアクセスが出来る。 まつもとりーさんが言うように、Web+DB PRESSSoftware Designのような技術雑誌も非常に参考になるし、結城浩さんの書く文章は非常に分かりやすい上にとても面白い。 そういった人達のアウトプットを見て、自分のアウトプットの質の向上につなげていきたい。