ElixirでもAWSをコントロール!erlcloudをElixirで使ってみた

はじめに

前回(ErlangでもAWSをコントロール!erlcloudを使ってみた)、ErlangでAWSのAPIを操作するerlcloudを使ってみました。

今回は、Erlangの仮想環境上で動作するプログラミング言語Elixirから、erlcloudを使ってみたいと思います!

やってみた

セットアップ

僕のローカル環境はMacBook Pro(OS X Yosemite 10.10.3)です。

まずはElixirをインストール。brewで一発です。

$ brew update
$ brew install elixir
$ elixir -v
Elixir 1.0.4

プロジェクトを作成する

Elixirのプロジェクト管理ツールであるMixを使って、新しいプロジェクトを作成します。今回はawsという名前にしました。

$ mix new aws
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/aws.ex
* creating test
* creating test/test_helper.exs
* creating test/aws_test.exs

Your mix project was created successfully.
You can use mix to compile it, test it, and more:

    cd aws
    mix test

Run `mix help` for more commands.

プロンプトに表示された通り、プロジェクトディレクトリに移動して、テストを実行してみます。

$ cd aws
$ mix test
Compiled lib/aws.ex
Generated aws app
.

Finished in 0.07 seconds (0.07s on load, 0.00s on tests)
1 tests, 0 failures

Randomized with seed 141109

問題無く動いてますね。

試してみる

簡単に動作を試してみます。まずプロジェクト定義が記述されるmix.exsを編集し、erlcloudを使うように設定します。また後ほど実行ファイルも作成するのでescript:定義も追加しています。

$ vi mix.exs
defmodule Aws.Mixfile do
  use Mix.Project

  def project do
    [app: :aws,
     version: "0.0.1",
     elixir: "~> 1.0",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     escript: [ main_module: Aws ],
     deps: deps]
  end

  def application do
    [applications: [:logger, :ssl, :erlcloud]]
  end

  defp deps do
    [{:erlcloud, git: "https://github.com/gleber/erlcloud"}]
  end
end

getでerlcloudリポジトリを取得します。

$ mix deps.get

そしてcompileによってerlcloudリポジトリの各ライブラリがコンパイルされます。

$ mix deps.compile

事前準備。環境変数にAWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYをセットします。

$ export AWS_ACCESS_KEY_ID=<YOUR_ACCESS_KEY>
$ export AWS_SECRET_ACCESS_KEY=<YOUR_SECRET_KEY>

では、ElixirのインタラクティブSheellであるiexから使ってみましょう。

$ iex -S mix
Erlang/OTP 17 [erts-6.4]  [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Compiled lib/aws.ex
Generated aws app
Interactive Elixir (1.0.4) - press Ctrl+C to exit (type h() ENTER for help)

まずAWSアクセスキーとシークレットアクセスキーを変数として定義します。

iex(1)> access_key_id = System.get_env("AWS_ACCESS_KEY_ID") |> String.to_char_list
iex(2)> secret_access_key = System.get_env("AWS_SECRET_ACCESS_KEY") |> String.to_char_list

次にEC2のエンドポイントを変数として定義します。今回は東京リージョンを指定しています。

iex(3)> ec2_endpoint = 'ec2.ap-northeast-1.amazonaws.com'

上記で定義したAWSアクセスキー、シークレットアクセスキー、EC2エンドポイントをセットします。

iex(4)> :erlcloud_ec2.configure(access_key_id, secret_access_key, ec2_endpoint)
:ok

では、DescribeInstancesを実行してみます。

iex(5)> :erlcloud_ec2.describe_instances()
{:ok,
 [[reservation_id: 'r-9a0XXXXX', owner_id: '123456789012',
   instances_set: [[instance_id: 'i-59eXXXXX',
     group_set: [[group_id: 'sg-53XXXXX', group_name: 'mainte']],
     image_id: 'ami-18869819', instance_state: [code: 16, name: 'running'],
     private_dns_name: 'ip-172-31-XXX-XXX.ap-northeast-1.compute.internal',
     dns_name: 'ec2-52-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com',
     reason: :none, key_name: 'mykey', ami_launch_index: 0,
     product_codes: [], instance_type: 't2.micro',
...snip...

はい、EC2インスタンスの一覧が取得できました!ちゃんと動いていますね!

スクリプトを書いて実行ファイルを作る

それではlib/aws.exを編集します。以下のようにEC2インスタンスをLaunchする内容にしました。

$ vi lib/aws.ex
defmodule Aws do
  require Record
  Record.defrecord :ec2_instance_spec, Record.extract(:ec2_instance_spec, from: "deps/erlcloud/include/erlcloud_ec2.hrl")

  def main(args) do
    IO.puts args
    access_key_id = System.get_env("AWS_ACCESS_KEY_ID") |> String.to_char_list
    secret_access_key = System.get_env("AWS_SECRET_ACCESS_KEY") |> String.to_char_list
    ec2_endpoint = 'ec2.ap-northeast-1.amazonaws.com'

    :erlcloud_ec2.configure(access_key_id, secret_access_key, ec2_endpoint)

    ami = 'ami-18869819'
    instancetype = 't2.micro'
    az = 'ap-northeast-1a'
    key = 'mykey'
    spec = ec2_instance_spec( image_id: ami,
                              instance_type: instancetype,
                              availability_zone: az,
                              key_name: key)

    :erlcloud_ec2.run_instances(spec)
  end
end

mix escript.buildを実行し、実行ファイルを作成します。ここでスクリプトに不備があればコンパイルエラーのメッセージが出力されます。

$ mix escript.build
Compiled lib/aws.ex
Generated aws app
Generated escript aws with MIX_ENV=dev

では出来上がった実行ファイルを走らせてみます!

$ ./aws

はい、できました!

EC2_Management_Console

さいごに

今回はSapporo.beam@niku_nameさんにたくさん質問させて頂きました。ありがとうございました!

Erlangの後にElixirを触ると、確かにElixirのほうがRubyぽさがあって取っ付きやすいですね。こうやって色々なプログラミング言語に触れてみると新しい発見があって楽しいです。今後も新しいツールを見つけたらどんどん試していきます!