documentation and fmt
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
terraform {
|
||||
backend "gcs" {
|
||||
bucket = "arcodange-tf"
|
||||
prefix = "tools/hashicorp_vault/main"
|
||||
bucket = "arcodange-tf"
|
||||
prefix = "tools/hashicorp_vault/main"
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
197
hashicorp-vault/iac/modules/README.md
Normal file
197
hashicorp-vault/iac/modules/README.md
Normal 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 qu’une **application déployée dans Kubernetes** puisse :
|
||||
- s’authentifier 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 l’application (notamment les identifiants Postgres).
|
||||
L’objectif 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 à s’authentifier auprès de Vault.
|
||||
|
||||
2. **L’application** (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 l’application.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 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 à l’app) de s’authentifier 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 l’app 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.
|
||||
|
||||
Lorsqu’un nouveau secret est émis, le Deployment ciblé est redémarré pour recharger les variables d’environnement.
|
||||
|
||||
✅ 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.
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
applications = [
|
||||
"webapp",
|
||||
"erp",
|
||||
"webapp",
|
||||
"erp",
|
||||
]
|
||||
@@ -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" {
|
||||
|
||||
Reference in New Issue
Block a user