Skip to content

Vault Operations

Operational guide for HashiCorp Vault secrets management in the fzymgc-house cluster.

PropertyValue
URLhttps://vault.fzymgc.house
Auth MethodsOIDC (Keycloak), Token
Storage BackendIntegrated Storage (Raft)
Terraform Moduletf/vault/
Helper Script./scripts/vault-helper.sh

All infrastructure secrets stored under secret/fzymgc-house/:

PathPurpose
infrastructure/bmc/tpi-alphaTuringPi Alpha BMC credentials
infrastructure/bmc/tpi-betaTuringPi Beta BMC credentials
infrastructure/cloudflare/api-tokenCloudflare API token
cluster/keycloakKeycloak Terraform/bootstrap admin credentials
cluster/hcp-terraformHCP Terraform agent token
Terminal window
export VAULT_ADDR=https://vault.fzymgc.house
# OIDC login (browser-based)
vault login -method=oidc
# Token login
vault login
Terminal window
vault kv get secret/fzymgc-house/cluster/keycloak
# Get single field
vault kv get -field=terraform_password secret/fzymgc-house/cluster/keycloak
Terminal window
vault kv list secret/fzymgc-house/cluster/
Terminal window
vault kv put secret/fzymgc-house/cluster/example key=value
Terminal window
# Check connectivity
./scripts/vault-helper.sh status
# List infrastructure secrets
./scripts/vault-helper.sh list
# Get specific secret
./scripts/vault-helper.sh get bmc/tpi-alpha
# Get single field
./scripts/vault-helper.sh get bmc/tpi-alpha password
# Vault lookup in group_vars
tpi_bmc_password: "{{ lookup('community.hashi_vault.vault_kv2_get', 'infrastructure/bmc/tpi-alpha', engine_mount_point='secret/fzymgc-house').secret.password }}"
cloudflare_api_token: "{{ lookup('community.hashi_vault.vault_kv2_get', 'infrastructure/cloudflare/api-token', engine_mount_point='secret/fzymgc-house').secret.token }}"

For Ansible modules that access Vault directly, ensure the CA bundle is set so Python requests can validate TLS. Configure vault_ca_cert_bundle in ansible/inventory/group_vars/all.yml or set VAULT_CACERT.

Requires community.hashi_vault collection (installed via requirements).

data "vault_kv_secret_v2" "cloudflare" {
mount = "secret/fzymgc-house"
name = "infrastructure/cloudflare/api-token"
}
provider "cloudflare" {
api_token = data.vault_kv_secret_v2.cloudflare.data["token"]
}
  1. Generate new credential
  2. Update Vault secret
  3. Restart affected pods to pick up changes

Some secrets support automatic rotation via Vault policies.

Rotating secrets consumed via write-only (*_wo) attributes

Section titled “Rotating secrets consumed via write-only (*_wo) attributes”

Some Terraform sinks read Vault secrets ephemerally and write them through write-only attributes (kubernetes_secret_v1.data_wo, tfe_notification_configuration.token_wo, …; hl-106s, ADR hl-ujwi). Terraform cannot diff write-only content, so rotating the Vault secret does not propagate by itself (exception: the tfe notification url/token use the provider’s auto-hash mode and re-send automatically).

After rotating such a secret in Vault:

  1. Find the consuming resource (grep the workspace for data_wo / ephemeral "vault_kv_secret_v2").
  2. Increment its data_wo_revision by exactly 1 (helm’s set_wo_revision must strictly increase; kubernetes accepts any change).
  3. Plan/apply the workspace (main-cluster-bootstrap is Local execution — apply manually).
  4. Verify the in-cluster value changed (kubectl get secret ... -o json | jq -S '.data' | sha256sum).

Kubernetes workloads using VaultDynamicSecret automatically rotate PKI certificates:

apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultDynamicSecret
metadata:
name: router-hosts-client-cert
spec:
mount: fzymgc-house/v1/ica1/v1
path: issue/router-hosts-client
destination:
name: router-hosts-client-cert
create: true
renewalPercent: 67

The operator renews certificates at 67% of TTL automatically.

For CLI tools (like router-hosts), certificates must be manually renewed:

Terminal window
# Check certificate expiry
openssl x509 -in ~/.config/router-hosts/tls.crt -text -noout | grep -A2 Validity
# Re-issue certificate (Bash/Zsh)
CERT_DATA=$(vault write -format=json fzymgc-house/v1/ica1/v1/issue/router-hosts-client \
common_name="cli-$(whoami)" ttl=720h)
echo "$CERT_DATA" | jq -r '.data.certificate' > ~/.config/router-hosts/tls.crt
echo "$CERT_DATA" | jq -r '.data.private_key' > ~/.config/router-hosts/tls.key
echo "$CERT_DATA" | jq -r '.data.issuing_ca' > ~/.config/router-hosts/ca.crt
RoleMount PathPurposeDefault TTL
router-hosts-clientfzymgc-house/v1/ica1/v1gRPC client auth720h
router-hosts-serverfzymgc-house/v1/ica1/v1gRPC server cert720h

Developers need infrastructure-developer policy. Defined in tf/vault/policy-infrastructure-developer.hcl:

path "secret/data/fzymgc-house/infrastructure/*" {
capabilities = ["read", "list"]
}
path "secret/metadata/fzymgc-house/infrastructure/*" {
capabilities = ["list"]
}
path "secret/data/fzymgc-house/*" {
capabilities = ["read", "list"]
}
path "secret/metadata/fzymgc-house/*" {
capabilities = ["list"]
}

If Vault is sealed, unseal keys are required. Contact cluster admin.

Check your Vault policy assignments in Keycloak groups.

Terminal window
curl -s https://vault.fzymgc.house/v1/sys/health
vault token lookup
Terminal window
ansible-galaxy collection list | grep hashi_vault
ansible localhost -m debug -a "msg={{ lookup('community.hashi_vault.vault_kv2_get', 'infrastructure/bmc/tpi-alpha', engine_mount_point='secret/fzymgc-house').secret.password }}"
Terminal window
vault token lookup
terraform console
> data.vault_kv_secret_v2.keycloak.data