FsCDK lets you describe AWS infrastructure with a small, expressive F# DSL built on top of the AWS Cloud Development Kit (CDK). If you like computation expressions, immutability, and readable diffs, you’ll feel right at home.
This page gives you a quick, human-sized tour. No buzzwords, just a couple of realistic stacks you can read end-to-end.
What you’ll see below: - Define per-environment settings once and reuse them. - Declare DynamoDB tables, Lambdas, queues and topics with intent, not boilerplate. - Wire resources together (grants and subscriptions) without hunting for ARNs.
#r "../src/bin/Release/net8.0/publish/Amazon.JSII.Runtime.dll"
#r "../src/bin/Release/net8.0/publish/Constructs.dll"
#r "../src/bin/Release/net8.0/publish/Amazon.CDK.Lib.dll"
#r "../src/bin/Release/net8.0/publish/System.Text.Json.dll"
#r "../src/bin/Release/net8.0/publish/FsCDK.dll"
open FsCDK
open Amazon.CDK
open Amazon.CDK.AWS.DynamoDB
open Amazon.CDK.AWS.Lambda
// 1) Environments
let devEnv =
environment {
account "123456789012"
region "us-east-1"
}
let prodEnv =
environment {
account "098765432109"
region "us-east-1"
}
// 2) A Dev stack you can actually work with
let devStack =
stack "Dev" {
// Attach StackProps implicitly via nested builder
stackProps {
env devEnv
description "Developer stack for feature work"
tags [ "service", "users"; "env", "dev" ]
}
// resources
table "users" {
partitionKey "id" AttributeType.STRING
billingMode BillingMode.PAY_PER_REQUEST
removalPolicy RemovalPolicy.DESTROY // fine for dev
}
lambda "users-api-dev" {
handler "Users::Handler::FunctionHandler"
runtime Runtime.DOTNET_8
code "./examples/lambdas/users" // any folder with your code bundle
memory 512
timeout 10.0
description "CRUD over the users table"
}
queue "users-dlq" {
messageRetention (7.0 * 24.0 * 3600.0) // 7 days
}
queue "users-queue" {
deadLetterQueue "users-dlq" 5
visibilityTimeout 30.0
}
topic "user-events" { displayName "User events" }
// wiring
subscription {
topic "user-events"
queue "users-queue"
}
grant {
table "users"
lambda "users-api-dev"
readWriteAccess
}
}
// 3) A production-leaning stack
let prodStack =
stack "Prod" {
stackProps {
env prodEnv
stackName "users-prod"
terminationProtection true
tags [ "service", "users"; "env", "prod" ]
}
table "users" {
partitionKey "id" AttributeType.STRING
billingMode BillingMode.PAY_PER_REQUEST
removalPolicy RemovalPolicy.RETAIN // keep data safe
pointInTimeRecovery true
}
lambda "users-api" {
handler "Users::Handler::FunctionHandler"
runtime Runtime.DOTNET_8
code "./examples/lambdas/users"
memory 1024
timeout 15.0
description "CRUD over the users table"
}
grant {
table "users"
lambda "users-api"
readWriteAccess
}
}
// 4) Build an in-memory CDK app (no deploy here). We create stacks into an App
app {
// Build both stacks into the same app
devStack
prodStack
}
namespace FsCDK
namespace Amazon
namespace Amazon.CDK
namespace Amazon.CDK.AWS
namespace Amazon.CDK.AWS.DynamoDB
namespace Amazon.CDK.AWS.Lambda
val devEnv: Environment
val environment: EnvironmentBuilder
custom operation: account (string)
Calls EnvironmentBuilder.Account
custom operation: region (string)
Calls EnvironmentBuilder.Region
val prodEnv: Environment
val devStack: StackSpec
val stack: name: string -> StackBuilder
val stackProps: StackPropsBuilder
custom operation: env (Environment)
Calls StackPropsBuilder.Environment
custom operation: description (string)
Calls StackPropsBuilder.Description
custom operation: tags ((string * string) list)
Calls StackPropsBuilder.Tags
val table: name: string -> TableBuilder
custom operation: partitionKey (string) (AttributeType)
Calls TableBuilder.PartitionKey
[<Struct>]
type AttributeType =
| BINARY = 0
| NUMBER = 1
| STRING = 2
field AttributeType.STRING: AttributeType = 2
custom operation: billingMode (BillingMode)
Calls TableBuilder.BillingMode
[<Struct>]
type BillingMode =
| PAY_PER_REQUEST = 0
| PROVISIONED = 1
field BillingMode.PAY_PER_REQUEST: BillingMode = 0
custom operation: removalPolicy (RemovalPolicy)
Calls TableBuilder.RemovalPolicy
[<Struct>]
type RemovalPolicy =
| DESTROY = 0
| RETAIN = 1
| SNAPSHOT = 2
| RETAIN_ON_UPDATE_OR_DELETE = 3
field RemovalPolicy.DESTROY: RemovalPolicy = 0
val lambda: name: string -> FunctionBuilder
custom operation: handler (string)
Calls FunctionBuilder.Handler
custom operation: runtime (Runtime)
Calls FunctionBuilder.Runtime
Multiple items
type Runtime = inherit DeputyBase new: name: string * ?family: Nullable<RuntimeFamily> * ?props: ILambdaRuntimeProps -> unit member RuntimeEquals: other: Runtime -> bool member ToString: unit -> string member BundlingImage: DockerImage member Family: Nullable<RuntimeFamily> member IsVariable: bool member Name: string member SupportsCodeGuruProfiling: bool member SupportsInlineCode: bool ...
--------------------
Runtime(name: string, ?family: System.Nullable<RuntimeFamily>, ?props: ILambdaRuntimeProps) : Runtime
type Runtime = inherit DeputyBase new: name: string * ?family: Nullable<RuntimeFamily> * ?props: ILambdaRuntimeProps -> unit member RuntimeEquals: other: Runtime -> bool member ToString: unit -> string member BundlingImage: DockerImage member Family: Nullable<RuntimeFamily> member IsVariable: bool member Name: string member SupportsCodeGuruProfiling: bool member SupportsInlineCode: bool ...
--------------------
Runtime(name: string, ?family: System.Nullable<RuntimeFamily>, ?props: ILambdaRuntimeProps) : Runtime
property Runtime.DOTNET_8: Runtime with get
custom operation: code (Code)
Calls FunctionBuilder.Code
custom operation: memory (int)
Calls FunctionBuilder.Memory
custom operation: timeout (float)
Calls FunctionBuilder.Timeout
custom operation: description (string)
Calls FunctionBuilder.Description
val queue: name: string -> QueueBuilder
custom operation: messageRetention (float)
Calls QueueBuilder.MessageRetention
custom operation: deadLetterQueue (string) (int)
Calls QueueBuilder.DeadLetterQueue
custom operation: visibilityTimeout (float)
Calls QueueBuilder.VisibilityTimeout
val topic: name: string -> TopicBuilder
custom operation: displayName (string)
Calls TopicBuilder.DisplayName
val subscription: SubscriptionBuilder
custom operation: topic (string)
Calls SubscriptionBuilder.Topic
custom operation: queue (string)
Calls SubscriptionBuilder.Queue
val grant: GrantBuilder
custom operation: table (string)
Calls GrantBuilder.Table
custom operation: lambda (string)
Calls GrantBuilder.Lambda
custom operation: readWriteAccess
Calls GrantBuilder.ReadWriteAccess
val prodStack: StackSpec
custom operation: stackName (string)
Calls StackPropsBuilder.StackName
custom operation: terminationProtection (bool)
Calls StackPropsBuilder.TerminationProtection
field RemovalPolicy.RETAIN: RemovalPolicy = 1
custom operation: pointInTimeRecovery (bool)
Calls TableBuilder.PointInTimeRecovery
val app: AppBuilder