a960757ab2
Why: teabot's implementer and reviewer bot users should mint ephemeral, scoped Gitea tokens on demand instead of holding standing personal access tokens (Gitea tokens never expire on their own). This registers and mounts the new vault-plugin-secrets-gitea engine and declares its roles, mirroring the rancher engine wiring. Change: - Register the plugin in the catalog (config/plugins/vault-plugin-secrets-gitea.yaml) pinned to the released v0.1.0 binary sha256. - Add gitea_secret_backend + gitea_secret_backend_role modules and wire them through config.hcl, terragrunt.hcl, and vault_cluster variables/main, using the giteavaultsecret provider (terraform-unkin registry, v0.1.0). - Mount the engine at gitea/ against https://git.unkin.net; seeded site-admin credentials are read from KV (service/vault/au/syd1/secret_backend/gitea/config). - Add teabot-implementer (write:repository, write:issue) and teabot-reviewer (read:repository, write:issue) roles, ttl 1h / max_ttl 4h. Claude-Session: https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
257 lines
11 KiB
HCL
257 lines
11 KiB
HCL
# =============================================================================
|
|
# VAULT MODULE CONFIGURATION SYSTEM
|
|
# =============================================================================
|
|
#
|
|
# This file automatically discovers and organizes YAML configuration files
|
|
# for Vault modules, creating structured configuration maps for Terraform.
|
|
#
|
|
# HOW IT WORKS:
|
|
# 1. Scans all subdirectories for *.yaml files
|
|
# 2. Groups files by module type based on directory structure
|
|
# 3. Creates unique resource keys to prevent naming conflicts
|
|
# 4. Adds computed fields like name, backend, etc. from file paths
|
|
#
|
|
# DIRECTORY STRUCTURE:
|
|
# config/
|
|
# ├── auth_approle_role/
|
|
# │ └── approle/
|
|
# │ ├── certmanager.yaml # Creates key: "approle/certmanager"
|
|
# │ └── myapp.yaml # Creates key: "approle/myapp"
|
|
# ├── auth_kubernetes_role/
|
|
# │ └── k8s/au/syd1/
|
|
# │ ├── default.yaml # Creates key: "k8s/au/syd1/default"
|
|
# │ └── myapp.yaml # Creates key: "k8s/au/syd1/myapp"
|
|
# └── kv_secret_backend/
|
|
# ├── kv.yaml # Creates key: "kv"
|
|
# └── secrets.yaml # Creates key: "secrets"
|
|
#
|
|
# EXAMPLE YAML FILE (config/auth_approle_role/approle/myapp.yaml):
|
|
# ```yaml
|
|
# token_ttl: 3600
|
|
# token_max_ttl: 7200
|
|
# bind_secret_id: true
|
|
# token_bound_cidrs:
|
|
# - "10.0.0.0/8"
|
|
# ```
|
|
#
|
|
# This becomes:
|
|
# ```hcl
|
|
# auth_approle_role = {
|
|
# "approle/myapp" = {
|
|
# approle_name = "myapp" # Auto-computed from filename
|
|
# mount_path = "approle" # Auto-computed from directory
|
|
# token_ttl = 3600 # From YAML content
|
|
# token_max_ttl = 7200 # From YAML content
|
|
# bind_secret_id = true # From YAML content
|
|
# token_bound_cidrs = ["10.0.0.0/8"]
|
|
# }
|
|
# }
|
|
# ```
|
|
#
|
|
# KEY NAMING PATTERNS:
|
|
# - Simple backends: filename only (e.g., "kv", "transit")
|
|
# - Role-based resources: full path without extension (e.g., "approle/myapp")
|
|
# - This ensures uniqueness when multiple backends have similar role names
|
|
#
|
|
# GENERATED OUTPUTS:
|
|
# - config.auth_approle_backend, config.auth_approle_role, etc.
|
|
# - Each module gets its own map with properly structured configuration
|
|
#
|
|
# =============================================================================
|
|
|
|
locals {
|
|
# Find all YAML files in subdirectories
|
|
config_files = fileset(".", "**/*.yaml")
|
|
|
|
# Create a flat map of all files with their content
|
|
all_configs = {
|
|
for file_path in local.config_files :
|
|
file_path => yamldecode(file(file_path))
|
|
}
|
|
|
|
# Group by module directory (first part of path)
|
|
config = {
|
|
auth_approle_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(basename(file_path), ".yaml") => content
|
|
if startswith(file_path, "auth_approle_backend/")
|
|
}
|
|
auth_approle_role = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "auth_approle_role/", ""), ".yaml") => merge(content, {
|
|
approle_name = trimsuffix(basename(file_path), ".yaml")
|
|
mount_path = split("/", replace(file_path, "auth_approle_role/", ""))[0]
|
|
})
|
|
if startswith(file_path, "auth_approle_role/")
|
|
}
|
|
auth_ldap_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(basename(file_path), ".yaml") => content
|
|
if startswith(file_path, "auth_ldap_backend/")
|
|
}
|
|
auth_ldap_group = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "auth_ldap_group/", ""), ".yaml") => merge(content, {
|
|
groupname = trimsuffix(basename(file_path), ".yaml")
|
|
backend = split("/", replace(file_path, "auth_ldap_group/", ""))[0]
|
|
})
|
|
if startswith(file_path, "auth_ldap_group/")
|
|
}
|
|
auth_kubernetes_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "auth_kubernetes_backend/", ""), ".yaml") => content
|
|
if startswith(file_path, "auth_kubernetes_backend/")
|
|
}
|
|
auth_kubernetes_role = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "auth_kubernetes_role/", ""), ".yaml") => merge(content, {
|
|
role_name = trimsuffix(basename(file_path), ".yaml")
|
|
backend = dirname(replace(file_path, "auth_kubernetes_role/", ""))
|
|
})
|
|
if startswith(file_path, "auth_kubernetes_role/")
|
|
}
|
|
kv_secret_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(basename(file_path), ".yaml") => content
|
|
if startswith(file_path, "kv_secret_backend/")
|
|
}
|
|
transit_secret_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(basename(file_path), ".yaml") => content
|
|
if startswith(file_path, "transit_secret_backend/")
|
|
}
|
|
transit_secret_backend_key = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "transit_secret_backend_key/", ""), ".yaml") => merge(content, {
|
|
name = trimsuffix(basename(file_path), ".yaml")
|
|
backend = dirname(replace(file_path, "transit_secret_backend_key/", ""))
|
|
})
|
|
if startswith(file_path, "transit_secret_backend_key/")
|
|
}
|
|
ssh_secret_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(basename(file_path), ".yaml") => content
|
|
if startswith(file_path, "ssh_secret_backend/")
|
|
}
|
|
ssh_secret_backend_role = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "ssh_secret_backend_role/", ""), ".yaml") => merge(content, {
|
|
name = trimsuffix(basename(file_path), ".yaml")
|
|
backend = dirname(replace(file_path, "ssh_secret_backend_role/", ""))
|
|
})
|
|
if startswith(file_path, "ssh_secret_backend_role/")
|
|
}
|
|
pki_secret_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "pki_secret_backend/", ""), ".yaml") => content
|
|
if startswith(file_path, "pki_secret_backend/")
|
|
}
|
|
pki_secret_backend_role = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "pki_secret_backend_role/", ""), ".yaml") => merge(content, {
|
|
name = trimsuffix(basename(file_path), ".yaml")
|
|
backend = dirname(replace(file_path, "pki_secret_backend_role/", ""))
|
|
})
|
|
if startswith(file_path, "pki_secret_backend_role/")
|
|
}
|
|
kubernetes_secret_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "kubernetes_secret_backend/", ""), ".yaml") => content
|
|
if startswith(file_path, "kubernetes_secret_backend/")
|
|
}
|
|
kubernetes_secret_backend_role = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "kubernetes_secret_backend_role/", ""), ".yaml") => merge(content, {
|
|
name = trimsuffix(basename(file_path), ".yaml")
|
|
backend = dirname(replace(file_path, "kubernetes_secret_backend_role/", ""))
|
|
})
|
|
if startswith(file_path, "kubernetes_secret_backend_role/")
|
|
}
|
|
consul_secret_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "consul_secret_backend/", ""), ".yaml") => content
|
|
if startswith(file_path, "consul_secret_backend/")
|
|
}
|
|
consul_secret_backend_role = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "consul_secret_backend_role/", ""), ".yaml") => merge(content, {
|
|
name = trimsuffix(basename(file_path), ".yaml")
|
|
backend = dirname(replace(file_path, "consul_secret_backend_role/", ""))
|
|
})
|
|
if startswith(file_path, "consul_secret_backend_role/")
|
|
}
|
|
pki_mount_only = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(basename(file_path), ".yaml") => content
|
|
if startswith(file_path, "pki_mount_only/")
|
|
}
|
|
litellm_secret_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(basename(file_path), ".yaml") => content
|
|
if startswith(file_path, "litellm_secret_backend/")
|
|
}
|
|
litellm_secret_backend_role = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "litellm_secret_backend_role/", ""), ".yaml") => merge(content, {
|
|
name = trimsuffix(basename(file_path), ".yaml")
|
|
backend = dirname(replace(file_path, "litellm_secret_backend_role/", ""))
|
|
})
|
|
if startswith(file_path, "litellm_secret_backend_role/")
|
|
}
|
|
plugins = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(basename(file_path), ".yaml") => merge(content, {
|
|
name = trimsuffix(basename(file_path), ".yaml")
|
|
})
|
|
if startswith(file_path, "plugins/")
|
|
}
|
|
gpg_secret_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(basename(file_path), ".yaml") => content
|
|
if startswith(file_path, "gpg_secret_backend/")
|
|
}
|
|
gpg_key = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "gpg_key/", ""), ".yaml") => merge(content, {
|
|
name = trimsuffix(basename(file_path), ".yaml")
|
|
backend = dirname(replace(file_path, "gpg_key/", ""))
|
|
})
|
|
if startswith(file_path, "gpg_key/")
|
|
}
|
|
rancher_secret_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(basename(file_path), ".yaml") => content
|
|
if startswith(file_path, "rancher_secret_backend/")
|
|
}
|
|
rancher_secret_backend_service_account = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "rancher_secret_backend_service_account/", ""), ".yaml") => merge(content, {
|
|
name = trimsuffix(basename(file_path), ".yaml")
|
|
backend = dirname(replace(file_path, "rancher_secret_backend_service_account/", ""))
|
|
})
|
|
if startswith(file_path, "rancher_secret_backend_service_account/")
|
|
}
|
|
rancher_secret_backend_role = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "rancher_secret_backend_role/", ""), ".yaml") => merge(content, {
|
|
name = trimsuffix(basename(file_path), ".yaml")
|
|
backend = dirname(replace(file_path, "rancher_secret_backend_role/", ""))
|
|
})
|
|
if startswith(file_path, "rancher_secret_backend_role/")
|
|
}
|
|
gitea_secret_backend = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(basename(file_path), ".yaml") => content
|
|
if startswith(file_path, "gitea_secret_backend/")
|
|
}
|
|
gitea_secret_backend_role = {
|
|
for file_path, content in local.all_configs :
|
|
trimsuffix(replace(file_path, "gitea_secret_backend_role/", ""), ".yaml") => merge(content, {
|
|
name = trimsuffix(basename(file_path), ".yaml")
|
|
backend = dirname(replace(file_path, "gitea_secret_backend_role/", ""))
|
|
})
|
|
if startswith(file_path, "gitea_secret_backend_role/")
|
|
}
|
|
}
|
|
}
|