Header menu logo FsCDK

EKS Amazon EKS (Elastic Kubernetes Service) Example

This example demonstrates how to create Amazon EKS (Elastic Kubernetes Service) clusters using FsCDK for container orchestration with Kubernetes.

What is EKS?

Amazon Elastic Kubernetes Service (EKS) is a managed Kubernetes service that makes it easy to run Kubernetes on AWS without needing to install and operate your own Kubernetes control plane.

Key Benefits: - Fully managed Kubernetes control plane - Automatic upgrades and patching - Integration with AWS services (IAM, VPC, CloudWatch) - High availability across multiple AZs - Support for both EC2 and Fargate compute

Prerequisites

Basic EKS Cluster

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

Advanced Cluster Configurations

Fargate Profile for Serverless Pods

Run pods without managing EC2 instances using AWS Fargate.

Benefits: - No node management overhead - Pay only for pod resources - Automatic scaling - Improved security isolation

stack "FargateEKSStack" {
    description "EKS cluster with Fargate profiles"

    let! fargateVpc =
        vpc "FargateVpc" {
            maxAzs 2
            cidr "10.0.0.0/16"
        }

    let fargateCluster =
        eksCluster "FargateCluster" {
            vpc fargateVpc
            version KubernetesVersion.V1_28
            defaultCapacity 0

            addFargateProfile (
                "FargateProfile",
                FargateProfileOptions(
                    Selectors =
                        [| Selector(Namespace = "default")
                           Selector(Namespace = "kube-system")
                           Selector(Namespace = "production", Labels = dict [ "compute-type", "serverless" ]) |]
                )
            )

        }

    ()
}

Multi-Architecture Node Groups

Support both x86 and ARM workloads for cost optimization.

ARM (Graviton) Benefits: - 20% better price/performance - Lower energy consumption - Same performance as x86 for most workloads

stack "MultiArchEKSStack" {
    description "EKS cluster with x86 and ARM node groups"

    let! multiArchVpc =
        vpc "MultiArchVpc" {
            maxAzs 2
            cidr "10.0.0.0/16"
        }

    let multiArchCluster =
        eksCluster "MultiArchCluster" {
            vpc multiArchVpc
            version KubernetesVersion.V1_28
            defaultCapacity 0

            addNodegroupCapacity (
                "ARMNodeGroup", // ARM-based nodes (Graviton)
                NodegroupOptions(
                    InstanceTypes = [| InstanceType("t4g.medium") |],
                    MinSize = 1.,
                    MaxSize = 5.,
                    DesiredSize = 2.,
                    AmiType = NodegroupAmiType.AL2_ARM_64,
                    Labels = dict [ "arch", "arm64" ]
                )
            )

            addNodegroupCapacity (
                "X86NodeGroup", // x86 nodes
                NodegroupOptions(
                    InstanceTypes = [| InstanceType("t3.medium") |],
                    MinSize = 1.,
                    MaxSize = 5.,
                    DesiredSize = 2.,
                    AmiType = NodegroupAmiType.AL2_X86_64,
                    Labels = dict [ "arch", "amd64" ]
                )
            )
        }

    ()
}

Spot Instances for Cost Optimization

Use Spot Instances for fault-tolerant workloads to save up to 90%.

Best for: - Batch processing - CI/CD pipelines - Stateless applications - Non-critical workloads

stack "SpotEKSStack" {
    description "EKS cluster with Spot instance node group"

    let! spotVpc =
        vpc "SpotVpc" {
            maxAzs 2
            cidr "10.0.0.0/16"
        }

    let spotCluster =
        eksCluster "SpotCluster" {
            vpc spotVpc
            version KubernetesVersion.V1_28
            defaultCapacity 0

            // On-demand nodes for critical workloads
            addNodegroupCapacity (
                "OnDemandNodes",
                NodegroupOptions(
                    InstanceTypes = [| InstanceType("t3.medium") |],
                    MinSize = 1.,
                    MaxSize = 3.,
                    DesiredSize = 2.,
                    Labels = dict [ "capacity-type", "on-demand" ]
                )
            )

            // Spot instance node group
            addNodegroupCapacity (
                "SpotNodes",
                NodegroupOptions(
                    InstanceTypes =
                        [| InstanceType("t3.medium")
                           InstanceType("t3a.medium")
                           InstanceType("t2.medium") |],
                    CapacityType = CapacityType.SPOT,
                    MinSize = 0.,
                    MaxSize = 10.,
                    DesiredSize = 2.,
                    Labels = dict [ "capacity-type", "spot" ]

                )
            )
        }

    ()
}

Security Best Practices

IRSA (IAM Roles for Service Accounts)

Grant Kubernetes pods fine-grained IAM permissions without sharing credentials.

Benefits: - Least-privilege access per pod - No shared credentials - Audit trail via CloudTrail - Automatic credential rotation

stack "IRSAEKSStack" {
    description "EKS cluster with IRSA for pod permissions"

    let! irsaVpc =
        vpc "IRSAVpc" {
            maxAzs 2
            cidr "10.0.0.0/16"
        }

    let appServiceAccount =
        eksCluster "SpotCluster" {
            vpc irsaVpc
            version KubernetesVersion.V1_28
            defaultCapacity 0

            addServiceAccount ("AppServiceAccount", ServiceAccountOptions(Name = "my-app-sa", Namespace = "default"))
        }

    // Create S3 bucket
    let appBucket =
        s3Bucket "app-bucket" {
            versioned true
            encryption Amazon.CDK.AWS.S3.BucketEncryption.S3_MANAGED
        }

    // Grant S3 access to the service account
    //appBucket.Bucket.Value.GrantReadWrite(appServiceAccount) |> ignore

    ()
}

Secrets Encryption with KMS

Enable envelope encryption for Kubernetes secrets at rest.

Security: - Protects sensitive data in etcd - Automatic key rotation - Audit logs via CloudTrail

stack "SecureEKSStack" {
    description "EKS cluster with KMS secrets encryption"

    let! secureVpc =
        vpc "SecureVpc" {
            maxAzs 2
            cidr "10.0.0.0/16"
        }

    // Create KMS key for secrets encryption
    let! secretsKey =
        kmsKey "EKSSecretsKey" {
            description "KMS key for EKS secrets encryption"
            enableKeyRotation
        }

    let secureCluster =
        eksCluster "SecureCluster" {
            vpc secureVpc
            version KubernetesVersion.V1_28
            encryptionKey secretsKey
            endpointAccess EndpointAccess.PRIVATE

            setClusterLogging
                [ ClusterLoggingTypes.API
                  ClusterLoggingTypes.AUDIT
                  ClusterLoggingTypes.AUTHENTICATOR ]
        }

    ()
}

Kubernetes Deployments

Deploy Application Manifests

Apply Kubernetes resources directly from CDK.

    // Deploy nginx application
    appCluster.AddManifest(
        "NginxDeployment",
        dict
            [ "apiVersion", box "apps/v1"
              "kind", box "Deployment"
              "metadata", box (dict [ "name", box "nginx"; "namespace", box "default" ])
              "spec",
              box (
                  dict
                      [ "replicas", box 3
                        "selector", box (dict [ "matchLabels", box (dict [ "app", box "nginx" ]) ])
                        "template",
                        box (
                            dict
                                [ "metadata", box (dict [ "labels", box (dict [ "app", box "nginx" ]) ])
                                  "spec",
                                  box (
                                      dict
                                          [ "containers",
                                            box
                                                [| dict
                                                       [ "name", box "nginx"
                                                         "image", box "nginx:1.25"
                                                         "ports", box [| dict [ "containerPort", box 80 ] |]
                                                         "resources",
                                                         box (
                                                             dict
                                                                 [ "requests",
                                                                   box (
                                                                       dict [ "memory", box "128Mi"; "cpu", box "100m" ]
                                                                   )
                                                                   "limits",
                                                                   box (
                                                                       dict [ "memory", box "256Mi"; "cpu", box "200m" ]
                                                                   ) ]
                                                         ) ] |] ]
                                  ) ]
                        ) ]
              ) ]
    )
    |> ignore

    // Deploy service
    appCluster.AddManifest(
        "NginxService",
        dict
            [ "apiVersion", box "v1"
              "kind", box "Service"
              "metadata", box (dict [ "name", box "nginx-service"; "namespace", box "default" ])
              "spec",
              box (
                  dict
                      [ "type", box "LoadBalancer"
                        "selector", box (dict [ "app", box "nginx" ])
                        "ports", box [| dict [ "port", box 80; "targetPort", box 80; "protocol", box "TCP" ] |] ]
              ) ]
    )
    |> ignore

    ()
}
*)

Install Helm Charts

Install applications using Helm package manager.

stack "HelmChartsStack" {
    description "EKS cluster with Helm chart installations"

    let! helmVpc =
        vpc "HelmVpc" {
            maxAzs 2
            cidr "10.0.0.0/16"
        }

    let helmCluster =
        eksCluster "HelmCluster" {
            vpc helmVpc
            version KubernetesVersion.V1_28

            addHelmChart (
                // Install AWS Load Balancer Controller
                "AWSLoadBalancerController",
                HelmChartOptions(
                    Chart = "aws-load-balancer-controller",
                    Repository = "https://aws.github.io/eks-charts",
                    Namespace = "kube-system",
                    Values =
                        dict
                            [ "clusterName", box "HelmCluster"
                              "serviceAccount.create", box false
                              "serviceAccount.name", box "aws-load-balancer-controller" ]
                )
            )

            addHelmChart (
                // Install metrics-server for HPA
                "MetricsServer",
                HelmChartOptions(
                    Chart = "metrics-server",
                    Repository = "https://kubernetes-sigs.github.io/metrics-server/",
                    Namespace = "kube-system",
                    Values = dict [ "replicas", box 2 ]
                )
            )

            addHelmChart (
                // Install Prometheus for monitoring
                "Prometheus",
                HelmChartOptions(
                    Chart = "kube-prometheus-stack",
                    Repository = "https://prometheus-community.github.io/helm-charts",
                    Namespace = "monitoring",
                    CreateNamespace = true,
                    Values =
                        dict
                            [ "prometheus.prometheusSpec.retention", box "30d"
                              "grafana.enabled", box true ]
                )
            )
        }

    ()
}

Auto Scaling

Cluster Autoscaler

Automatically adjust node group size based on pod resource requests.

stack "AutoScalingEKSStack" {
    description "EKS cluster with autoscaling"

    let! autoScaleVpc =
        vpc "AutoScaleVpc" {
            maxAzs 2
            cidr "10.0.0.0/16"
        }

    let autoScaleCluster =
        eksCluster "AppCluster" {
            vpc autoScaleVpc
            version KubernetesVersion.V1_28

            // Auto-scaling node group
            addNodegroupCapacity (
                "AutoScalingNodes",
                NodegroupOptions(
                    InstanceTypes = [| InstanceType("t3.medium") |],
                    MinSize = 2.,
                    MaxSize = 10.,
                    DesiredSize = 3.,
                    Labels = dict [ "node-group", "autoscaling" ]
                )
            )

            // Install Cluster Autoscaler via Helm
            addHelmChart (
                "ClusterAutoscaler",
                HelmChartOptions(
                    Chart = "cluster-autoscaler",
                    Repository = "https://kubernetes.github.io/autoscaler",
                    Namespace = "kube-system",
                    Values =
                        dict
                            [ "autoDiscovery.clusterName", box "AutoScalingCluster"
                              "awsRegion", box config.Region
                              "rbac.create", box true
                              "rbac.serviceAccount.name", box "cluster-autoscaler" ]
                )
            )

        }

    ()
}

Complete Production Example

stack "ProductionEKSStack" {
    env (
        environment {
            account config.Account
            region config.Region
        }
    )

    description "Production-ready EKS cluster with security and monitoring"
    tags [ "Environment", "Production"; "Project", "K8sCluster"; "ManagedBy", "FsCDK" ]

    // Production VPC with high availability
    let! prodVpc =
        vpc "ProductionVPC" {
            maxAzs 3
            natGateways 3 // One NAT gateway per AZ for HA
            cidr "10.0.0.0/16"
        }

    // KMS key for secrets encryption

    let! eksKey =
        kmsKey "ProdEKSKey" {
            description "Production EKS secrets encryption key"
            alias "alias/prod-eks-secrets"
            enableKeyRotation
        }

    // Production EKS cluster
    let prodCluster =
        eksCluster "ProductionCluster" {
            vpc prodVpc
            version KubernetesVersion.V1_28
            defaultCapacity 0
            endpointAccess EndpointAccess.PRIVATE // Private API for security
            encryptionKey eksKey

            setClusterLogging
                [ ClusterLoggingTypes.API
                  ClusterLoggingTypes.AUDIT
                  ClusterLoggingTypes.AUTHENTICATOR
                  ClusterLoggingTypes.CONTROLLER_MANAGER
                  ClusterLoggingTypes.SCHEDULER ]

            // On-demand node group for critical workloads
            addNodegroupCapacity (
                "CriticalNodes",
                NodegroupOptions(
                    InstanceTypes = [| InstanceType("t3.large") |],
                    MinSize = 3.,
                    MaxSize = 10.,
                    DesiredSize = 5.,
                    Labels = dict [ "workload-type", "critical"; "capacity-type", "on-demand" ],
                    Tags = dict [ "Name", "eks-critical-node"; "Environment", "production" ]
                )
            )

            // Spot instance node group for batch workloads
            addNodegroupCapacity (
                "BatchNodes",
                NodegroupOptions(
                    InstanceTypes =
                        [| InstanceType("t3.large")
                           InstanceType("t3a.large")
                           InstanceType("t3.xlarge") |],
                    CapacityType = CapacityType.SPOT,
                    MinSize = 0.,
                    MaxSize = 20.,
                    DesiredSize = 3.,
                    Labels = dict [ "workload-type", "batch"; "capacity-type", "spot" ]
                )
            )

            // Install essential add-ons
            addHelmChart (
                "MetricsServer",
                HelmChartOptions(
                    Chart = "metrics-server",
                    Repository = "https://kubernetes-sigs.github.io/metrics-server/",
                    Namespace = "kube-system",
                    Values =
                        dict
                            [ "replicas", box 3
                              "resources.requests.cpu", box "100m"
                              "resources.requests.memory", box "200Mi" ]
                )
            )

            addHelmChart (
                "ClusterAutoscaler",
                HelmChartOptions(
                    Chart = "cluster-autoscaler",
                    Repository = "https://kubernetes.github.io/autoscaler",
                    Namespace = "kube-system",
                    Values =
                        dict
                            [ "autoDiscovery.clusterName", box "ProductionCluster"
                              "awsRegion", box config.Region
                              "extraArgs.scale-down-delay-after-add", box "10m"
                              "extraArgs.skip-nodes-with-local-storage", box false ]
                )
            )

            // Monitoring stack
            addHelmChart (
                "PrometheusStack",
                HelmChartOptions(
                    Chart = "kube-prometheus-stack",
                    Repository = "https://prometheus-community.github.io/helm-charts",
                    Namespace = "monitoring",
                    CreateNamespace = true,
                    Values =
                        dict
                            [ "prometheus.prometheusSpec.retention", box "30d"
                              "prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage",
                              box "50Gi"
                              "grafana.enabled", box true
                              "grafana.adminPassword", box "ChangeMeInProduction!"
                              "alertmanager.enabled", box true ]
                )
            )

        }

    ()
}

Access Control

Configure kubectl Access

After deployment, configure kubectl to access your cluster:

# Update kubeconfig
aws eks update-kubeconfig --name ProductionCluster --region us-east-1

# Verify access
kubectl get nodes
kubectl get pods --all-namespaces

# View cluster info
kubectl cluster-info

Grant IAM Users/Roles Access

Grant additional AWS users or roles access to the cluster:

//let developerRole =
//    Role.FromRoleArn(this, "DeveloperRole", "arn:aws:iam::123456789012:role/DeveloperRole")

// prodCluster.AwsAuth.AddRoleMapping(developerRole, AwsAuthMapping(
//     Groups = [| "developers" |],
//     Username = "developer"
// )) |> ignore

Cost Optimization

EKS vs ECS Comparison

Feature

ECS

EKS

Control Plane Cost

Free

\(0.10/hour (\)73/month)

Compute Cost

EC2/Fargate pricing

EC2/Fargate pricing

Learning Curve

Lower

Higher

Portability

AWS-only

Multi-cloud

Ecosystem

AWS-focused

Kubernetes ecosystem

Best For

Simple containers

Complex orchestration

Cost Savings Strategies

  1. Use Fargate for variable workloads: Pay only for pod resources
  2. Spot Instances for batch jobs: Save up to 90%
  3. Graviton (ARM) instances: 20% better price/performance
  4. Cluster Autoscaler: Scale down during low usage
  5. Reserved Instances: Up to 72% savings for baseline capacity

Example Monthly Costs

Small Cluster: - Control plane: \(73 - 3 t3.medium nodes (on-demand): ~\)90 - Total: ~$163/month

Production Cluster: - Control plane: \(73 - 5 t3.large nodes (on-demand): ~\)305 - 10 t3.large spot nodes (average): ~\(60 - Total: ~\)438/month

Deployment

# Synthesize CloudFormation template
cdk synth ProductionEKSStack

# Deploy to AWS (takes 15-20 minutes)
cdk deploy ProductionEKSStack

# Configure kubectl
aws eks update-kubeconfig --name ProductionCluster --region <region>

# Verify cluster
kubectl get nodes

# Destroy resources when done
cdk destroy ProductionEKSStack

Troubleshooting

Common Issues

Issue: Pods stuck in Pending state

# Check pod events
kubectl describe pod <pod-name>

# Common causes:
# - Insufficient node capacity (add more nodes)
# - Resource requests too high (adjust limits)
# - Node selector mismatch (check labels)

Issue: Cannot connect to cluster

# Verify AWS credentials
aws sts get-caller-identity

# Update kubeconfig
aws eks update-kubeconfig --name <cluster-name>

# Check endpoint access
# Ensure EndpointAccess allows your connection source

Next Steps

Resources

namespace Amazon
namespace Amazon.CDK
namespace Amazon.CDK.AWS
namespace Amazon.CDK.AWS.EC2
namespace Amazon.CDK.AWS.EKS
namespace Amazon.CDK.AWS.IAM
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 Eks-kubernetes
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: 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>
custom operation: tags ((string * string) list) Calls StackBuilder.Tags
<summary>Adds tags to the stack.</summary>
<param name="config">The current stack configuration.</param>
<param name="tags">A list of key-value pairs for tagging.</param>
<code lang="fsharp"> stack "MyStack" { tags [ "Environment", "Production"; "Team", "DevOps" ] } </code>
val clusterVpc: 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 cluster: EKSClusterSpec
val eksCluster: name: string -> EKSClusterBuilder
<summary>Creates an EKS cluster with AWS best practices.</summary>
<param name="name">The cluster name.</param>
<code lang="fsharp"> eksCluster "MyCluster" { vpc myVpc version KubernetesVersion.V1_28 defaultCapacity 3 } </code>
custom operation: vpc (IVpc) Calls EKSClusterBuilder.Vpc
<summary>Sets the VPC for the cluster.</summary>
custom operation: version (KubernetesVersion) Calls EKSClusterBuilder.Version
<summary>Sets the Kubernetes version.</summary>
type KubernetesVersion = inherit DeputyBase static member Of: version: string -> KubernetesVersion member Version: string static member V1_14: KubernetesVersion static member V1_15: KubernetesVersion static member V1_16: KubernetesVersion static member V1_17: KubernetesVersion static member V1_18: KubernetesVersion static member V1_19: KubernetesVersion static member V1_20: KubernetesVersion ...
property KubernetesVersion.V1_28: KubernetesVersion with get
custom operation: defaultCapacity (int) Calls EKSClusterBuilder.DefaultCapacity
<summary>Sets the default node capacity.</summary>
custom operation: endpointAccess (EndpointAccess) Calls EKSClusterBuilder.EndpointAccess
<summary>Sets the endpoint access mode.</summary>
type EndpointAccess = inherit DeputyBase member OnlyFrom: [<ParamArray>] cidr: string array -> EndpointAccess static member PRIVATE: EndpointAccess static member PUBLIC: EndpointAccess static member PUBLIC_AND_PRIVATE: EndpointAccess
property EndpointAccess.PUBLIC_AND_PRIVATE: EndpointAccess with get
custom operation: setClusterLogging (ClusterLoggingTypes list) Calls EKSClusterBuilder.SetClusterLogging
<summary>Set cluster logging. Default: API/AUDIT/AUTHENTICATOR/CONTROLLER_MANAGER/SCHEDULER</summary>
[<Struct>] type ClusterLoggingTypes = | API = 0 | AUDIT = 1 | AUTHENTICATOR = 2 | CONTROLLER_MANAGER = 3 | SCHEDULER = 4
field ClusterLoggingTypes.API: ClusterLoggingTypes = 0
field ClusterLoggingTypes.AUDIT: ClusterLoggingTypes = 1
field ClusterLoggingTypes.AUTHENTICATOR: ClusterLoggingTypes = 2
field ClusterLoggingTypes.CONTROLLER_MANAGER: ClusterLoggingTypes = 3
field ClusterLoggingTypes.SCHEDULER: ClusterLoggingTypes = 4
custom operation: addNodegroupCapacity (string * NodegroupOptions) Calls EKSClusterBuilder.AddNodegroupCapacity
Multiple items
type NodegroupOptions = interface INodegroupOptions new: unit -> unit member AmiType: Nullable<NodegroupAmiType> member CapacityType: Nullable<CapacityType> member DesiredSize: Nullable<float> member DiskSize: Nullable<float> member EnableNodeAutoRepair: Nullable<bool> member ForceUpdate: Nullable<bool> member InstanceTypes: InstanceType array member Labels: IDictionary<string,string> ...

--------------------
NodegroupOptions() : NodegroupOptions
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.MEDIUM: InstanceSize = 3
val fargateVpc: IVpc
val fargateCluster: EKSClusterSpec
custom operation: addFargateProfile (string * FargateProfileOptions) Calls EKSClusterBuilder.AddFargateProfile
Multiple items
type FargateProfileOptions = interface IFargateProfileOptions new: unit -> unit member FargateProfileName: string member PodExecutionRole: IRole member Selectors: ISelector array member SubnetSelection: ISubnetSelection member Vpc: IVpc

--------------------
FargateProfileOptions() : FargateProfileOptions
Multiple items
type Selector = interface ISelector new: unit -> unit member Labels: IDictionary<string,string> member Namespace: string

--------------------
Selector() : Selector
val dict: keyValuePairs: ('Key * 'Value) seq -> System.Collections.Generic.IDictionary<'Key,'Value> (requires equality)
val multiArchVpc: IVpc
val multiArchCluster: EKSClusterSpec
[<Struct>] type NodegroupAmiType = | AL2_X86_64 = 0 | AL2_X86_64_GPU = 1 | AL2_ARM_64 = 2 | BOTTLEROCKET_ARM_64 = 3 | BOTTLEROCKET_X86_64 = 4 | BOTTLEROCKET_ARM_64_NVIDIA = 5 | BOTTLEROCKET_X86_64_NVIDIA = 6 | BOTTLEROCKET_ARM_64_FIPS = 7 | BOTTLEROCKET_X86_64_FIPS = 8 | WINDOWS_CORE_2019_X86_64 = 9 ...
field NodegroupAmiType.AL2_ARM_64: NodegroupAmiType = 2
field NodegroupAmiType.AL2_X86_64: NodegroupAmiType = 0
val spotVpc: IVpc
val spotCluster: EKSClusterSpec
[<Struct>] type CapacityType = | SPOT = 0 | ON_DEMAND = 1 | CAPACITY_BLOCK = 2
field CapacityType.SPOT: CapacityType = 0
val irsaVpc: IVpc
val appServiceAccount: EKSClusterSpec
custom operation: addServiceAccount (string * ServiceAccountOptions) Calls EKSClusterBuilder.AddServiceAccount
Multiple items
type ServiceAccountOptions = interface IServiceAccountOptions new: unit -> unit member Annotations: IDictionary<string,string> member IdentityType: Nullable<IdentityType> member Labels: IDictionary<string,string> member Name: string member Namespace: string

--------------------
ServiceAccountOptions() : ServiceAccountOptions
val appBucket: BucketSpec
val s3Bucket: name: string -> BucketBuilder
<summary> Creates a new S3 bucket builder with secure defaults. Example: s3Bucket "my-bucket" { versioned true } Alias for bucket builder. </summary>
custom operation: versioned (bool) Calls BucketBuilder.Versioned
<summary> Enables or disables versioning for the S3 bucket. **Security Best Practice:** Enable versioning for: - Critical data that requires audit trails - Data subject to compliance requirements (HIPAA, SOC2, etc.) - Production buckets storing business data **Cost Consideration:** Versioning stores all versions of objects, increasing storage costs. Only disable for: - Temporary/cache buckets - Build artifacts with short lifecycle - Development/testing buckets **Default:** false (opt-in for cost optimization) </summary>
<param name="value">True to enable versioning, false to disable.</param>
<param name="config">The current bucket configuration.</param>
<code lang="fsharp"> bucket "production-data" { versioned true // Enable for production } bucket "cache-bucket" { versioned false // Disable for temp data } </code>
custom operation: encryption (AWS.S3.BucketEncryption) Calls BucketBuilder.Encryption
namespace Amazon.CDK.AWS.S3
[<Struct>] type BucketEncryption = | UNENCRYPTED = 0 | KMS_MANAGED = 1 | S3_MANAGED = 2 | KMS = 3 | DSSE_MANAGED = 4 | DSSE = 5
field AWS.S3.BucketEncryption.S3_MANAGED: AWS.S3.BucketEncryption = 2
val secureVpc: IVpc
val secretsKey: AWS.KMS.IKey
val kmsKey: name: string -> KMSKeyBuilder
<summary> Creates a new KMS key builder with secure defaults. Example: kmsKey "my-encryption-key" { description "Encrypts sensitive data" } </summary>
custom operation: description (string) Calls KMSKeyBuilder.Description
<summary>Sets the description for the KMS key.</summary>
<param name="description">Human-readable description.</param>
<code lang="fsharp"> kmsKey "my-key" { description "Encryption key for S3 bucket data" } </code>
custom operation: enableKeyRotation Calls KMSKeyBuilder.EnableKeyRotation
<summary>Enables automatic key rotation (recommended for security).</summary>
<code lang="fsharp"> kmsKey "my-key" { enableKeyRotation } </code>
val secureCluster: EKSClusterSpec
custom operation: encryptionKey (AWS.KMS.IKey) Calls EKSClusterBuilder.SecretsEncryptionKey
<summary>Sets the KMS key used for secrets encryption.</summary>
property EndpointAccess.PRIVATE: EndpointAccess with get
val helmVpc: IVpc
val helmCluster: EKSClusterSpec
custom operation: addHelmChart (string * HelmChartOptions) Calls EKSClusterBuilder.AddHelmChart
Multiple items
type HelmChartOptions = interface IHelmChartOptions new: unit -> unit member Atomic: Nullable<bool> member Chart: string member ChartAsset: Asset member CreateNamespace: Nullable<bool> member Namespace: string member Release: string member Repository: string member SkipCrds: Nullable<bool> ...

--------------------
HelmChartOptions() : HelmChartOptions
val box: value: 'T -> obj
val autoScaleVpc: IVpc
val autoScaleCluster: EKSClusterSpec
val prodVpc: IVpc
val eksKey: AWS.KMS.IKey
custom operation: alias (string) Calls KMSKeyBuilder.Alias
<summary>Sets an alias for the KMS key (e.g., "alias/my-app-key").</summary>
<param name="alias">The key alias.</param>
<code lang="fsharp"> kmsKey "my-key" { alias "alias/my-app-key" } </code>
val prodCluster: EKSClusterSpec
type Tags = inherit DeputyBase member Add: key: string * value: string * ?props: ITagProps -> unit member Remove: key: string * ?props: ITagProps -> unit static member Of: scope: IConstruct -> Tags

Type something to start searching.