- この記事は…
- Elixir で AWS を操作する選択肢
- ex_aws について
- チュートリアル(S3 バケット一覧を取得する)
— ゴール
— docker run
— mix new
— mix.exs からの mix deps.get
— config.exs
— iex を起動
— list_buckets を実行
— request! でリクエストを送信
— レスポンスがちょっとアレなので…
— 最後は Poison で JSON に… - 以上
この記事は…
qiita.com
参加者の少ない, 初老丸 Advent Calendar 2017 17 日目の記事です.
Elixir で AWS を操作する選択肢
- 公式パッケージは提供されていません(2017/12/17 時点)
- 以下のようなパッケージがオープンソースで提供されていました(2017/12/17 時点)
Package 名 | GitHub URL | GitHub Star | 備考 |
---|---|---|---|
ex_aws | https://github.com/ex-aws/ex_aws | 553 | |
aws | https://github.com/jkakar/aws-elixir | 165 | |
erlcloud | https://github.com/erlcloud/erlcloud | 523 | AWS APIs library for Erlang |
ざっくり検索したので, 他にもあれば教えて下さい.
ということで, Github Star 数基準に選定して ex_aws で試してみます.
ex_aws について
github.com
- 2.0 以降では, 各 AWS サービス毎にパッケージが提供されている(ex: S3 を操作する場合, ex_aws_s3 とか)
- 21 の AWS サービスをサポート(2017/12/17 時点)
- HTTP クライアントや JSON Codec を利用者側で選ぶことが出来る
- リトライ処理は Exponential Backoff アルゴリズムで実装している
- 自動的なりトライ処理とページネート(大量のリソースをよしなに分割して出力してくれるという理解)
チュートリアル(S3 バケット一覧を取得する)
ゴール
- ex_aws_s3 を利用して S3 のバケット一覧 JSON で取得する
docker run
オフィシャルリポジトリを利用します.
docker run --name elixir_aws_sample -t -i -v ${HOME}:/root -v $(pwd):/elixir elixir /bin/bash
mix new
mix new s3_ope
以下のように出力されます.
root@65afa8ba92a5:/elixir# mix new s3_ope * creating README.md * creating .gitignore * creating mix.exs * creating config * creating config/config.exs * creating lib * creating lib/aws_demo.ex * creating test * creating test/test_helper.exs * creating test/aws_demo_test.exs Your Mix project was created successfully. You can use "mix" to compile it, test it, and more: cd s3_ope mix test Run "mix help" for more commands.
mix.exs からの mix deps.get
以下のように依存パッケージを記載します.
defp deps do [ {:ex_aws, "~> 2.0"}, {:ex_aws_s3, "~> 2.0"}, {:hackney, "~> 1.9"}, {:sweet_xml, "~> 0.6"}, {:configparser_ex, "~> 2.0"} ] end
mix deps.get
を実行する.
mix deps.get
以下のように出力される.
root@65afa8ba92a5:/elixir/s3_ope # mix deps.get Resolving Hex dependencies... Dependency resolution completed: certifi 2.0.0 configparser_ex 2.0.1 ex_aws 2.0.2 ex_aws_s3 2.0.0 hackney 1.10.1 ... * Getting unicode_util_compat (Hex package) Checking package (https://repo.hex.pm/tarballs/unicode_util_compat-0.3.1.tar) Fetched package
config.exs
config.exs に Shared Credentials のプロファイル名(watashino-profile
)を以下のように設定します.
... config :ex_aws, debug_requests: false, access_key_id: [{:awscli, "watashino-profile", 30}, :instance_role], secret_access_key: [{:awscli, "watashino-profile", 30}, :instance_role], region: "ap-northeast-1" ...
これだけです. 簡単ですな.
iex を起動
iex -S mix
初回の場合, 以下のように出力されます.
root@65afa8ba92a5:/elixir/s3_ope# iex -S mix Erlang/OTP 20 [erts-9.1.3] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:10] [hipe] [kernel-poll:false] ===> Compiling mimerl ===> Compiling metrics = ... ==> ex_aws_s3 Compiling 7 files (.ex) Generated ex_aws_s3 app ==> s3_ope Compiling 1 file (.ex) Generated s3_ope app Interactive Elixir (1.5.2) - press Ctrl+C to exit (type h() ENTER for help)
list_buckets を実行
list_buckets/0
を実行すると以下のように出力されます.(出力はサンプルです)
iex(1)> ExAws.S3.list_buckets %ExAws.Operation.S3{body: "", bucket: "", headers: %{}, http_method: :get, params: [], parser: &ExAws.S3.Parsers.parse_all_my_buckets_result/1, path: "/", resource: "", service: :s3, stream_builder: nil}
この状態では, まだ S3 にリクエストは送信されていない状態です. list_buckets
を呼び出す為の準備をする感じでしょうか.
request! でリクエストを送信
ExAws の request!/2
をパイプライン演算子でつなげてあげることで, 初めて S3 にリクエストが送信されました.(出力はサンプルです)
iex(4)> ExAws.S3.list_buckets |> ExAws.request! %{body: %{buckets: [%{creation_date: "2017-12-17T05:30:42.000Z", name: "oreno-bucket-1"}, %{creation_date: "2017-12-17T05:30:43.000Z", name: "oreno-bucket-2"}, %{creation_date: "2017-12-17T05:30:44.000Z", name: "oreno-bucket-3"}, ... headers: [{"x-amz-id-2", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}, {"x-amz-request-id", "0F9E0E78F451D1C1"}, {"Date", "Sun, 17 Dec 2017 04:56:41 GMT"}, {"Content-Type", "application/xml"}, {"Transfer-Encoding", "chunked"}, {"Server", "AmazonS3"}], status_code: 200}
上記のようにレスポンスが Map で返ってきます.
レスポンスがちょっとアレなので…
Map の get/3
で必要な部分だけをよしなに取得して…(出力はサンプルです)
iex(8)> ExAws.S3.list_buckets |> ExAws.request! |> Map.get(:body) |> Map.get(:buckets) [%{creation_date: "2017-12-17T05:30:42.000Z", name: "oreno-bucket-1"}, %{creation_date: "2017-12-17T05:30:43.000Z", name: "oreno-bucket-2"}, %{creation_date: "2017-12-17T05:30:44.000Z", name: "oreno-bucket-3"}]
最後は Poison で JSON に…
Poison の encode!/2
を使えば JSON に.(出力はサンプルです)
iex(9)> ExAws.S3.list_buckets |> ExAws.request! |> Map.get(:body) |> Map.get(:buckets) |> Poison.encode! "[{\"name\":\"oreno-bucket-1\",\"creation_date\":\"2017-12-17T05:30:42.000Z\"},{\"name\":\"oreno-bucket-2\",\"creation_date\":\"2017-12-17T05:30:43.000Z\"},{\"name\":\"oreno-bucket-3\",\"creation_date\":\"2017-12-17T05:30:44.000Z\"}]"
いい感じ.
以上
ex_aws で S3 のバケット一覧を取得するまでのチュートリアルでした.
ex_aws は開発も活発で, パッケージのダウンロード数についても ex_aws が aws と比較しても圧倒的なので, 事実上のスタンダードパッケージだと思いますので, 今後のアップデートに注目していきたいと思います.