F# で AWS CDK して躓いてる
最近仕事で AWS CDK を使ってみたが、非常に良い感触だった。 仕事では TypeScript を採用したが、テンプレートが提供されている言語を見るとなんと F# がいるではないか。
PS> cdk init --list
Available templates:
* app: Template for a CDK Application
└─ cdk init app --language=[csharp|fsharp|go|java|javascript|python|typescript]
* lib: Template for a CDK Construct Library
└─ cdk init lib --language=typescript
* sample-app: Example CDK Application with some constructs
└─ cdk init sample-app --language=[csharp|fsharp|go|java|javascript|python|typescript]
単に「C# のクラス用意したから継承して使ってや~」的なもので F# 向けに調整されてないだろうが、コレ誰が使うねんという気がしたので、試してみた。
参考にした前例たち。非常に参考にさせてもらった。
まずテンプレからプロジェクトを生成した素の状態で CFn を作成してみる。
cdk init sample-app --language=fsharp
cdk synth
ちゃんと CFn をビルドできた。 どんなコードが出るか知りたかったので sample-app
を使ったが、ここで app
テンプレを使うと、利用されない this
が残ってるので警告が出る。でも勿論 CFn をビルドできる。
記述に関しては TypeScript など他の言語と大差なさそう。ただ予想通り C# との相互運用は前提になってる。
宣言的に記述する箇所については let
バインディングして、 リソースに手続き的に何かすると do
バインディングみたい。
試しに S3 と Lambda を EventBridge で繋いでみたい。
F# の CDK では Amazon.CDK
に必要な Construct が全部入りしてるみたい。なので Amazon.CDK.xxx
みたいな感じでポチポチ .
を刻んでいけば、ドキュメントがなくてもそれなりに探せる。
F# は言語固有モジュールが無いので、ここに例えば Lambda を足すとすると、個別にビルドする感じになる。あれめちゃくちゃ楽で好きなんやけど、 .Net 向けにはない。 プロジェクトを別途足す方向で作るらしい。
# テンプレなかったので探してインストール
dotnet new lambda.EmptyFunction --search
dotnet new --install Amazon.Lambda.Templates
dotnet new lambda.S3 --output . --name api --language "F#"
cd src
dotnet sln add api
stack をザーッと書いてみたが、めちゃくちゃつまづきどころがある。
open System.Collections
したらStack
が競合するので注意MemorySize
に128
を渡してたら Ionide やdotnet build
ではエラー検知できなかったが、cdk synth
でエラー(めんどくせ)MemorySize
を128
から(Some 128.0 |> Option.toNullable)
に
必須プロパティがビルドまでわからないのつらい
EventPattern
のIDictionary<string,obj>
を一息で書くのかなりキツイ(まじでめんどい)Value
の型が揃わないところは個別にlet
してあとで組み合わせたりdict
に食わせるtuple
はきっちりカッコで囲むと先述のlet
が不要になった
EventPattern
のDetail
がcdk synth
でエラーになる
Prefix のパターンをやりたいのだけど、 Content filtering in Amazon EventBridge event patterns - Amazon EventBridge
EventPattern:
source:
- aws.s3
detail-type:
- Object Created
detail:
bucket:
name:
- Ref: バケツ
object:
key:
- prefix: test/
以下の記述だとエラーになる。
EventPattern =
EventPattern(
Source = [| "aws.s3" |],
DetailType = [| "Object Created" |],
Detail =
dict [ ("bucket", dict [ ("name", [| bucket.BucketName |]) ])
("object", dict [ ("key", [| dict [ ("prefix", "test/") ] |]) ]) ]
)
Unhandled exception. System.ArgumentException: Could not infer JSII type for .NET type 'IDictionary`2' (Parameter 'type')
dict [ ("prefix", "test/") ]
の代わりに文字列を渡してると問題なくなるけど、それってスキーマ違反なんですけど。
この辺 TypeScript は困った記憶ないので、参ったなという感じ。
この辺の回答が出たら割りと参考になるかもなーと思って見ている。How to set detail on an eventpattern in java · Discussion #20894 · aws/aws-cdk 単純に F# 力の低さに起因して記述できないだけだといいけど。
もうちょっと深掘したいが今週はここまで。 とりあえず repo は作った。 krymtkts/aws-cdk-fsharp-trial