Tableau Server Helm Chart - Prerequisites

Important: This documentation assumes a knowledge of Helm and Helm charts and does not attempt to provide detailed, prescriptive examples. It is designed for customers who are familiar with both Tableau Server and Helm and Helm charts.

This topic explains the prerequisites necessary to use a Helm chart for deploying Tableau Server.

Helm Chart Download and Distribution

The Helm charts will be shipped as part of the Tableau Server in a Container setup tool (tableau-server-container-setup-tool-<version>.tar.gz) and can be downloaded from the Tableau Server download(Link opens in a new window) page.

After extraction, the required Helm chart files are located in the helm/tableau directory.

Required Tools

  • kubectl CLI configured to access your Kubernetes cluster
  • helm CLI version 3.x or later
  • Access to a Kubernetes cluster (1.19+)

Cluster Requirements

  • At least one node with 16GB RAM and 4 CPU cores (8 cores recommended).
  • StorageClass configured for dynamic PersistentVolume provisioning.
  • Ability to create LoadBalancer services or Ingress resources.

Required Information

Be sure you have the following before starting:

  • Your Tableau Server license key
  • The TSM Administrator username and password for the initial account
  • The Tableau Server hostname for access

Amazon Elastic Kubernetes Service (EKS) prerequisites

efs-bootstrap StorageClass

By default efs-bootstrap is not created in EKS. For multinode bootstrap sharing, create it before Helm install.

For multinode deplyment, bootstrap storage must be provisionable before pods can schedule. If your efs-bootstrap StorageClass does not dynamically provision EFS volumes, you must either:

  • Create a static bootstrap PV in advance and bind it to tableau-server-bootstrap

    or

  • Set persistence.bootstrap.createPV: true and provide valid persistence.bootstrap.pv.csi.volumeHandle (real EFS ID, fs-...).

If this is not done, pods remain in a Pending state with unbound PVCs.

  1. Ensure the EFS CSI driver is installed in your cluster.

    kubectl get csidriver efs.csi.aws.com

    A CSIDriver object can exist even when the EKS managed add-on is not installed. Confirm the add-on explicitly.

    If you get a ResourceNotFoundException error (no add-on), or pods later fail with mount errors such as driver name efs.csi.aws.com not found in the list of registered CSI drivers, install the EKS add-on and wait until the status is ACTIVE and then verify the node plugin pods.

    This is necessary because multinode bootstrap uses an EFS-backed volume (ReadWriteMany). Without the EFS CSI node plugin on additional nodes, bootstrap PVCs can bind but mounts fail and pods stay in Init/Pending states.

    If EFS mounts fail with:

      is not authorized to perform: elasticfilesystem:DescribeMountTargets

      or

      Failed to resolve "fs-....efs.<region>.amazonaws.com"

    Use one of these remediations:

    • IAM fix on EKS node role (Preferred): grant EFS and EC2 read permissions so mount target and AZ discovery work. Resolve the node instance role name from your node group:

      aws eks list-nodegroups --cluster-name <cluster-name>
      aws eks describe-nodegroup \
      --cluster-name <cluster-name> \
      --nodegroup-name <nodegroup-name> \
      --query "nodegroup.nodeRole" \
      --output text
    • Use the IAM **role name** (last segment of the ARN) in attach-role-policy:

      aws iam attach-role-policy \
      --role-name <your-node-instance-role> \
      --policy-arn arn:aws:iam::aws:policy/AmazonElasticFileSystemClientReadWriteAccess
      aws iam attach-role-policy \
      --role-name <your-node-instance-role> \
      --policy-arn arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
      • Typical permissions involved:

        • elasticfilesystem:DescribeMountTargets, 
          elasticfilesystem:DescribeFileSystems
        • ec2:DescribeAvailabilityZones (often needed when DescribeAvailabilityZones appears in mount errors)

    • explicitly mount target IP: set mounttargetip on the bootstrap PV CSI volume attributes when DNS/discovery is restricted in your environment.

      • Helm values (createPV: true path):

        persistence:
        bootstrap:
        pv:
        csi:
        volumeAttributes:
        mounttargetip: "10.x.x.x"
      • Manual PV path

        spec:
        csi:
        driver: efs.csi.aws.com
        volumeHandle: fs-xxxxxxxx
        volumeAttributes:
        mounttargetip: 10.x.x.x
  2. Create efs-bootstrap StorageClass (example):

    apiVersion: storage.k8s.io/v1
    kind: StorageClass metadata:
    name: efs-bootstrap
    provisioner: efs.csi.aws.com
    reclaimPolicy: Retain
    volumeBindingMode: Immediate
    allowVolumeExpansion: true
  3. Choose one bootstrap provisioning path (required):

  • Dynamic EFS provisioning path:

    use an EFS CSI dynamic StorageClass configured for Access Points (for example provisioningMode: efs-ap, fileSystemId, and permissions/basePath parameters according to your platform standard).

  • Static PV path:

    create tableau-bootstrap-pv manually with csi.driver: efs.csi.aws.com and csi.volumeHandle: fs-...

    then set:

    • persistence.bootstrap.createPV: false

    • persistence.bootstrap.volumeName: tableau-bootstrap-pv

  • Helm-created static PV path:

    set:

    • persistence.bootstrap.createPV: true

    • persistence.bootstrap.pv.csi.volumeHandle: fs-...

Non-EKS prerequisite

ReadWriteMany StorageClass

For clusters not hosted on EKS (or if not using EFS), the critical requirement for multinode bootstrap sharing is providing a StorageClass that supports ReadWriteMany (RWX) access mode for the bootstrap volume. This is required because bootstrap storage must be provisionable before pods can schedule.

Common self-hosted RWX storage backends for Kubernetes include:

  • NFS (most common, easiest to test)

  • CephFS

  • Longhorn (if installed)

  • GlusterFS

  • NetApp/other enterprise storage

You must ensure the corresponding CSI driver for your chosen backend is installed.

To configure Tableau Server to use your custom RWX StorageClass, update your Helm values (e.g., values-multinode.yaml) to set persistence.bootstrap.storageClass to the name of your StorageClass:

persistence:
  # ... other persistence settings ...

  # Bootstrap volume (required for multi-node)
  bootstrap:
    enabled: true
    storageClass: "my-rwx-storage" # <--- Replace with your StorageClass name
    accessMode: ReadWriteMany
    size: 1Gi
    createPV: false

Additional Resources

Thanks for your feedback!Your feedback has been successfully submitted. Thank you!