documentation and fmt
All checks were successful
Helm Charts / Detect changed charts (push) Successful in 16s
Helm Charts / Library charts tool (push) Has been skipped
Helm Charts / Application charts pgcat (push) Has been skipped

This commit is contained in:
2025-08-31 11:33:27 +02:00
parent 3f6604def2
commit be6e6135d7
6 changed files with 230 additions and 33 deletions

View File

@@ -1,6 +1,6 @@
terraform {
backend "gcs" {
bucket = "arcodange-tf"
prefix = "tools/hashicorp_vault/main"
bucket = "arcodange-tf"
prefix = "tools/hashicorp_vault/main"
}
}

View File

@@ -2,8 +2,8 @@ resource "vault_auth_backend" "kubernetes" {
type = "kubernetes"
}
resource "vault_kubernetes_auth_backend_config" "config" {
backend = vault_auth_backend.kubernetes.path
kubernetes_host = "https://kubernetes.default.svc:443"
backend = vault_auth_backend.kubernetes.path
kubernetes_host = "https://kubernetes.default.svc:443"
}
resource "vault_mount" "kvv2" {
@@ -29,18 +29,18 @@ resource "vault_database_secret_backend_connection" "postgres" {
postgresql {
connection_url = "postgresql://{{username}}:{{password}}@pgbouncer.tools:5432/postgres?sslmode=disable"
username = var.POSTGRES_CREDENTIALS_EDITOR_USERNAME
password = var.POSTGRES_CREDENTIALS_EDITOR_PASSWORD
username = var.POSTGRES_CREDENTIALS_EDITOR_USERNAME
password = var.POSTGRES_CREDENTIALS_EDITOR_PASSWORD
}
}
resource "vault_mount" "transit" {
path = "transit"
type = "transit"
description = "Pour le vault secret operator (vso) dans k3s en cas de redemarrage par exemple"
# default_lease_ttl_seconds = 3600
# max_lease_ttl_seconds = 86400
path = "transit"
type = "transit"
description = "Pour le vault secret operator (vso) dans k3s en cas de redemarrage par exemple"
# default_lease_ttl_seconds = 3600
# max_lease_ttl_seconds = 86400
}
resource "vault_transit_secret_backend_key" "vso_client_cache" {
backend = vault_mount.transit.path
@@ -49,17 +49,17 @@ resource "vault_transit_secret_backend_key" "vso_client_cache" {
data "vault_policy_document" "vso_client_cache" {
rule {
path = "${vault_mount.transit.path}/encrypt/${vault_transit_secret_backend_key.vso_client_cache.name}"
path = "${vault_mount.transit.path}/encrypt/${vault_transit_secret_backend_key.vso_client_cache.name}"
capabilities = ["create", "update"]
}
rule {
path = "${vault_mount.transit.path}/decrypt/${vault_transit_secret_backend_key.vso_client_cache.name}"
path = "${vault_mount.transit.path}/decrypt/${vault_transit_secret_backend_key.vso_client_cache.name}"
capabilities = ["create", "update"]
}
}
resource "vault_policy" "vso_client_cache" {
name = "edit-vso-client-cache"
policy = data.vault_policy_document.vso_client_cache.hcl
name = "edit-vso-client-cache"
policy = data.vault_policy_document.vso_client_cache.hcl
}
resource "vault_kubernetes_auth_backend_role" "vso" {
@@ -75,8 +75,8 @@ resource "vault_kubernetes_auth_backend_role" "vso" {
}
module "app_policies" {
source = "./modules/app_policy"
for_each = var.applications
name = each.value
source = "./modules/app_policy"
for_each = var.applications
name = each.value
gitea_app_id = var.gitea_app_id
}

View File

@@ -0,0 +1,197 @@
# Modules
## app_policy
_Ce module à déclarer dans ce projet permet au projet subordonné de déclarer le module app_roles suivant._
Ce module Terraform associe un **projet Git** à un ensemble de ressources Vault :
- Une **policy `-ops`** pour la CI/CD du projet (dépôt Git).
- Une **policy `app`** pour le runtime applicatif (pods).
- Un **groupe Vault** lié au projet. (pour ajouter les utilisateurs vault associé à leur compte gitea)
- Un **rôle JWT Vault** lié à ton SCM (ex: Gitea).
- Les droits nécessaires pour gérer les rôles Kubernetes et Postgres associés au projet.
### 🚀 Usage
```hcl
module "webapp_vault" {
source = "./modules/vault_project"
name = "webapp"
gitea_app_id = "my-gitea-oauth-app-id" # secret récupéré via vault dans la CI
}
```
## app_roles
Ce module Terraform configure les rôles Vault nécessaires pour quune **application déployée dans Kubernetes** puisse :
- sauthentifier auprès de Vault via son `ServiceAccount`,
- obtenir des **identifiants Postgres dynamiques**,
- accéder à ses secrets dans Vault.
### 🚀 Usage
```hcl
module "webapp_vault_app" {
source = "./modules/vault_app"
name = "webapp"
database = "mydb" # optionnel, par défaut = name
}
```
## principe
```lua
+-----------------+
| Dépôt Git |
| (CI/CD Terraform|
+--------+--------+
|
[Auth via Vault JWT Role]
|
+----------v-----------+
| Vault (Policy -ops) |
| - Peut gérer |
| - Roles K8s |
| - Roles Postgres|
| - Secrets KV |
+----------+-----------+
|
[Token éphémère CI/CD]
|
+----------------v----------------+
| Kubernetes API |
| - Applique CRDs / Secrets |
| - Configure Longhorn / RBAC |
+---------------------------------+
--------------------------- Flux runtime ---------------------------
+-----------------+
| Pod App |
| (SA: webapp) |
+--------+--------+
|
[Auth via Vault K8s Role]
|
+----------v-----------+
| Vault (Policy app) |
| - Peut lire |
| - kvv2/data/... |
| - postgres/... |
+---------------------+
|
[Secrets dynamiques: PW DB, etc.]
|
+--------v---------+
| Postgres DB |
+------------------+
```
---
_documentation destinée aux dépots des applications:_
---
# 🔑 Gestion des secrets avec Vault Secrets Operator (VSO)
Ce repository utilise [Vault Secrets Operator](https://developer.hashicorp.com/vault/docs/platform/k8s/vso) pour gérer les secrets de lapplication (notamment les identifiants Postgres).
Lobjectif est déviter de stocker des credentials statiques, en déléguant la génération et la rotation à HashiCorp Vault.
---
## ⚙️ Architecture
1. **Terraform côté admin** configure Vault :
- un **backend Postgres** (`postgres/`) connecté à la base via pgbouncer,
- un **rôle Vault** `webapp` (`postgres/roles/webapp`) qui définit la manière dont les credentials dynamiques sont créés,
- un **rôle Kubernetes** `webapp` (`auth/kubernetes/role/webapp`) qui autorise le ServiceAccount `webapp` du namespace à sauthentifier auprès de Vault.
2. **Lapplication** (dans ce repo) déclare :
- un `VaultAuth` qui associe le **ServiceAccount `webapp`** au rôle Vault `webapp`,
- un `VaultDynamicSecret` qui demande un secret dynamique (`postgres/creds/webapp`),
- un `Secret` Kubernetes généré automatiquement par VSO (`vso-db-credentials`), injecté dans le Pod de lapplication.
---
## 🛠️ Ressources déployées
### `VaultAuth`
```yaml
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: auth
namespace: {{ .Release.Namespace }}
spec:
method: kubernetes
mount: kubernetes
kubernetes:
role: webapp
serviceAccount: {{ include "webapp.serviceAccountName" . }}
audiences:
- vault
```
Permet à VSO (et donc à lapp) de sauthentifier auprès de Vault avec le rôle webapp.
VaultDynamicSecret
```yaml
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultDynamicSecret
metadata:
name: vso-db
namespace: {{ .Release.Namespace }}
spec:
mount: postgres
path: creds/webapp # chemin du rôle dynamique Postgres
destination:
create: true
name: vso-db-credentials
rolloutRestartTargets:
- kind: Deployment
name: {{ include "webapp.fullname" . }}
vaultAuthRef: auth
```
Demande un secret dynamique Postgres depuis Vault et le stocke dans un Secret Kubernetes nommé vso-db-credentials.
Le Deployment de lapp est redémarré automatiquement à chaque rotation de credentials.
📦 Consommation du secret
Une fois VSO en place, les credentials Postgres sont disponibles dans le Secret Kubernetes :
```yaml
apiVersion: v1
kind: Pod
metadata:
name: example
spec:
containers:
- name: app
image: myapp:latest
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: vso-db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: vso-db-credentials
key: password
````
🔄 Rotation
Vault génère des identifiants éphémères (par défaut TTL = 1h).
VSO renouvelle ou régénère automatiquement ces credentials.
Lorsquun nouveau secret est émis, le Deployment ciblé est redémarré pour recharger les variables denvironnement.
✅ Résumé
Pas de secrets stockés en clair dans Git ou Helm.
Rotation automatique des credentials Postgres.
Intégration fluide avec Kubernetes via ServiceAccounts.

View File

@@ -1,16 +1,16 @@
terraform {
required_providers {
vault = {
source = "vault"
version = "4.4.0"
}
required_providers {
vault = {
source = "vault"
version = "4.4.0"
}
}
}
provider vault {
address = "https://vault.arcodange.duckdns.org"
auth_login_jwt { # TERRAFORM_VAULT_AUTH_JWT environment variable
mount = "gitea_jwt"
role = "gitea_cicd"
}
provider "vault" {
address = "https://vault.arcodange.duckdns.org"
auth_login_jwt { # TERRAFORM_VAULT_AUTH_JWT environment variable
mount = "gitea_jwt"
role = "gitea_cicd"
}
}

View File

@@ -1,4 +1,4 @@
applications = [
"webapp",
"erp",
"webapp",
"erp",
]

View File

@@ -2,11 +2,11 @@ variable "gitea_app_id" {
type = string
}
variable "POSTGRES_CREDENTIALS_EDITOR_USERNAME" {
type = string
type = string
sensitive = true
}
variable "POSTGRES_CREDENTIALS_EDITOR_PASSWORD" {
type = string
type = string
sensitive = true
}
variable "applications" {