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の場合で記載します。
作業概要
- .Net Coreのインストール
- Auroraの作成
- C#コード作成
- デプロイ用パッケージの作成
- Lambdaの実行
1. .Net Coreのインストール
MicrosoftのサイトからMac用をダウンロードしてインストールします。
2. Auroraの作成
AWSマネジメントコンソールからAuroraを構築します。
※留意点
- VPC内からアクセスするため、Publicly Accessible:Noにします
- お試しなら、インスタンスタイプは一番料金が安いdb.t2.smallがオススメです
3. C#コード作成
適当な作業ディレクトリを作成し、その配下に.csファイルを作成します。
またAuroraに接続するために、下記値を設定します。
- クラスタエンドポイント
- ユーザ / パスワード
- データベース名
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ファイルを作成します。
<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へ接続できました。