LoginSignup
18
18

More than 5 years have passed since last update.

ex_awsを利用して、S3の擬似サービス、s3rverにアクセスしてみよう

Last updated at Posted at 2016-03-16

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を実行

mix.exs
  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/config.exs
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_idsecret_access_keyにはダミーの値を設定して問題ないです。

また、少しややこしかったのですが、下記を見ると、hostMap形式で設定してあげる必要があるようでした。

s3rverへのリクエスト実行時に、どのようなパラメータが渡っていくのかをconsole出力したい場合は、debug_requeststrueに設定する必要があるようでした。

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の解決に失敗しているようでした。

lib/ex_aws/s3/request.ex
  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. 暫定対応

  1. テスト実施時にホスト名を変更する
  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/config.exs
config :ex_aws,
  access_key_id: [{:system, "AWS_ACCESS_KEY_ID"}, :instance_role],
  secret_access_key: [{:system, "AWS_SECRET_ACCESS_KEY"}, :instance_role]

本日は以上となります。

18
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
18