# 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://vault01.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 Certificates from PKI **Method 1: ACME (Recommended for automated services)** First, enable ACME support: ```bash bao write pki_int/config/acme enabled=true ``` ACME directory endpoint: ``` https://vault01.home.2rjus.net:8200/v1/pki_int/acme/directory ``` Use with ACME clients (lego, certbot, cert-manager, etc.): ```bash # Example with lego lego --email admin@home.2rjus.net \ --dns manual \ --server https://vault01.home.2rjus.net:8200/v1/pki_int/acme/directory \ --accept-tos \ run -d test.home.2rjus.net ``` **Method 2: Static certificates via Terraform** Define in `pki.tf`: ```hcl locals { static_certificates = { "monitoring" = { common_name = "monitoring.home.2rjus.net" alt_names = ["grafana.home.2rjus.net", "prometheus.home.2rjus.net"] ttl = "720h" } } } ``` Terraform will auto-issue and auto-renew these certificates. **Method 3: Manual CLI issuance** ```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 ## Initial Setup Steps After deploying this configuration, perform these one-time setup tasks: ### 1. Enable ACME ```bash export BAO_ADDR='https://vault01.home.2rjus.net:8200' export BAO_TOKEN='your-root-token' export BAO_SKIP_VERIFY=1 # Configure cluster path (required for ACME) bao write pki_int/config/cluster path=https://vault01.home.2rjus.net:8200/v1/pki_int # Enable ACME on intermediate CA bao write pki_int/config/acme enabled=true # Verify ACME is enabled curl -k https://vault01.home.2rjus.net:8200/v1/pki_int/acme/directory ``` ### 2. Download Root CA Certificate For trusting the internal CA on clients: ```bash # Download root CA certificate bao read -field=certificate pki/cert/ca > homelab-root-ca.crt # Install on NixOS hosts (add to system/default.nix or similar) security.pki.certificateFiles = [ ./homelab-root-ca.crt ]; ``` ### 3. Test Certificate Issuance ```bash # Manual test bao write pki_int/issue/homelab common_name="test.home.2rjus.net" ttl="24h" ``` ## Next Steps 1. Replace step-ca ACME endpoint with OpenBao in `system/acme.nix` 2. Add more AppRoles for different host types 3. Migrate existing sops-nix secrets to OpenBao KV 4. Set up SSH CA for host and user certificates 5. Configure auto-unseal for vault01