CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-pulumi--kubernetes

A comprehensive Pulumi resource provider for creating and managing Kubernetes resources and workloads in a running cluster

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

storage-resources.mddocs/

Storage Resources

The Storage API groups provide resources for dynamic volume provisioning, storage management, and Container Storage Interface (CSI) driver integration across multiple API versions.

Package Import

import { storage } from "@pulumi/kubernetes";
import * as k8s from "@pulumi/kubernetes";

// Direct storage imports
import { StorageClass, VolumeAttachment, CSIDriver } from "@pulumi/kubernetes/storage/v1";

StorageClass (storage/v1)

StorageClass provides a way for administrators to describe the "classes" of storage they offer with dynamic provisioning.

class StorageClass extends pulumi.CustomResource {
    constructor(name: string, args?: StorageClassArgs, opts?: pulumi.CustomResourceOptions)
    
    public static get(name: string, id: pulumi.Input<pulumi.ID>, opts?: pulumi.CustomResourceOptions): StorageClass
    
    // Output properties
    public readonly apiVersion!: pulumi.Output<"storage.k8s.io/v1">;
    public readonly kind!: pulumi.Output<"StorageClass">;
    public readonly metadata!: pulumi.Output<outputs.meta.v1.ObjectMeta>;
    public readonly provisioner!: pulumi.Output<string>;
    public readonly parameters!: pulumi.Output<{[key: string]: string}>;
    public readonly reclaimPolicy!: pulumi.Output<string>;
    public readonly allowVolumeExpansion!: pulumi.Output<boolean>;
    public readonly volumeBindingMode!: pulumi.Output<string>;
    public readonly allowedTopologies!: pulumi.Output<outputs.core.v1.TopologySelectorTerm[]>;
    public readonly mountOptions!: pulumi.Output<string[]>;
}

interface StorageClassArgs {
    apiVersion?: pulumi.Input<"storage.k8s.io/v1">;
    kind?: pulumi.Input<"StorageClass">;
    metadata?: pulumi.Input<inputs.meta.v1.ObjectMeta>;
    provisioner: pulumi.Input<string>;
    parameters?: pulumi.Input<{[key: string]: pulumi.Input<string>}>;
    reclaimPolicy?: pulumi.Input<"Delete" | "Retain">;
    allowVolumeExpansion?: pulumi.Input<boolean>;
    volumeBindingMode?: pulumi.Input<"Immediate" | "WaitForFirstConsumer">;
    allowedTopologies?: pulumi.Input<pulumi.Input<inputs.core.v1.TopologySelectorTerm>[]>;
    mountOptions?: pulumi.Input<pulumi.Input<string>[]>;
}

Volume Binding Modes

// Volume binding mode types
type VolumeBindingMode = 
    | "Immediate"              // Volume binding and provisioning happens immediately
    | "WaitForFirstConsumer";  // Volume binding and provisioning delayed until Pod using PVC is created

// Reclaim policy types
type ReclaimPolicy = 
    | "Delete"  // Volume will be deleted when PVC is deleted
    | "Retain"; // Volume will be retained when PVC is deleted

StorageClass Usage Examples

// AWS EBS GP3 Storage Class
const ebsGp3StorageClass = new k8s.storage.v1.StorageClass("ebs-gp3", {
    metadata: {
        name: "ebs-gp3",
        annotations: {
            "storageclass.kubernetes.io/is-default-class": "true",
        },
    },
    provisioner: "ebs.csi.aws.com",
    parameters: {
        type: "gp3",
        iops: "3000",
        throughput: "125",
        encrypted: "true",
    },
    reclaimPolicy: "Delete",
    allowVolumeExpansion: true,
    volumeBindingMode: "WaitForFirstConsumer",
});

// High-performance SSD Storage Class
const fastSsdStorageClass = new k8s.storage.v1.StorageClass("fast-ssd", {
    metadata: {
        name: "fast-ssd",
    },
    provisioner: "ebs.csi.aws.com",
    parameters: {
        type: "io2",
        iops: "10000",
        encrypted: "true",
    },
    reclaimPolicy: "Delete",
    allowVolumeExpansion: true,
    volumeBindingMode: "Immediate",
    allowedTopologies: [{
        matchLabelExpressions: [{
            key: "topology.ebs.csi.aws.com/zone",
            values: ["us-west-2a", "us-west-2b"],
        }],
    }],
});

// Google Cloud Persistent Disk Storage Class
const gceStorageClass = new k8s.storage.v1.StorageClass("gce-ssd", {
    metadata: {
        name: "gce-ssd",
    },
    provisioner: "pd.csi.storage.gke.io",
    parameters: {
        type: "pd-ssd",
        replication: "regional-pd",
    },
    reclaimPolicy: "Delete",
    allowVolumeExpansion: true,
    volumeBindingMode: "WaitForFirstConsumer",
});

// Azure Disk Storage Class
const azureDiskStorageClass = new k8s.storage.v1.StorageClass("azure-premium", {
    metadata: {
        name: "azure-premium",
    },
    provisioner: "disk.csi.azure.com",
    parameters: {
        skuName: "Premium_LRS",
        cachingmode: "ReadOnly",
    },
    reclaimPolicy: "Delete",
    allowVolumeExpansion: true,
    volumeBindingMode: "WaitForFirstConsumer",
});

// Local Storage Class for high-performance workloads
const localStorageClass = new k8s.storage.v1.StorageClass("local-storage", {
    metadata: {
        name: "local-storage",
    },
    provisioner: "kubernetes.io/no-provisioner",
    reclaimPolicy: "Delete",
    volumeBindingMode: "WaitForFirstConsumer",
    allowedTopologies: [{
        matchLabelExpressions: [{
            key: "kubernetes.io/hostname",
            values: ["worker-1", "worker-2", "worker-3"],
        }],
    }],
});

VolumeAttachment (storage/v1)

VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.

class VolumeAttachment extends pulumi.CustomResource {
    constructor(name: string, args?: VolumeAttachmentArgs, opts?: pulumi.CustomResourceOptions)
    
    public static get(name: string, id: pulumi.Input<pulumi.ID>, opts?: pulumi.CustomResourceOptions): VolumeAttachment
    
    // Output properties
    public readonly apiVersion!: pulumi.Output<"storage.k8s.io/v1">;
    public readonly kind!: pulumi.Output<"VolumeAttachment">;
    public readonly metadata!: pulumi.Output<outputs.meta.v1.ObjectMeta>;
    public readonly spec!: pulumi.Output<outputs.storage.v1.VolumeAttachmentSpec>;
    public readonly status!: pulumi.Output<outputs.storage.v1.VolumeAttachmentStatus>;
}

interface VolumeAttachmentArgs {
    apiVersion?: pulumi.Input<"storage.k8s.io/v1">;
    kind?: pulumi.Input<"VolumeAttachment">;
    metadata?: pulumi.Input<inputs.meta.v1.ObjectMeta>;
    spec: pulumi.Input<inputs.storage.v1.VolumeAttachmentSpec>;
}

CSIDriver (storage/v1)

CSIDriver captures information about a Container Storage Interface (CSI) volume driver deployed on the cluster.

class CSIDriver extends pulumi.CustomResource {
    constructor(name: string, args?: CSIDriverArgs, opts?: pulumi.CustomResourceOptions)
    
    public static get(name: string, id: pulumi.Input<pulumi.ID>, opts?: pulumi.CustomResourceOptions): CSIDriver
    
    // Output properties
    public readonly apiVersion!: pulumi.Output<"storage.k8s.io/v1">;
    public readonly kind!: pulumi.Output<"CSIDriver">;
    public readonly metadata!: pulumi.Output<outputs.meta.v1.ObjectMeta>;
    public readonly spec!: pulumi.Output<outputs.storage.v1.CSIDriverSpec>;
}

interface CSIDriverArgs {
    apiVersion?: pulumi.Input<"storage.k8s.io/v1">;
    kind?: pulumi.Input<"CSIDriver">;
    metadata?: pulumi.Input<inputs.meta.v1.ObjectMeta>;
    spec?: pulumi.Input<inputs.storage.v1.CSIDriverSpec>;
}

CSIDriver Usage Examples

// AWS EBS CSI Driver
const ebsCSIDriver = new k8s.storage.v1.CSIDriver("ebs-csi-driver", {
    metadata: {
        name: "ebs.csi.aws.com",
    },
    spec: {
        attachRequired: true,
        podInfoOnMount: false,
        volumeLifecycleModes: ["Persistent"],
        storageCapacity: true,
        fsGroupPolicy: "ReadWriteOnceWithFSType",
    },
});

// Azure Disk CSI Driver
const azureDiskCSIDriver = new k8s.storage.v1.CSIDriver("azure-disk-csi", {
    metadata: {
        name: "disk.csi.azure.com",
    },
    spec: {
        attachRequired: true,
        podInfoOnMount: false,
        volumeLifecycleModes: ["Persistent"],
        storageCapacity: true,
    },
});

// Custom CSI Driver
const customCSIDriver = new k8s.storage.v1.CSIDriver("custom-csi", {
    metadata: {
        name: "custom.csi.example.com",
    },
    spec: {
        attachRequired: true,
        podInfoOnMount: true,
        volumeLifecycleModes: ["Persistent", "Ephemeral"],
        storageCapacity: false,
        fsGroupPolicy: "File",
        tokenRequests: [{
            audience: "custom-storage-service",
            expirationSeconds: 3600,
        }],
    },
});

CSINode (storage/v1)

CSINode holds information about all CSI drivers installed on a node.

class CSINode extends pulumi.CustomResource {
    constructor(name: string, args?: CSINodeArgs, opts?: pulumi.CustomResourceOptions)
    
    public static get(name: string, id: pulumi.Input<pulumi.ID>, opts?: pulumi.CustomResourceOptions): CSINode
    
    // Output properties
    public readonly apiVersion!: pulumi.Output<"storage.k8s.io/v1">;
    public readonly kind!: pulumi.Output<"CSINode">;
    public readonly metadata!: pulumi.Output<outputs.meta.v1.ObjectMeta>;
    public readonly spec!: pulumi.Output<outputs.storage.v1.CSINodeSpec>;
}

interface CSINodeArgs {
    apiVersion?: pulumi.Input<"storage.k8s.io/v1">;
    kind?: pulumi.Input<"CSINode">;
    metadata?: pulumi.Input<inputs.meta.v1.ObjectMeta>;
    spec: pulumi.Input<inputs.storage.v1.CSINodeSpec>;
}

CSIStorageCapacity (storage/v1)

CSIStorageCapacity stores the result of one CSI GetCapacity call.

class CSIStorageCapacity extends pulumi.CustomResource {
    constructor(name: string, args?: CSIStorageCapacityArgs, opts?: pulumi.CustomResourceOptions)
    
    public static get(name: string, id: pulumi.Input<pulumi.ID>, opts?: pulumi.CustomResourceOptions): CSIStorageCapacity
    
    // Output properties
    public readonly apiVersion!: pulumi.Output<"storage.k8s.io/v1">;
    public readonly kind!: pulumi.Output<"CSIStorageCapacity">;
    public readonly metadata!: pulumi.Output<outputs.meta.v1.ObjectMeta>;
    public readonly nodeTopology!: pulumi.Output<outputs.meta.v1.LabelSelector>;
    public readonly storageClassName!: pulumi.Output<string>;
    public readonly capacity!: pulumi.Output<string>;
    public readonly maximumVolumeSize!: pulumi.Output<string>;
}

interface CSIStorageCapacityArgs {
    apiVersion?: pulumi.Input<"storage.k8s.io/v1">;
    kind?: pulumi.Input<"CSIStorageCapacity">;
    metadata?: pulumi.Input<inputs.meta.v1.ObjectMeta>;
    nodeTopology?: pulumi.Input<inputs.meta.v1.LabelSelector>;
    storageClassName?: pulumi.Input<string>;
    capacity?: pulumi.Input<string>;
    maximumVolumeSize?: pulumi.Input<string>;
}

Alpha and Beta Storage Resources

VolumeAttributesClass (storage/v1alpha1)

VolumeAttributesClass represents a specification of mutable volume attributes defined by the CSI driver.

class VolumeAttributesClass extends pulumi.CustomResource {
    constructor(name: string, args?: VolumeAttributesClassArgs, opts?: pulumi.CustomResourceOptions)
    
    // Output properties
    public readonly apiVersion!: pulumi.Output<"storage.k8s.io/v1alpha1">;
    public readonly kind!: pulumi.Output<"VolumeAttributesClass">;
    public readonly metadata!: pulumi.Output<outputs.meta.v1.ObjectMeta>;
    public readonly driverName!: pulumi.Output<string>;
    public readonly parameters!: pulumi.Output<{[key: string]: string}>;
}

Complete Storage Setup Examples

Database with Persistent Storage

// Storage class for database workloads
const dbStorageClass = new k8s.storage.v1.StorageClass("db-storage", {
    metadata: {
        name: "database-ssd",
    },
    provisioner: "ebs.csi.aws.com",
    parameters: {
        type: "io2",
        iops: "5000",
        encrypted: "true",
        fsType: "ext4",
    },
    reclaimPolicy: "Retain", // Don't delete data accidentally
    allowVolumeExpansion: true,
    volumeBindingMode: "WaitForFirstConsumer",
});

// PersistentVolumeClaim using the storage class
const dbPVC = new k8s.core.v1.PersistentVolumeClaim("postgres-data", {
    spec: {
        accessModes: ["ReadWriteOnce"],
        storageClassName: "database-ssd",
        resources: {
            requests: {
                storage: "100Gi",
            },
        },
    },
});

// StatefulSet using the PVC
const postgresDB = new k8s.apps.v1.StatefulSet("postgres", {
    spec: {
        serviceName: "postgres",
        replicas: 1,
        selector: {
            matchLabels: {
                app: "postgres",
            },
        },
        template: {
            metadata: {
                labels: {
                    app: "postgres",
                },
            },
            spec: {
                containers: [{
                    name: "postgres",
                    image: "postgres:14",
                    env: [{
                        name: "POSTGRES_PASSWORD",
                        valueFrom: {
                            secretKeyRef: {
                                name: "postgres-secret",
                                key: "password",
                            },
                        },
                    }],
                    volumeMounts: [{
                        name: "postgres-data",
                        mountPath: "/var/lib/postgresql/data",
                    }],
                    ports: [{
                        containerPort: 5432,
                    }],
                }],
                volumes: [{
                    name: "postgres-data",
                    persistentVolumeClaim: {
                        claimName: dbPVC.metadata.name,
                    },
                }],
            },
        },
    },
});

Multi-Tier Storage Setup

// Fast storage for cache layer
const cacheStorageClass = new k8s.storage.v1.StorageClass("cache-nvme", {
    metadata: {
        name: "cache-nvme",
    },
    provisioner: "ebs.csi.aws.com",
    parameters: {
        type: "gp3",
        iops: "16000",
        throughput: "1000",
    },
    reclaimPolicy: "Delete",
    allowVolumeExpansion: true,
    volumeBindingMode: "Immediate",
});

// Standard storage for application data
const standardStorageClass = new k8s.storage.v1.StorageClass("standard-ssd", {
    metadata: {
        name: "standard-ssd",
    },
    provisioner: "ebs.csi.aws.com",
    parameters: {
        type: "gp3",
        iops: "3000",
    },
    reclaimPolicy: "Delete",
    allowVolumeExpansion: true,
    volumeBindingMode: "WaitForFirstConsumer",
});

// Archive storage for backups
const archiveStorageClass = new k8s.storage.v1.StorageClass("archive-storage", {
    metadata: {
        name: "archive-storage",
    },
    provisioner: "ebs.csi.aws.com",
    parameters: {
        type: "sc1", // Cold HDD
    },
    reclaimPolicy: "Retain",
    allowVolumeExpansion: true,
    volumeBindingMode: "WaitForFirstConsumer",
});

CSI Driver Deployment

// CSI Driver for custom storage solution
const customStorageCSIDriver = new k8s.storage.v1.CSIDriver("custom-storage", {
    metadata: {
        name: "storage.example.com",
    },
    spec: {
        attachRequired: true,
        podInfoOnMount: true,
        volumeLifecycleModes: ["Persistent", "Ephemeral"],
        storageCapacity: true,
        fsGroupPolicy: "ReadWriteOnceWithFSType",
        tokenRequests: [{
            audience: "storage.example.com",
            expirationSeconds: 3600,
        }],
    },
});

// Storage class using custom CSI driver
const customStorageClass = new k8s.storage.v1.StorageClass("custom-fast", {
    metadata: {
        name: "custom-fast",
    },
    provisioner: "storage.example.com",
    parameters: {
        tier: "premium",
        encryption: "aes-256",
        replication: "3",
    },
    reclaimPolicy: "Delete",
    allowVolumeExpansion: true,
    volumeBindingMode: "WaitForFirstConsumer",
});

Storage Monitoring and Management

Storage Capacity Tracking

// CSI Storage Capacity for monitoring available storage
const storageCapacity = new k8s.storage.v1.CSIStorageCapacity("node1-capacity", {
    metadata: {
        name: "ebs-capacity-us-west-2a",
        namespace: "kube-system",
    },
    nodeTopology: {
        matchLabels: {
            "topology.ebs.csi.aws.com/zone": "us-west-2a",
        },
    },
    storageClassName: "ebs-gp3",
    capacity: "1000Gi",
    maximumVolumeSize: "16Ti",
});

Resource Variants

All storage resources include the following variants:

List Resources

  • StorageClassList, VolumeAttachmentList, CSIDriverList, CSINodeList, CSIStorageCapacityList

Patch Resources

  • StorageClassPatch, VolumeAttachmentPatch, CSIDriverPatch, CSINodePatch, CSIStorageCapacityPatch
// Example patch operation
const storageClassPatch = new k8s.storage.v1.StorageClassPatch("update-storage-class", {
    metadata: {
        name: "existing-storage-class",
    },
    allowVolumeExpansion: true, // Enable volume expansion
    parameters: {
        iops: "5000", // Update IOPS setting
    },
});

Best Practices

StorageClass Best Practices

  1. Default Classes: Mark appropriate storage class as default with annotation
  2. Reclaim Policy: Use "Retain" for critical data, "Delete" for temporary data
  3. Volume Binding: Use "WaitForFirstConsumer" for zone-aware provisioning
  4. Encryption: Always enable encryption for sensitive data
  5. Performance Tuning: Choose appropriate IOPS and throughput for workload requirements

CSI Driver Best Practices

  1. Resource Limits: Set appropriate resource limits for CSI driver pods
  2. Security: Use service accounts and RBAC for proper permissions
  3. Monitoring: Monitor CSI driver health and performance metrics
  4. Updates: Keep CSI drivers updated for security and feature improvements
  5. Backup Strategy: Implement proper backup and disaster recovery procedures

The Storage API groups provide comprehensive dynamic storage provisioning and management capabilities, enabling efficient and scalable storage solutions for containerized applications.

Install with Tessl CLI

npx tessl i tessl/npm-pulumi--kubernetes

docs

core-resources.md

helm-integration.md

index.md

kustomize-integration.md

networking-resources.md

provider-configuration.md

rbac-resources.md

storage-resources.md

workload-resources.md

yaml-deployment.md

tile.json