This post walks you through installing HashiCorp Vault (Open Source Edition) on an Ubuntu 24.04 EC2 instance. We’ll use AWS KMS for auto-unseal and expose Vault using NGINX and Let’s Encrypt.
What You’ll Set Up
- Ubuntu 24.04 EC2 instance
- Vault OSS installed via apt
- AWS KMS auto-unseal
- Vault UI exposed via HTTPS using NGINX + Certbot
- Recovery via Shamir keys (default in OSS)
- Install Vault
wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install vault
- Install NGINX and Certbot
sudo apt install nginx certbot python3-certbot-nginx -y
- Configure Vault
Edit /etc/vault.d/vault.hcl, make sure you have following
# HTTP listener
listener "tcp" {
  address = "127.0.0.1:8200"
  tls_disable = 1
}
Restart Vault:
sudo systemctl daemon-reload
sudo systemctl enable vault
sudo systemctl restart vault
- Set Up NGINX as Reverse Proxy
Create config:
sudo tee /etc/nginx/sites-available/vault <<EOF
server {
    listen 80;
    server_name vault.maksonlee.com;
    location / {
        proxy_pass http://127.0.0.1:8200;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
    }
}
EOF
sudo ln -s /etc/nginx/sites-available/vault /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Get HTTPS certificate:
sudo certbot --nginx -d vault.maksonlee.com
- Create AWS KMS Key and IAM Role (in CloudShell)
KMS key:
aws kms create-key \
  --description "Vault auto-unseal key" \
  --key-usage ENCRYPT_DECRYPT \
  --key-spec SYMMETRIC_DEFAULT \
  --tags TagKey=Project,TagValue=Vault
aws kms create-alias \
  --alias-name alias/vault-unseal \
  --target-key-id <your-key-id>
IAM Role + Policy:
aws iam create-role --role-name VaultInstanceRole \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "ec2.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'
aws iam create-policy --policy-name VaultKMSUnsealAccess \
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:GenerateDataKey",
        "kms:DescribeKey"
      ],
      "Resource": "*"
    }]
  }'
aws iam attach-role-policy \
  --role-name VaultInstanceRole \
  --policy-arn arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):policy/VaultKMSUnsealAccess
Attach to EC2:
aws iam create-instance-profile \
  --instance-profile-name VaultInstanceProfile
aws iam add-role-to-instance-profile \
  --instance-profile-name VaultInstanceProfile \
  --role-name VaultInstanceRole
aws ec2 associate-iam-instance-profile \
  --instance-id <your-instance-id> \
  --iam-instance-profile Name=VaultInstanceProfile
- Enable KMS Auto-Unseal in Vault
Edit /etc/vault.d/vault.hcl, make sure you have following
seal "awskms" {
  region = "ap-south-1"
  kms_key_id = "alias/vault-unseal"
}
Restart Vault:
sudo systemctl restart vault
- Initialize Vault
VAULT_ADDR=http://127.0.0.1:8200 vault operator init
This will generate:
- Root token
- 5 Shamir recovery keys
Verify
VAULT_ADDR=http://127.0.0.1:8200 vault status
You should see:
Seal Type: awskms
Recovery Seal Type: shamir
Sealed: false
- Log In to Vault Web UI
- Open https://vault.maksonlee.com
- Choose Tokenas the authentication method
- Paste your Initial Root Token from Step 7
- Click Sign In
Done!
Vault is installed and:
- Automatically unseals using AWS KMS
- Is accessible via HTTPS
- Uses default OSS Shamir recovery mode
