vault: implement bootstrap integration
Some checks failed
Run nix flake check / flake-check (push) Failing after 3m15s

This commit is contained in:
2026-02-02 22:27:28 +01:00
parent 7fc69c40a6
commit 1f4b7a6cbc
19 changed files with 1949 additions and 11 deletions

View File

@@ -10,18 +10,25 @@ resource "proxmox_cloud_init_disk" "ci" {
pve_node = each.value.target_node
storage = "local" # Cloud-init disks must be on storage that supports ISO/snippets
# User data includes SSH keys and optionally NIXOS_FLAKE_BRANCH
# User data includes SSH keys and optionally NIXOS_FLAKE_BRANCH and Vault credentials
user_data = <<-EOT
#cloud-config
ssh_authorized_keys:
- ${each.value.ssh_public_key}
${each.value.flake_branch != null ? <<-BRANCH
${each.value.flake_branch != null || each.value.vault_wrapped_token != null ? <<-FILES
write_files:
- path: /etc/environment
content: |
%{~ if each.value.flake_branch != null ~}
NIXOS_FLAKE_BRANCH=${each.value.flake_branch}
%{~ endif ~}
%{~ if each.value.vault_wrapped_token != null ~}
VAULT_ADDR=https://vault.home.2rjus.net:8200
VAULT_WRAPPED_TOKEN=${each.value.vault_wrapped_token}
VAULT_SKIP_VERIFY=1
%{~ endif ~}
append: true
BRANCH
FILES
: ""}
EOT

View File

@@ -0,0 +1,42 @@
# WARNING: Auto-generated by create-host tool
# Manual edits will be overwritten when create-host is run
# Generated host policies
# Each host gets access to its own secrets under hosts/<hostname>/*
locals {
generated_host_policies = {
}
# Placeholder secrets - user should add actual secrets manually or via tofu
generated_secrets = {
}
}
# Create policies for generated hosts
resource "vault_policy" "generated_host_policies" {
for_each = local.generated_host_policies
name = "host-${each.key}"
policy = <<-EOT
# Allow host to read its own secrets
%{for path in each.value.paths~}
path "${path}" {
capabilities = ["read", "list"]
}
%{endfor~}
EOT
}
# Create AppRoles for generated hosts
resource "vault_approle_auth_backend_role" "generated_hosts" {
for_each = local.generated_host_policies
backend = vault_auth_backend.approle.path
role_name = each.key
token_policies = ["host-${each.key}"]
secret_id_ttl = 0 # Never expire (wrapped tokens provide time limit)
token_ttl = 3600
token_max_ttl = 3600
secret_id_num_uses = 0 # Unlimited uses
}

View File

@@ -66,6 +66,8 @@ locals {
gateway = lookup(vm, "gateway", var.default_gateway)
# Branch configuration for bootstrap (optional, uses master if not set)
flake_branch = lookup(vm, "flake_branch", null)
# Vault configuration (optional, for automatic secret provisioning)
vault_wrapped_token = lookup(vm, "vault_wrapped_token", null)
}
}
}