terraform: add vault secret managment to terraform

This commit is contained in:
2026-02-01 23:07:47 +01:00
parent b6f1e80c2a
commit 5d513fd5af
8 changed files with 448 additions and 0 deletions

201
terraform/vault/README.md Normal file
View File

@@ -0,0 +1,201 @@
# OpenBao Terraform Configuration
This directory contains Terraform/OpenTofu configuration for managing OpenBao (Vault) infrastructure as code.
## Overview
Manages the following OpenBao resources:
- **AppRole Authentication**: For host-based authentication
- **PKI Infrastructure**: Root CA + Intermediate CA for TLS certificates
- **KV Secrets Engine**: Key-value secret storage (v2)
- **Policies**: Access control policies
## Setup
1. **Copy the example tfvars file:**
```bash
cp terraform.tfvars.example terraform.tfvars
```
2. **Edit `terraform.tfvars` with your OpenBao credentials:**
```hcl
vault_address = "https://vault.home.2rjus.net:8200"
vault_token = "hvs.your-root-token-here"
vault_skip_tls_verify = true
```
3. **Initialize Terraform:**
```bash
tofu init
```
4. **Review the plan:**
```bash
tofu plan
```
5. **Apply the configuration:**
```bash
tofu apply
```
## Files
- `main.tf` - Provider configuration
- `variables.tf` - Variable definitions
- `approle.tf` - AppRole authentication backend and roles
- `pki.tf` - PKI engines (root CA and intermediate CA)
- `secrets.tf` - KV secrets engine and test secrets
- `terraform.tfvars` - Credentials (gitignored)
- `terraform.tfvars.example` - Example configuration
## Resources Created
### AppRole Authentication
- AppRole backend at `approle/`
- Host-based roles and policies (defined in `locals.host_policies`)
### PKI Infrastructure
- Root CA at `pki/` (10 year TTL)
- Intermediate CA at `pki_int/` (5 year TTL)
- Role `homelab` for issuing certificates to `*.home.2rjus.net`
- Certificate max TTL: 30 days
### Secrets
- KV v2 engine at `secret/`
- Secrets and policies defined in `locals.secrets` and `locals.host_policies`
## Usage Examples
### Adding a New Host
1. **Define the host policy in `approle.tf`:**
```hcl
locals {
host_policies = {
"monitoring01" = {
paths = [
"secret/data/hosts/monitoring01/*",
"secret/data/services/prometheus/*",
]
}
}
}
```
2. **Add secrets in `secrets.tf`:**
```hcl
locals {
secrets = {
"hosts/monitoring01/grafana-admin" = {
auto_generate = true
password_length = 32
}
}
}
```
3. **Apply changes:**
```bash
tofu apply
```
4. **Get AppRole credentials:**
```bash
# Get role_id
bao read auth/approle/role/monitoring01/role-id
# Generate secret_id
bao write -f auth/approle/role/monitoring01/secret-id
```
### Issue a certificate from PKI
```bash
# Issue certificate for a host
bao write pki_int/issue/homelab \
common_name="test.home.2rjus.net" \
ttl="720h"
```
### Read a secret
```bash
# Authenticate with AppRole first
bao write auth/approle/login \
role_id="..." \
secret_id="..."
# Read the test secret
bao kv get secret/test/example
```
## Managing Secrets
Secrets are defined in the `locals.secrets` block in `secrets.tf` using a declarative pattern:
### Auto-Generated Secrets (Recommended)
Most secrets can be auto-generated using the `random_password` provider:
```hcl
locals {
secrets = {
"hosts/monitoring01/grafana-admin" = {
auto_generate = true
password_length = 32
}
}
}
```
### Manual Secrets
For secrets that must have specific values (external services, etc.):
```hcl
# In variables.tf
variable "smtp_password" {
type = string
sensitive = true
}
# In secrets.tf locals block
locals {
secrets = {
"shared/smtp/credentials" = {
auto_generate = false
data = {
username = "notifications@2rjus.net"
password = var.smtp_password
server = "smtp.gmail.com"
}
}
}
}
# In terraform.tfvars
smtp_password = "super-secret-password"
```
### Path Structure
Secrets follow a three-tier hierarchy:
- `hosts/{hostname}/*` - Host-specific secrets
- `services/{service}/*` - Service-wide secrets (any host running the service)
- `shared/{category}/*` - Shared secrets (SMTP, backup, etc.)
## Security Notes
- `terraform.tfvars` is gitignored to prevent credential leakage
- Root token should be stored securely (consider using a limited admin token instead)
- `skip_tls_verify = true` is acceptable for self-signed certs in homelab
- AppRole secret_ids can be scoped to specific CIDR ranges for additional security
## Next Steps
1. Add more AppRoles for different host types
2. Create policies for different service tiers
3. Migrate existing sops-nix secrets to OpenBao KV
4. Enable ACME support on PKI intermediate CA (OpenBao 2.0+)
5. Set up SSH CA for host and user certificates