1. Configuring persistent storage in EKS with Amazon EFS for data analysis

    TypeScript

    To accomplish setting up persistent storage in Amazon EKS using Amazon EFS for data analysis, we need to configure several components:

    1. EKS Cluster: We need an EKS cluster to manage our Kubernetes resources. This will involve creating an EKS Cluster resource.
    2. IAM Role for EKS: This role is used by the EKS service to make AWS API calls on your behalf.
    3. EFS File System and Mount Targets: A central location for storage that can be accessed by multiple EKS pods across different availability zones.
    4. PersistentVolume (PV) and PersistentVolumeClaim (PVC): Kubernetes resources that allow a pod to use persistent storage. The PV is a piece of storage in the cluster, while PVC is a request for storage by a user.

    The following Pulumi program (written in TypeScript) sets up these components, assuming that you have AWS access and your Pulumi environment already set up.

    First, we will explain why we use certain resources:

    • aws.eks.Cluster: Provisions an EKS cluster.
    • aws.iam.Role: Creates an IAM role that EKS will assume for AWS services interaction.
    • aws.iam.RolePolicyAttachment: Attaches a policy to the role to grant required permissions.
    • aws.efs.FileSystem: Creates a new EFS file system for persistent storage.
    • aws.efs.AccessPoint: Creates an access point that acts as an application-specific entry point to an EFS file system.
    • kubernetes.core.v1.PersistentVolume: Defines persistent storage (backed by EFS) in Kubernetes.
    • kubernetes.core.v1.PersistentVolumeClaim: Allows pods to request a specific size and access mode for PV.

    Let's start with the Pulumi program to create these resources:

    import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; import * as k8s from "@pulumi/kubernetes"; import * as eks from "@pulumi/eks"; // Create an EKS cluster const cluster = new eks.Cluster("my-eks-cluster", { instanceType: "t2.medium", desiredCapacity: 2, minSize: 1, maxSize: 2, storageClasses: "gp2", // Setting the default storage class to gp2 (General Purpose SSD) deployDashboard: false, // No need to deploy the Kubernetes dashboard }); // IAM role for EKS const eksRole = new aws.iam.Role("eksRole", { assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({ Service: "eks.amazonaws.com" }), }); // Attaching AmazonEKSWorkerNodePolicy to the IAM role new aws.iam.RolePolicyAttachment("eksWorkerNodePolicyAttachment", { policyArn: "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy", role: eksRole.name, }); // Attaching AmazonEKS_CNI_Policy to the IAM role new aws.iam.RolePolicyAttachment("eksCniPolicyAttachment", { policyArn: "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy", role: eksRole.name, }); // Attaching AmazonEC2ContainerRegistryReadOnly to the IAM role new aws.iam.RolePolicyAttachment("eksRegistryPolicyAttachment", { policyArn: "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly", role: eksRole.name, }); // Create an EFS File System const fileSystem = new aws.efs.FileSystem("my-efs", {}); // Create an EFS Access Point const accessPoint = new aws.efs.AccessPoint("my-access-point", { fileSystemId: fileSystem.id, }); // Setup the K8s provider const k8sProvider = new k8s.Provider("k8sProvider", { kubeconfig: cluster.kubeconfig.apply(JSON.stringify), }); // Persistent Volume that uses the EFS file system const persistentVolume = new k8s.core.v1.PersistentVolume("my-pv", { spec: { capacity: { storage: "5Gi", // Specify the size of storage }, accessModes: ["ReadWriteMany"], // EFS supports ReadWriteMany access mode persistentVolumeReclaimPolicy: "Retain", // Set to 'Retain' or 'Delete' storageClassName: "efs-sc", // Storage class name, can be any string mountOptions: ["tls"], // Amazon EFS supports encrypting data in transit csi: { driver: "efs.csi.aws.com", // EFS CSI driver volumeHandle: fileSystem.arn, // Reference to the EFS ARN }, }, }, { provider: k8sProvider }); // Persistent Volume Claim which requests the Persistent Volume const persistentVolumeClaim = new k8s.core.v1.PersistentVolumeClaim("my-pvc", { spec: { accessModes: ["ReadWriteMany"], // Should match the PV's access modes resources: { requests: { storage: "5Gi", // Should match or be less than the PV's size }, }, storageClassName: "efs-sc", // Should match the PV's storage class name }, }, { provider: k8sProvider }); // Expose the cluster's kubeconfig export const kubeconfig = cluster.kubeconfig;

    This program sets up an EKS cluster and configures persistent storage with EFS, which can be used for storing and analyzing data in a consistent and scalable way across multiple pods. By creating a PersistentVolume that references the EFS filesystem and a PersistentVolumeClaim to claim storage from that volume, we allow our Kubernetes pods to use the EFS as a common data layer.

    Note that persistent storage with EFS allows pods to access shared storage from any node within the EKS cluster, providing a way to persist data beyond the lifecycle of any single pod, thus suitable for data analysis workloads which require access to shared, persistent data.

    Remember to follow AWS and Pulumi