Header menu logo FsCDK

EC2 ECS Amazon EC2 and ECS (Elastic Container Service) Example

This example demonstrates how to create Amazon EC2 (Elastic Compute Cloud) instances and ECS (Elastic Container Service) services using FsCDK.

EC2 Instance (Virtual Machine)

#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 Amazon.CDK
open Amazon.CDK.AWS.EC2
open FsCDK

ECS Cluster and Fargate Service

open Amazon.CDK.AWS.ECS

stack "ECSStack" {
    scope (app { context [ "environment", "production" ] })

    description "ECS cluster with Fargate service"

    // Create VPC
    let! myVpc =
        vpc "MyVpc" {
            maxAzs 2
            natGateways 1
            cidr "10.0.0.0/16"
        }

    // Create ECS cluster
    let myCluster =
        ecsCluster "MyCluster" {
            vpc myVpc
            containerInsights ContainerInsights.ENABLED
            enableFargateCapacityProviders true
        }

    ()
}

Key Features

EC2 (Virtual Machines)

ECS (Container Orchestration)

Security Best Practices

  1. EC2 Instances:
    • IMDSv2 is required by default to prevent SSRF attacks
    • EBS volumes are encrypted by default
    • Detailed monitoring is opt-in to control costs
  2. ECS Services:
    • Services are private by default (no public IP)
    • Container Insights enabled for security monitoring
    • Follows principle of least privilege

Deployment

# Synthesize CloudFormation template
cdk synth

# Deploy to AWS
cdk deploy

# Destroy resources when done
cdk destroy
namespace Amazon
namespace Amazon.CDK
namespace Amazon.CDK.AWS
namespace Amazon.CDK.AWS.EC2
namespace FsCDK
val get: unit -> {| Account: string; Region: string |}
namespace System
type Environment = static member Exit: exitCode: int -> unit static member ExpandEnvironmentVariables: name: string -> string static member FailFast: message: string -> unit + 1 overload static member GetCommandLineArgs: unit -> string array static member GetEnvironmentVariable: variable: string -> string + 1 overload static member GetEnvironmentVariables: unit -> IDictionary + 1 overload static member GetFolderPath: folder: SpecialFolder -> string + 1 overload static member GetLogicalDrives: unit -> string array static member SetEnvironmentVariable: variable: string * value: string -> unit + 1 overload static member CommandLine: string ...
<summary>Provides information about, and means to manipulate, the current environment and platform. This class cannot be inherited.</summary>
System.Environment.GetEnvironmentVariable(variable: string) : string
System.Environment.GetEnvironmentVariable(variable: string, target: System.EnvironmentVariableTarget) : string
val config: {| Account: string; Region: string |}
module Config from Ec2-ecs
val stack: name: string -> StackBuilder
<summary>Creates an AWS CDK Stack construct.</summary>
<param name="name">The name of the stack.</param>
<code lang="fsharp"> stack "MyStack" { lambda myFunction bucket myBucket } </code>
custom operation: scope (Constructs.Construct) Calls StackBuilder.Scope
val app: AppBuilder
<summary>Creates an AWS CDK App construct.</summary>
<code lang="fsharp"> app { context [ ("environment", "production"); ("feature-flag", true) ] stackTraces true } </code>
custom operation: context ((string * obj) list) Calls AppBuilder.Context
<summary>Adds context to the App with a key-value pair.</summary>
<param name="config">The current stack configuration.</param>
<param name="keys">The context key-value pairs to add.</param>
<code lang="fsharp"> app { context [ ("environment", "production") ("feature-flag", true) ] } </code>
custom operation: env (IEnvironment) Calls StackBuilder.Env
val environment: EnvironmentBuilder
<summary>Creates an AWS CDK Environment configuration.</summary>
<code lang="fsharp"> environment { account "123456789012" region "us-west-2" } </code>
custom operation: account (string) Calls EnvironmentBuilder.Account
<summary>Sets the AWS account ID for the environment.</summary>
<param name="config">The current configuration.</param>
<param name="accountId">The AWS account ID.</param>
<code lang="fsharp"> environment { account "123456789012" } </code>
anonymous record field Account: string
custom operation: region (string) Calls EnvironmentBuilder.Region
<summary>Sets the AWS region for the environment.</summary>
<param name="config">The current configuration.</param>
<param name="regionName">The AWS region name.</param>
<code lang="fsharp"> environment { region "us-west-2" } </code>
anonymous record field Region: string
custom operation: description (string) Calls StackBuilder.Description
<summary>Sets the stack description.</summary>
<param name="config">The current stack configuration.</param>
<param name="desc">A description of the stack.</param>
<code lang="fsharp"> stack "MyStack" { description "My application stack" } </code>
val myVpc: IVpc
val vpc: name: string -> VpcBuilder
<summary>Creates a VPC configuration with AWS best practices.</summary>
<param name="name">The VPC name.</param>
<code lang="fsharp"> vpc "MyVpc" { maxAzs 2 natGateways 1 cidr "10.0.0.0/16" } </code>
custom operation: maxAzs (int) Calls VpcBuilder.MaxAzs
<summary>Sets the maximum number of Availability Zones to use.</summary>
<param name="config">The current VPC configuration.</param>
<param name="maxAzs">The maximum number of AZs (default: 2 for HA).</param>
<code lang="fsharp"> vpc "MyVpc" { maxAzs 3 } </code>
custom operation: natGateways (int) Calls VpcBuilder.NatGateways
<summary>Sets the number of NAT Gateways.</summary>
<param name="config">The current VPC configuration.</param>
<param name="natGateways">The number of NAT gateways (default: 1 for cost optimization).</param>
<code lang="fsharp"> vpc "MyVpc" { natGateways 2 } </code>
custom operation: cidr (string) Calls VpcBuilder.Cidr
<summary>Sets the CIDR block for the VPC.</summary>
<param name="config">The current VPC configuration.</param>
<param name="cidr">The CIDR block (e.g., "10.0.0.0/16").</param>
<code lang="fsharp"> vpc "MyVpc" { cidr "10.0.0.0/16" } </code>
val ec2Instance: name: string -> EC2InstanceBuilder
<summary> Creates a new EC2 instance builder with secure defaults. Example: ec2Instance "my-instance" { instanceType (InstanceType.Of(InstanceClass.BURSTABLE3, InstanceSize.SMALL)) } </summary>
custom operation: instanceType (InstanceType) Calls EC2InstanceBuilder.InstanceType
Multiple items
type InstanceType = inherit DeputyBase new: instanceTypeIdentifier: string -> unit member IsBurstable: unit -> bool member SameInstanceClassAs: other: InstanceType -> bool member ToString: unit -> string static member Of: instanceClass: InstanceClass * instanceSize: InstanceSize -> InstanceType member Architecture: InstanceArchitecture

--------------------
InstanceType(instanceTypeIdentifier: string) : InstanceType
InstanceType.Of(instanceClass: InstanceClass, instanceSize: InstanceSize) : InstanceType
[<Struct>] type InstanceClass = | STANDARD3 = 0 | M3 = 1 | STANDARD4 = 2 | M4 = 3 | STANDARD5 = 4 | M5 = 5 | STANDARD5_NVME_DRIVE = 6 | M5D = 7 | STANDARD5_AMD = 8 | M5A = 9 ...
field InstanceClass.BURSTABLE3: InstanceClass = 172
[<Struct>] type InstanceSize = | NANO = 0 | MICRO = 1 | SMALL = 2 | MEDIUM = 3 | LARGE = 4 | XLARGE = 5 | XLARGE2 = 6 | XLARGE3 = 7 | XLARGE4 = 8 | XLARGE6 = 9 ...
field InstanceSize.SMALL: InstanceSize = 2
custom operation: machineImage (IMachineImage) Calls EC2InstanceBuilder.MachineImage
type MachineImage = inherit DeputyBase static member FromSsmParameter: parameterName: string * ?options: ISsmParameterImageOptions -> IMachineImage static member GenericLinux: amiMap: IDictionary<string,string> * ?props: IGenericLinuxImageProps -> IMachineImage static member GenericWindows: amiMap: IDictionary<string,string> * ?props: IGenericWindowsImageProps -> IMachineImage static member LatestAmazonLinux: ?props: IAmazonLinuxImageProps -> IMachineImage static member LatestAmazonLinux2: ?props: IAmazonLinux2ImageSsmParameterProps -> IMachineImage static member LatestAmazonLinux2022: ?props: IAmazonLinux2022ImageSsmParameterProps -> IMachineImage static member LatestAmazonLinux2023: ?props: IAmazonLinux2023ImageSsmParameterProps -> IMachineImage static member LatestWindows: version: WindowsVersion * ?props: IWindowsImageProps -> IMachineImage static member Lookup: props: ILookupMachineImageProps -> IMachineImage ...
MachineImage.LatestAmazonLinux2(?props: IAmazonLinux2ImageSsmParameterProps) : IMachineImage
custom operation: vpc (IVpc) Calls EC2InstanceBuilder.Vpc
custom operation: requireImdsv2 (bool) Calls EC2InstanceBuilder.RequireImdsv2
custom operation: detailedMonitoring (bool) Calls EC2InstanceBuilder.DetailedMonitoring
namespace Amazon.CDK.AWS.ECS
val myCluster: ECSClusterSpec
val ecsCluster: name: string -> ECSClusterBuilder
<summary> Creates a new ECS cluster builder with best practices. Example: ecsCluster "my-cluster" { vpc myVpc } </summary>
custom operation: vpc (IVpc) Calls ECSClusterBuilder.Vpc
custom operation: containerInsights (ContainerInsights) Calls ECSClusterBuilder.ContainerInsights
[<Struct>] type ContainerInsights = | ENABLED = 0 | DISABLED = 1 | ENHANCED = 2
field ContainerInsights.ENABLED: ContainerInsights = 0
custom operation: enableFargateCapacityProviders (bool) Calls ECSClusterBuilder.EnableFargateCapacityProviders

Type something to start searching.