HashiCorp Vault — Storage Backends
The storage backend determines where Vault persists its encrypted data. Choosing the right backend is one of the most important production decisions you’ll make.
Storage Backend Overview
┌─────────────────────────────────────────────────────┐
│ Vault Server │
│ │
│ ┌────────────────┐ │
│ │ Barrier │ ← encrypts all data │
│ └───────┬────────┘ │
│ │ │
│ ┌───────▼────────┐ │
│ │ Storage Backend │ ← stores ciphertext│
│ └───────┬────────┘ │
│ │ │
│ ┌───────────┼───────────┐ │
│ │ │ │ │
│ ┌────▼───┐ ┌────▼────┐ ┌───▼────┐ │
│ │ Raft │ │ Consul │ │ S3 │ │
│ │ (rec.) │ │ │ │ │ │
│ └────────┘ └─────────┘ └────────┘ │
└─────────────────────────────────────────────────────┘
💡 Key point: The storage backend only sees encrypted data. It does not need to provide its own encryption.
Comparison Matrix
| Backend | HA Support | Consistency | Operational Complexity | Recommended |
|---|---|---|---|---|
| Raft (Integrated) | ✅ Built-in | Strong | Low | ✅ Yes |
| Consul | ✅ External | Strong | Medium | For Consul users |
| S3 | ❌ | Eventual | Low | Dev/backup only |
| GCS | ❌ | Eventual | Low | Dev/backup only |
| Azure Blob | ❌ | Eventual | Low | Dev/backup only |
| Filesystem | ❌ | N/A | None | Dev/test only |
| DynamoDB | ✅ (with HA) | Strong | Medium | AWS deployments |
Raft Storage (Recommended)
Raft is Vault’s integrated storage backend. It provides built-in consensus and HA without external dependencies.
# vault.hcl — Raft storage
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-1"
}
Why Raft Is Recommended
- No external dependencies — No need to manage a separate Consul cluster
- Built-in HA — Leader election and data replication handled by Vault
- Simple operations — Backup with
vault operator raft snapshot - Strong consistency — Raft consensus guarantees data consistency
Multi-Node Raft Cluster
# Node 1 — vault-1.hcl
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-1"
retry_join {
leader_api_addr = "https://vault-2.example.com:8200"
}
retry_join {
leader_api_addr = "https://vault-3.example.com:8200"
}
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/opt/vault/tls/vault-cert.pem"
tls_key_file = "/opt/vault/tls/vault-key.pem"
}
api_addr = "https://vault-1.example.com:8200"
cluster_addr = "https://vault-1.example.com:8201"
Raft Cluster Operations
# List raft peers
vault operator raft list-peers
# Expected output:
# Node Address State Voter
# ---- ------- ----- -----
# vault-1 vault-1.example.com:8201 leader true
# vault-2 vault-2.example.com:8201 follower true
# vault-3 vault-3.example.com:8201 follower true
# Take a snapshot (backup)
vault operator raft snapshot save backup.snap
# Restore from snapshot
vault operator raft snapshot restore backup.snap
# Remove a peer
vault operator raft remove-peer vault-3
Consul Storage
Consul was the original recommended backend before Raft was integrated:
# vault.hcl — Consul storage
storage "consul" {
address = "127.0.0.1:8500"
path = "vault/"
token = "consul-acl-token"
}
When to Use Consul
- You already operate a Consul cluster
- You need Consul for service discovery alongside Vault
- Your organization has Consul expertise
Consul vs Raft
| Feature | Raft | Consul |
|---|---|---|
| External dependency | None | Consul cluster required |
| Operational complexity | Low | Higher (manage Consul + Vault) |
| Backup method | raft snapshot |
Consul snapshot + Vault backup |
| HA mechanism | Built-in leader election | Consul session locks |
| Performance | Excellent | Depends on Consul cluster |
Filesystem Storage
For development and testing only:
# vault.hcl — Filesystem storage (NO HA)
storage "file" {
path = "/opt/vault/data"
}
⚠️ Warning: Filesystem storage does not support HA. Never use it in production.
Cloud Object Storage
Amazon S3
storage "s3" {
bucket = "my-vault-storage"
region = "us-east-1"
access_key = "AKIA..."
secret_key = "secret..."
}
Google Cloud Storage
storage "gcs" {
bucket = "my-vault-storage"
}
Azure Blob Storage
storage "azure" {
accountName = "myvaultstorage"
accountKey = "base64key..."
container = "vault-data"
}
⚠️ Warning: Cloud object storage backends do not support HA. Use them for dev/test or as backup targets, not for production clusters.
DynamoDB Storage (AWS)
DynamoDB supports HA when configured with a lock table:
storage "dynamodb" {
ha_enabled = "true"
region = "us-east-1"
table = "vault-data"
}
Choosing the Right Backend
Need HA?
/ \
Yes No
/ \
Have Consul? ┌─────────────┐
/ \ │ Use Raft │
Yes No │ (single │
│ │ │ node) or │
▼ ▼ │ Filesystem │
┌────────┐ ┌────────┐ └─────────────┘
│ Consul │ │ Raft │
│ or │ │ (rec.) │
│ Raft │ │ │
└────────┘ └────────┘
For most deployments: Use Raft. It’s simpler, has no external dependencies, and is HashiCorp’s recommended backend.
Quick Reference
| Backend | HA | Config Key | Production Use |
|---|---|---|---|
| Raft | ✅ | storage "raft" |
✅ Recommended |
| Consul | ✅ | storage "consul" |
✅ If you have Consul |
| DynamoDB | ✅ | storage "dynamodb" |
✅ AWS deployments |
| S3 | ❌ | storage "s3" |
❌ Dev/backup only |
| GCS | ❌ | storage "gcs" |
❌ Dev/backup only |
| Azure Blob | ❌ | storage "azure" |
❌ Dev/backup only |
| Filesystem | ❌ | storage "file" |
❌ Dev/test only |
Next: Vault UI & CLI