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
-
Copy the example tfvars file:
cp terraform.tfvars.example terraform.tfvars -
Edit
terraform.tfvarswith your OpenBao credentials:vault_address = "https://vault.home.2rjus.net:8200" vault_token = "hvs.your-root-token-here" vault_skip_tls_verify = true -
Initialize Terraform:
tofu init -
Review the plan:
tofu plan -
Apply the configuration:
tofu apply
Files
main.tf- Provider configurationvariables.tf- Variable definitionsapprole.tf- AppRole authentication backend and rolespki.tf- PKI engines (root CA and intermediate CA)secrets.tf- KV secrets engine and test secretsterraform.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
homelabfor issuing certificates to*.home.2rjus.net - Certificate max TTL: 30 days
Secrets
- KV v2 engine at
secret/ - Secrets and policies defined in
locals.secretsandlocals.host_policies
Usage Examples
Adding a New Host
- Define the host policy in
approle.tf:
locals {
host_policies = {
"monitoring01" = {
paths = [
"secret/data/hosts/monitoring01/*",
"secret/data/services/prometheus/*",
]
}
}
}
- Add secrets in
secrets.tf:
locals {
secrets = {
"hosts/monitoring01/grafana-admin" = {
auto_generate = true
password_length = 32
}
}
}
- Apply changes:
tofu apply
- Get AppRole credentials:
# 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
# Issue certificate for a host
bao write pki_int/issue/homelab \
common_name="test.home.2rjus.net" \
ttl="720h"
Read a secret
# 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:
locals {
secrets = {
"hosts/monitoring01/grafana-admin" = {
auto_generate = true
password_length = 32
}
}
}
Manual Secrets
For secrets that must have specific values (external services, etc.):
# 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 secretsservices/{service}/*- Service-wide secrets (any host running the service)shared/{category}/*- Shared secrets (SMTP, backup, etc.)
Security Notes
terraform.tfvarsis gitignored to prevent credential leakage- Root token should be stored securely (consider using a limited admin token instead)
skip_tls_verify = trueis acceptable for self-signed certs in homelab- AppRole secret_ids can be scoped to specific CIDR ranges for additional security
Next Steps
- Add more AppRoles for different host types
- Create policies for different service tiers
- Migrate existing sops-nix secrets to OpenBao KV
- Enable ACME support on PKI intermediate CA (OpenBao 2.0+)
- Set up SSH CA for host and user certificates