4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Elixir on AWS LambdaからDynamoDBへアクセス

Posted at

AWS LambdaのCustom RuntimeでElixirを動かし、DynamoDBのGET/PUTを試してみます。

環境

  • Windows 10 Pro 64bit
  • VSCode 1.38.1
  • Docker Desktop for Windows 2.1.0.4
  • Docker Engine 19.03.4

事前準備

こちらで作った環境をベースに作業を進めます。

参考資料

alertlogic社のサンプルコードをベースに都度試しながら進めます。

環境変数の読込

AWS Lambdaの環境変数に設定したキーに対する値をログに出力します。

  • lib/lambda_ex.ex
    • 以下の通り変更を加え、MIX_ENV=prod mix erllambda.releaseを実行しリリース用モジュールをリビルド。出来上がったzipファイルをAWS Lambdaへ反映
      • ログへの環境変数の内容出力を追加
defmodule LambdaEx do

  def handle(event, context) do
    :erllambda.message("event: ~p", [event])
    :erllambda.message("context: ~p", [context])
+    :erllambda.message("envName: ~p", [System.get_env("ENV_NAME")])

    {:ok, response({:ok, [[{"result", "OK"}]]})}
  end

  defp items_to_json(items) do
    items
    |> Enum.map(&:maps.from_list/1)
    |> :jiffy.encode
  end

  defp response({:ok, response}) do
    %{
      statusCode: "200",
      body: items_to_json(response),
      headers: %{
        "Content-Type": "application/json"
      }
    }
  end

  defp response({:error, response}) do
    %{
      statusCode: "400",
      body: response,
      headers: %{
        "Content-Type": "application/json"
      }
    }
  end
end
  • AWS Lambdaの環境変数に値を設定

    • ENV_NAME : hoge
      image.png
  • 実行結果

    • CloudWatch LogsでログにenvName: hogeが出力されていることを確認。
      image.png

DynamoDBからGET

  • テスト用のテーブルを作成

    • テーブル名:TEST_ITEMS
    • プライマリキー:code(string)
    • 設定:デフォルト
  • テスト用のレコードを作成

    • {"code": "AAA", "name": "サンプル1", "type": "xxx"}
    • {"code": "BBB", "name": "サンプル2", "type": "yyy"}
      image.png
  • lib/lambda_ex.ex

    • 以下の通り変更を加え、モジュールリビルド&AWS Lambdaへ反映
      • 環境変数からテーブル名取得を追加
      • テーブルからの全件取得を追加
      • テーブルから取得した値をレスポンスに追加
defmodule LambdaEx do

  def handle(event, context) do
    :erllambda.message("event: ~p", [event])
    :erllambda.message("context: ~p", [context])
+    # :erllambda.message("envName: ~p", [System.get_env("ENV_NAME")])

+    table_name = System.get_env("TABLE_NAME")
    
+    result = scan_all(table_name)

+    # {:ok, response({:ok, [[{"result", "OK"}]]})}
+    {:ok, response(result)}
  end

+  defp scan_all(table_name) do
+    :erlcloud_ddb_util.scan_all(table_name)
+  end
  
  defp items_to_json(items) do
    items
    |> Enum.map(&:maps.from_list/1)
    |> :jiffy.encode
  end

  defp response({:ok, response}) do
    %{
      statusCode: "200",
      body: items_to_json(response),
      headers: %{
        "Content-Type": "application/json"
      }
    }
  end

  defp response({:error, response}) do
    %{
      statusCode: "400",
      body: response,
      headers: %{
        "Content-Type": "application/json"
      }
    }
  end
end

  • AWS Lambdaの環境変数に値を設定

    • TABLE_NAME : TEST_ITEMS
      image.png
  • 実行結果

    • 実行詳細のbodyにDynamoDBの値が出力されていることを確認。
      image.png

DynamoDBへPUT

  • lib/lambda_ex.ex
    • 以下の通り変更を加え、モジュールリビルド&AWS Lambdaへ反映
      • AWS LambdaのeventパラメータをそのままDynamoDBへPUTする処理を追加
defmodule LambdaEx do

  def handle(event, context) do
    :erllambda.message("event: ~p", [event])
    :erllambda.message("context: ~p", [context])
    # :erllambda.message("envName: ~p", [System.get_env("ENV_NAME")])

    table_name = System.get_env("TABLE_NAME")

+    put_item(event, table_name)

    result = scan_all(table_name)

    # {:ok, response({:ok, [[{"result", "OK"}]]})}
    {:ok, response(result)}
  end

  defp scan_all(table_name) do
    :erlcloud_ddb_util.scan_all(table_name)
  end

+  defp put_item(item, table_name) do
+    :erlcloud_ddb2.put_item(table_name, :maps.to_list(item))
+  end

  defp items_to_json(items) do
    items
    |> Enum.map(&:maps.from_list/1)
    |> :jiffy.encode
  end

  defp response({:ok, response}) do
    %{
      statusCode: "200",
      body: items_to_json(response),
      headers: %{
        "Content-Type": "application/json"
      }
    }
  end

  defp response({:error, response}) do
    %{
      statusCode: "400",
      body: response,
      headers: %{
        "Content-Type": "application/json"
      }
    }
  end
end

  • テストイベントのペイロードにDynamoDBへ登録する値を設定
    image.png

  • 実行結果

    • 実行詳細のbodyに新規追加したレコードの値が出力されていることを確認。
      image.png
      image.png

所感

erlcloudを使うことで簡単にAWSのリソースへアクセスすることができました。また、Docker + VSCodeのリモートアクセス機能を使うことでビルド~反映が簡単になりました。あとはlocalstackである程度動作確認してから反映できればより良いと思います。

4
0
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
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?