This guide explains how to configure the Vision One File Security Helm chart to use AWS EBS storage for the Database Container when deploying on Amazon EKS.
This guide configures the database to use AWS EBS (Elastic Block Store) by setting storageClass.create: false and specifying an existing EBS-based StorageClass.
If your EKS cluster already has the EBS CSI driver installed (most clusters do), you can skip directly to Step 2 or Step 3:
kubectl get storageclass (look for gp2 or gp3)gp2 exists, create gp3 StorageClass (see Step 2)visiononeFilesecurity.management.dbEnabled: truevalues.yaml to set databaseContainer.storageClass.create: falsedatabaseContainer.persistence.storageClassName: "gp3"See Step 3: Configure Helm Chart for AWS EBS for details.
visiononeFilesecurity:
management:
dbEnabled: true
databaseContainer:
persistence:
storageClassName: "gp3" # Or gp2, custom StorageClass name
size: 100Gi
storageClass:
create: false # Use existing AWS EBS StorageClass
kubectl get storageclass
Look for StorageClasses with provisioner ebs.csi.aws.com. Common names: gp2, gp3.
If you see these, the driver is already installed. Skip to Step 2.
curl -o ebs-csi-iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/master/docs/example-iam-policy.json
aws iam create-policy \
--policy-name AmazonEKS_EBS_CSI_Driver_Policy \
--policy-document file://ebs-csi-iam-policy.json
eksctl create iamserviceaccount \
--cluster <your-cluster-name> \
--namespace kube-system \
--name ebs-csi-controller-sa \
--attach-policy-arn arn:aws:iam::<your-account-id>:policy/AmazonEKS_EBS_CSI_Driver_Policy \
--approve \
--override-existing-serviceaccounts
This will output the IAM role ARN. Copy it for the next step.
aws eks create-addon \
--cluster-name <your-cluster-name> \
--addon-name aws-ebs-csi-driver \
--service-account-role-arn <role-arn-from-step-2> \
--resolve-conflicts OVERWRITE
Note: The
--resolve-conflicts OVERWRITEflag is required if there’s an existing ServiceAccount.
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver
kubectl get storageclass
You should see gp2 or gp3 StorageClasses.
If your cluster only has gp2 and you want to use gp3, create a gp3 StorageClass:
cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
provisioner: ebs.csi.aws.com
parameters:
type: gp3
encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
EOF
Verify it was created:
kubectl get storageclass gp3
Edit your values.yaml. Make sure the Management Service is allowed to deploy the embedded database:
visiononeFilesecurity:
management:
dbEnabled: true
databaseContainer:
persistence:
storageClassName: "gp3" # Use existing AWS EBS StorageClass
size: 100Gi
storageClass:
create: false # Don't create local StorageClass
Check what’s available in your cluster:
kubectl get storageclass
Common options:
gp2 - General Purpose SSD (older)gp3 - General Purpose SSD (recommended)io1 / io2 - Provisioned IOPS SSDFor volume type comparisons, see AWS EBS Volume Types.
helm upgrade --install my-release visionone-filesecurity/visionone-filesecurity \
--namespace visionone-filesecurity \
--create-namespace \
-f values.yaml
Or using –set flags:
helm upgrade --install my-release visionone-filesecurity/visionone-filesecurity \
--namespace visionone-filesecurity \
--create-namespace \
--set visiononeFilesecurity.management.dbEnabled=true \
--set databaseContainer.storageClass.create=false \
--set databaseContainer.persistence.storageClassName=gp3 \
--set databaseContainer.persistence.size=100Gi
kubectl get pvc -n visionone-filesecurity
The PVC should show STATUS: Bound.
kubectl get pv | grep visionone-filesecurity
aws ec2 describe-volumes \
--filters "Name=tag:kubernetes.io/created-for/pvc/name,Values=postgres-data-my-release-visionone-filesecurity-database-container-0"
Or check in AWS Console: EC2 → Volumes
Check CSI driver status:
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver
Check CSI driver logs:
kubectl logs -n kube-system -l app=ebs-csi-controller -c csi-provisioner
Common causes:
If you see errors like:
rpc error: code = FailedPrecondition desc = Failed health check (verify network connection and IAM credentials):
dry-run EC2 API call failed: operation error EC2: DescribeAvailabilityZones, api error UnauthorizedOperation
This means the EBS CSI driver doesn’t have the required IAM permissions.
Solution: Follow the IAM setup steps in Step 1: Install AWS EBS CSI Driver above.
Verify the fix:
# Check EBS CSI controller pods are healthy (should be 6/6 Running)
kubectl get pods -n kube-system | grep ebs-csi-controller
# Check logs for no more IAM errors
kubectl logs -n kube-system -l app=ebs-csi-controller -c csi-provisioner --tail=20
The EBS CSI driver needs these IAM permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:CreateVolume",
"ec2:DeleteVolume",
"ec2:AttachVolume",
"ec2:DetachVolume",
"ec2:DescribeVolumes",
"ec2:DescribeVolumeStatus",
"ec2:DescribeInstances",
"ec2:CreateSnapshot",
"ec2:DeleteSnapshot",
"ec2:DescribeSnapshots",
"ec2:CreateTags"
],
"Resource": "*"
}
]
}
Check if EBS volume and pod are in the same availability zone:
# Get pod's node
kubectl get pod -n visionone-filesecurity -o wide
# Get node's AZ
kubectl get node <node-name> -o jsonpath='{.metadata.labels.topology\.kubernetes\.io/zone}'
# Get EBS volume's AZ
aws ec2 describe-volumes --volume-ids <volume-id> --query 'Volumes[0].AvailabilityZone'
Solution: EBS volumes can only attach to instances in the same AZ. The StorageClass uses volumeBindingMode: WaitForFirstConsumer to handle this automatically.
The database container handles permissions automatically. If you see permission errors:
kubectl logs pod/my-release-visionone-filesecurity-database-container-0 -n visionone-filesecurity
Remember to keep
visiononeFilesecurity.management.dbEnabled: truein these examples so the database resources are rendered.
visiononeFilesecurity:
management:
dbEnabled: true
databaseContainer:
persistence:
storageClassName: "gp3"
size: 100Gi
storageClass:
create: false
visiononeFilesecurity:
management:
dbEnabled: true
databaseContainer:
persistence:
storageClassName: "gp3"
size: 500Gi
storageClass:
create: false