LoginSignup
2
3

More than 5 years have passed since last update.

AWS Lambda(C#)からAuroraにつないでみる

Posted at

Serverless Meetup Tokyo #4に参加してきたら

  • AWS SAから「ServerlessにはAuroraは不向き」的な話をされた
  • ENI作成時間が気になるなら、定期的にLambdaの暖機が必要

のような逆風にも負けずLambdaからAuroraに接続するアツい話を聞いて、無性にLambda(C#)からAuroraに接続したくなったので試してみました。

そう言えば「LambdaならC#よりnode.js/Pythonの方がオススメ」的な話も聞いたことがあるような...

開発環境

  • Mac
  • .Net Core 2.0.0 / .Net Core 1.0.5共存環境

本来Lambdaの作成には.Net Core 2.0.0は不要ですが
 ・自分の環境は1.0と2.0の共存環境で
 ・2.0.0になってdotnet restoreの振る舞いが変わった
ため、dotnetコマンドのバージョンが2.0.0の場合で記載します。

作業概要

  1. .Net Coreのインストール
  2. Auroraの作成
  3. C#コード作成
  4. デプロイ用パッケージの作成
  5. Lambdaの実行

1. .Net Coreのインストール

MicrosoftのサイトからMac用をダウンロードしてインストールします。

2.0.0
1.0.5 with SDK 1.0.4

2. Auroraの作成

AWSマネジメントコンソールからAuroraを構築します。

※留意点

  • VPC内からアクセスするため、Publicly Accessible:Noにします
  • お試しなら、インスタンスタイプは一番料金が安いdb.t2.smallがオススメです

3. C#コード作成

適当な作業ディレクトリを作成し、その配下に.csファイルを作成します。
またAuroraに接続するために、下記値を設定します。

  • クラスタエンドポイント
  • ユーザ / パスワード
  • データベース名
MyFunction.cs
using Amazon.Lambda.Core;
using MySql.Data.MySqlClient;

namespace sample_aurora
{
    public class MyFunction
    {
        const string ConnectionString = "<<クラスタエンドポイント>>;user=<<ユーザ>>;password=<<パスワード>>;port=3306;database=<<データベース名>>;SslMode=None";

        [LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
        public string MyHandler(LambdaEvent lambdaEvent, ILambdaContext context)
        {
            string command = lambdaEvent.Command;
            LambdaLogger.Log("Command: " + command + "\n");
            switch(command){
                case "select":
                    Select();
                    break;
                case "insert":
                    Insert();
                    break;
                case "init":
                    Init();
                    break;
                default:
                    LambdaLogger.Log("Do nothing.\n");
                    break;

            }
            return "Sample function was executed.";
        }

        private void Select()
        {
            MySqlConnection connection = new MySqlConnection(ConnectionString);
            connection.Open();

            MySqlCommand command = new MySqlCommand("select id from test_tbl;", connection);

            string message = "Data: ";

            using (MySqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    string row = $"{reader["id"]}";
                    message = message + "," + row;
                }
            }

            connection.Close();

            LambdaLogger.Log(message + "\n");
        }

        private void Insert()
        {
            MySqlConnection connection = new MySqlConnection(ConnectionString);
            connection.Open();

            MySqlCommand command = new MySqlCommand("insert into test_tbl values ();", connection);

            command.ExecuteNonQuery();

            connection.Close();

            LambdaLogger.Log("A record has been inserted.\n");
        }

        private void Init()
        {
            MySqlConnection connection = new MySqlConnection(ConnectionString);
            connection.Open();

            MySqlCommand command = new MySqlCommand("create table if not exists test_tbl (id int auto_increment primary key);", connection);

            command.ExecuteNonQuery();

            connection.Close();

            LambdaLogger.Log("A table has been created.\n");
        }
    }

    public class LambdaEvent
    {
        public string Command { get; set; }
    }
}

4. デプロイ用パッケージの作成

4-1. .csprojファイルの作成

同じ作業ディレクトリに.csprojファイルを作成します。

sample_aurora.csproj
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp1.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Amazon.Lambda.TestUtilities" Version="1.0.0" />
    <PackageReference Include="Amazon.Lambda.Serialization.Json" Version="1.1.0" />
    <PackageReference Include="Amazon.Lambda.Core" Version="1.0.0" />
    <PackageReference Include="MySql.Data.Core" Version="7.0.4-IR-191" />
  </ItemGroup>
</Project>

4-2. デプロイパッケージの作成

作業ディレクトリ内で以下コマンドを実行します。

$ dotnet restore
$ dotnet publish --output publish
$ cp ~/.nuget/packages/system.data.sqlclient/4.1.0/runtimes/unix/lib/netstandard1.3/System.Data.SqlClient.dll publish/
$ cp ~/.nuget/packages/system.diagnostics.tracesource/4.0.0/runtimes/unix/lib/netstandard1.3/System.Diagnostics.TraceSource.dll pulish/
$ cd publish
$ zip ../sample_aurora.zip *

※留意点

  • System.Data.SqlClient.dllとSystem.Diagnostics.TraceSource.dllはdotnet publishでは含まれなかったため、手動でコピーしています。(無いとLambda実行時にエラーになります)

4-3. Lamdbaのデプロイ

AWSマネジメントコンソールからLambdaを選んで、「sample_aurora.zip」をデプロイします。

  • VPC対応にします
  • Auroraに接続できるsecurity groupを指定します
  • もしくは、指定したsubnet groupがaurora側のsecurity groupで許可されていれば、lamdbaで指定するsecurity grouopはダミーで構いません

5. Lambdaの実行

AWSマネジメントコンソールからLambdaを実行します。

5-1. テーブル作成

test eventに以下のjsonを指定してLambdaを実行します。

{
  "Command": "init"
}

Log outputに以下出力されます。

Command: init
A table has been created.

5-2. Insert

test eventに以下のjsonを指定してLambdaを実行します。

{
  "Command": "insert"
}

Log outputに以下出力されます。

Command: insert
A record has been inserted.

実行した回数分テーブルにレコードが追加されます。

5-3. Select

test eventに以下のjsonを指定してLambdaを実行します。

{
  "Command": "select"
}

Log outputに以下出力されます。

Command: select
Data: ,1,2,3

雑感

案外簡単にC# LambdaからAuroraへ接続できました。

2
3
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
2
3