1. やりたいこと
Elixirを利用して、kinesis, s3を操作したいです。
とはいえ、テスト環境はローカルで行いたいので、s3rverだったり、そのdocker版のdocker-s3rverを利用してみることにしました。
2. 利用してみたリポジトリ
3. 実施手順
3-0. s3rverをローカルホストで起動する
npm install s3rver
export PATH=$PATH:node_modules/.bin
mkdir -p tmp
s3rver -d tmp
上記のコマンドを実行することで、localhost:4568
で、s3rverが立ち上がります。
3-1. mix.exsに依存を追加して、deps.getを実行
defp deps do
[
{:mix_test_watch, "~> 0.2", only: [:dev, :test]},
{:ex_aws, "~> 0.4.10"},
{:poison, "~> 1.2"},
{:httpoison, "~> 0.7"}
]
end
mix deps.get
3-2. config.exsに、aws、s3の設定を記載する
config :my_app_conf, :ex_aws,
s3: [
scheme: "http://",
region: "us-east-0",
access_key_id: "xxxxxxxxxxxxxxxxxxxxx",
secret_access_key: "xxxxxxxxxxxxxxxxxxxxx",
host: %{"us-east-0" => "localhost:4568"}
],
debug_requests: true
上記のように、s3rverを利用する場合は、access_key_id
やsecret_access_key
にはダミーの値を設定して問題ないです。
また、少しややこしかったのですが、下記を見ると、host
はMap
形式で設定してあげる必要があるようでした。
s3rverへのリクエスト実行時に、どのようなパラメータが渡っていくのかをconsole出力したい場合は、debug_requests
をtrue
に設定する必要があるようでした。
3-3. mix testを実行することで、接続テストを実施
以下のような、実行ファイルを用意しました。
defmodule MyModule do
@moduledoc"""
"""
require Logger
use ExAws.S3.Client, otp_app: :my_app_conf
@doc"""
"""
def create_a_bucket_and_put_data do
put_bucket("fuga", "us-east-0")
put_object("fuga", "name", "aaa")
end
end
3-4. 実行したけれども動かず。。
logには、HTTP ERROR :nxdomain
のようなエラーが出ました。
put_bucket
からして失敗しているようでした。
4. 今回の暫定対応
4-1. 原因について
ちょっとソースを眺めてみると、endpointの解決に失敗しているようでした。
defp host_and_bucket(host, ""), do: host
defp host_and_bucket(host, bucket) do
case bucket |> String.contains?(".") do
true -> [host, "/", bucket]
false -> [bucket, ".", host]
end
end
本物のs3であれば、問題なく動くのですが、s3rverの場合は、バケットの名前が、ドメインの先頭ではなく、relative_pathとして、ドメインの後ろに付くようです。
4-2. 暫定対応
- テスト実施時にホスト名を変更する
- ex_awsを改造しちゃう
2.
のやりかたについてはテストのためにライブラリをいじる、という本末転倒気味な形になりますので却下としました。
でも一応こちらのように実装はしてみました。
ということで、1.
で試してみました。
4-3. ホスト名の変更
テストコマンドを叩くターミナルで、以下のように名称変更しました。
export bucket_name=テスト用のバケット名
sudo hostname ${bucket_name}.localhost
4-4. mix testの実行
4-3.
と同様のターミナルにてmix test
を実行
mix deps.get
を気を取り直して実施して、再度実行したところ、うまいこと、bucket作成とデータを作成したbucketに登録することができました^^
5. 所感
- ex_aws使いやすいですね^^ kinesis連携とかは、elixirで記述したほうがscalaとかよりもすっきりかけるかも。
- s3rverの思わぬ落とし穴、というか仕様でした。。しかし止むを得ずか。。動的にホスト名変更できるサービスを間にかましてまでテストもしたくないし。。ちょっと微妙かも。オールインワンなサービスが欲しいところです。
- bucket作成のテストはs3rverを使うと、現状だと難しいです。
- riak-s2とかにも時間があったら触ってみよう。
6. おまけ
下記のようにinstance_role
を見て、認証してくれるようです。
実運用時には、keyを配布する必要もなさそうなので、セキュリティ設計をしっかりと組むこともできそうですね^^
config :ex_aws,
access_key_id: [{:system, "AWS_ACCESS_KEY_ID"}, :instance_role],
secret_access_key: [{:system, "AWS_SECRET_ACCESS_KEY"}, :instance_role]
本日は以上となります。