A comprehensive Pulumi resource provider for creating and managing Kubernetes resources and workloads in a running cluster
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The Storage API groups provide resources for dynamic volume provisioning, storage management, and Container Storage Interface (CSI) driver integration across multiple API versions.
import { storage } from "@pulumi/kubernetes";
import * as k8s from "@pulumi/kubernetes";
// Direct storage imports
import { StorageClass, VolumeAttachment, CSIDriver } from "@pulumi/kubernetes/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 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// 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 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 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>;
}// 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 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 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>;
}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}>;
}// 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,
},
}],
},
},
},
});// 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 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",
});// 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",
});All storage resources include the following variants:
StorageClassList, VolumeAttachmentList, CSIDriverList, CSINodeList, CSIStorageCapacityListStorageClassPatch, 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
},
});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