Gestiamo i secrets di HashiCorp Vault con HashiCorp Terraform
- Gennaro Riccio
- Terraform , Hashicorp , Vault
- August 23, 2023
Terraform, non solo IaC (Infrastructure as Code), chi usa terraform per gestire IaC ne conosce la potenza e la comodità una volta creato lo script per il deploy di una infrastruttura sul cloud e on-prem questo è replicabile all’infinito in diversi ambienti e modificabile per gestire lo scaling ad esempio o semplicamente cambiare le caratteristiche di una infrastruttura in meniera semplice e veloce.
Un approccio diverso ed utilizzare Terraform per gestire un secret mananager quali può essere l’altro prodotto di punta di HashiCorp: Vault
Ingredienti
Di cosa abbiamo bisogno per la Proof of Concept:
- Hashicorp Vault
- Hashicorp Terraform
- Powershell Teminal
Infrastruttura di TEST utilizzata
- Docker Desktop
- Docker Image Hashicorp Vault
- HashiCorp Terraform
- Installazione in locale del tool
Installazione infrastruttura
Riporto brevemente i passaggi per l’installazione dell’infrastruttura su un sistema Windows, per approfondimenti vi rimando ai relativi site e tutorial presenti in rete.
Doker Desktop
E’ possibile installare doker desktop dal site principale: https://www.docker.com/products/docker-desktop/
Installazione semplice non richiede particolari conoscenze tecniche.
Docker Image Vault:
Per l’installazione di Vault basta lanciare la riga sotto
docker run --name Vault --cap-add=IPC_LOCK `
-e 'VAULT_LOCAL_CONFIG={"storage": {"file": {"path": "/vault/file"}}, "listener": [{"tcp": { "address": "0.0.0.0:8200", "tls_disable": true}}], "default_lease_ttl": "168h", "max_lease_ttl": "720h", "ui": true}' `
-p 8200:8200 hashicorp/vault:1.14 server
per i dettagli: https://hub.docker.com/r/hashicorp/vault
HashiCorp Terraform:
Da questo link si può scaricare il tool di terraform: https://developer.hashicorp.com/terraform/downloads?product_intent=terraform
Proof of Concept
Una volta che abbiamo la nostra infrastruttura possiamo in iniziare.
Fondamentali sono 2 variabili di ambiente per poter far dialogare Terraform con Vault:
VAULT_ADDR = endpoint di accesso a Vault nel caso in un installazione su Docker sarà : http://localhost:8200
VAULT_TOKEN = Token di autenticazione su Vault.
Componente fondamentale per Terraform è il provider, nel nostro caso quello di Vault. I provider sono delle astrazioni logiche delle Api dei componenti su cui si deve interagire.
La documentazione completa del provider vault la si può trovare qui: https://registry.terraform.io/providers/hashicorp/vault/latest/docs
Inoltre nel registry di Terraform si possono trovare tutti i provider con cui Terraform interagisce: https://registry.terraform.io/browse/providers
Definiamo il provider vault in questo modo:
provider "vault" {
address = ""
}
lavorando in localhost ed avendo settato la variabile VAULT_ADDR l’address può anche non essere valorizzato. La best practice è valorizzare il campo.
Definiamo il resource di tipologia secret da utilizzare nel caso in esempio la tipologia di secret KV version 2
resource "vault_mount" "kvv2" {
path = "test-project"
type = "kv"
options = { version = "2" }
description = "KV2 secret test-project application"
lifecycle {
ignore_changes = all
}
}
- path dove andremo a salvare i secrets in vault nel nostro caso ’test-project'
- type key value secret (kv) e la versione = 2 definita in options.
- Lifecyle essendo la resource unica e in teoria non modificabile si utilizza il lifecycle ingnore_changes in modo che non si possano fare modifiche alla resource.
A questo punto siamo pronti per definire il resource del secret:
resource "vault_kv_secret_v2" "test" {
mount = vault_mount.kvv2.path
name = "secret-test"
cas = 1
delete_all_versions = false
data_json = file("data.json")
custom_metadata {
max_versions = 5
}
}
- mount è il resuorce dove è definito il secret.
- name è il nome del secret da salvare.
- data_json il file json che contiene i secrets.
e nel custom_metadata definiamo quante versioni vogliamo tenere nello storico, in questo caso 5.
Se lavorate con la versione Enterprice di Vault avete a disposizione nella definizione dei resource anche il tag NAMESPACE per poter gestire i secret nei namespace di Vault.
La parte importante per l’automazione è il file data_json in questo file sono contenuti i secrets. Esempio di file json key/value dei nostri secrets legati al path test-project/secret-test
{
"zip":"pippo",
"foo":"pluto",
"zep":"lippa",
}
Il nostro file PutSecrets.tf finale è questo:
Verifichiamo la connesione verso Vault interrogando la lista dei secrets:
vault secrets list
Inizializziamo il workspace di terraform con il comando
terraform init
Come possiamo osservare automaticamente il provider viene scaricato per poter essere pronto a gestire i nostri secrets. Tramite il conmando Plan abbiamo la possibilità di verificare che il nostro script sia corretto.
Infine applichiamo lo script per poter salvare i nostri secret in Vault tramite il comando apply lanciamo lo script:
terraform apply -auto-approve
- -auto-approve permette l’esecuzione senza l’attesa uamana di conferma.
il gioco è fatto avremo nel nostro secret manager vault i secrets salvati:
vault kv get test-project/secret-test
ed il gioco è fatto.
Conclusioni
Abbiamo visto un uso alternativo di quello che di solito si vede in giro, ovvero deployare VM o reti con Terraform. Questo è ovviamente un piccolo esempio che può essere ampliato a dismisura ed esempio aggiungendo variabili che possono essere sostituite in maniera dinamica, cripatare/decriptare i file Json dei secret utilizzando Vault Transit, impletare il processo in un tool di CI/CD come sono ad esempio GitLab o Octopus Deploy e così via. Si può spaziare varamente su vari fronti, ritengo che Terreform è uno strumento che nella borsa di DevOps deve essere prensete.