
Gestire i secret in modo nativo in Kubernetes non è una scelta sicura: i secret in Kubernetes sono semplicemente testo in chiaro codificato in base64, accessibile da un pod in esecuzione.
Disclaimer:
Questo tutorial è pensato per farvi capire, passo dopo passo, ogni componente della configurazione. Nulla vi vieta di usare terraform per replicarla, ma affrontare alla cieca un setup così delicato porta a problemi che, senza una conoscenza approfondita, sono molto più difficili da risolvere.

È vero, è possibile cifrare un secret in Kubernetes, ma quel secret risulta cifrato solo a riposo: una volta montato nel Pod, diventa un semplice file o una variabile d'ambiente facilmente accessibile dall'interno del Pod stesso. In caso di violazione, i dati sono compromessi se qualcuno ottiene accesso al Pod o al namespace in cui gira tramite kubectl.
Hashicorp Vault è un modo sicuro per gestire i secret e per fare audit e revoca degli accessi. Una cosa è installare e usare Vault, un'altra è consumare quei secret all'interno di un Pod.
Questo articolo si concentra sull'installazione di Vault su GKE con Terraform e Helm; per il consumo dei secret potete approfondire leggendo l'altro mio articolo su come consumare i secret di Vault in modo trasparente da un Pod.
Questo approccio è più semplice da gestire se vi serve solo Vault e non avete bisogno delle funzionalità avanzate di Consul, come Consul template con Vault.
Nel tutorial vedremo come installare un Vault in alta disponibilità usando Google Cloud Storage (GCS) come backend di Vault, con TLS end-to-end.
Nota:
È buona prassi creare un setup di Vault per ogni ambiente, così da testare meglio gli aggiornamenti e tenere gli ambienti separati tra loro.
Sconsiglio di esporre Vault come servizio; per accedervi potete usare il comando:
$ kubectl port-forward vault-0 8200:8200e raggiungere la UI tramite https://127.0.0.1:8200, come spiegato più avanti.
Se avete delle VM che devono accedere a Vault, conviene usare il VPC peering, dato che servizi e pod hanno IP nativi: aspetto non trattato qui.
Tutorial:
In sintesi:
- Creare i certificati TLS per Vault
- Creare un bucket GCS per il backend di storage di Vault
- Creare il keyring KMS e la chiave di cifratura per l'auto-unseal di Vault
- Creare i service account perché Vault possa accedere a KMS e al backend GCS
- Installare l'Helm chart ufficiale di Hashicorp Vault tramite helm tillerless
Creazione dei certificati TLS per Vault:

Una delle raccomandazioni di hardening per la produzione è cifrare con TLS le comunicazioni tra Vault e i client, sia in ingresso che in uscita.
Creeremo un certificato che verrà utilizzato per:
- L'indirizzo del servizio Vault in Kubernetes
- 127.0.0.1
Per generare questi certificati useremo il CloudFlare SSL toolkit ( cfssl e cfssljson).
L'installazione richiede una installazione funzionante di Go 1.12+ e una corretta impostazione di GOPATH.
Importante: assicuratevi che la directory bin di GOPATH sia nel vostro PATH:
export PATH=$GOPATH/bin:$PATHInstallazione del CloudFlare SSL ToolKit:
go get -u github.com/cloudflare/cfssl/cmd/cfsslgo get -u github.com/cloudflare/cfssl/cmd/cfssljsonInizializzare una Certificate Authority (CA):
$ mkdir vault-ca && cd vault-caCreate i file della CA:
File di configurazione della CA con scadenza a 5 anni
$ cat <<EOF > ca-config.json{ "signing": { "default": { "expiry": "8760h" }, "profiles": { "default": { "usages": ["signing", "key encipherment", "server auth", "client auth"], "expiry": "8760h" } } }}EOFCertificate Signing Request della CA:
$ cat <<EOF > ca-csr.json{ "hosts": [\ "cluster.local"\ ], "key": { "algo": "rsa", "size": 2048 }, "names": [\ {\ "C": "US",\ "L": "NewYork",\ "O": "Kubernetes",\ "OU": "CA",\ "ST": "NewYork"\ }\ ]}EOFCertificate Signing Request di VAULT, da firmare con la CA appena creata: nota: cambiate il namespace di Vault se non è quello di default
$ cat <<EOF > vault-csr.json{ "CN": "Vault-GKE", "hosts": [\ "127.0.0.1",\ "vault.default.svc.cluster.local"\ ], "key": { "algo": "rsa", "size": 2048 }, "names": [\ {\ "C": "US",\ "L": "NewYork",\ "O": "Innovia",\ "OU": "Vault",\ "ST": "NewYork"\ }\ ]}EOFNaturalmente potete personalizzare i dati del certificato nella sezione "names" in fondo come preferite.
Eseguite il comando seguente per inizializzare la CA usando il file appena creato:
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca2019/11/12 16:35:01 [INFO] generating a new CA key and certificate from CSR2019/11/12 16:35:01 [INFO] generate received request2019/11/12 16:35:01 [INFO] received CSR2019/11/12 16:35:01 [INFO] generating key: rsa-20482019/11/12 16:35:01 [INFO] encoded CSR2019/11/12 16:35:01 [INFO] signed certificate with serial number 425581644650417483788325060652779897454211028144Generate una chiave privata e firmate il certificato TLS:
$ cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ -profile=default \ vault-csr.json | cfssljson -bare vault2019/11/12 16:36:33 [INFO] generate received request2019/11/12 16:36:33 [INFO] received CSR2019/11/12 16:36:33 [INFO] generating key: rsa-20482019/11/12 16:36:34 [INFO] encoded CSR2019/11/12 16:36:34 [INFO] signed certificate with serial number 311973563616303179057952194819087555625015840298A questo punto, nella directory di lavoro corrente dovreste trovare i seguenti file:
ca-key.pemca.pemvault-key.pemvault.pemconservate al sicuro i file della CA: vi serviranno per rifirmare il certificato alla scadenza (la CA ha durata 5 anni, Vault 1 anno).
Create un secret per il TLS di Vault e per il CA.pem:
kubectl create secret generic vault-tls \ --from-file=ca.pem \ --from-file=vault.pem \ --from-file=vault-key.pemImpostate il progetto GCP per il resto del tutorial:
$ export GCP_PROJECT=<your_project_id>Abilitazione delle API GCP necessarie:
$ gcloud services enable \ cloudapis.googleapis.com \ cloudkms.googleapis.com \ container.googleapis.com \ containerregistry.googleapis.com \ iam.googleapis.com \ --project ${GCP_PROJECT}Operation "operations/acf.8e126724-bbde-4c0d-b516-5dca5b8443ee" finished successfully.Backend di storage di Vault
Google Cloud Storage
In modalità HA, i server Vault hanno due stati aggiuntivi: standby e active. All'interno di un cluster Vault, una sola istanza è active e gestisce tutte le richieste (lettura e scrittura), mentre i nodi standby reindirizzano le richieste al nodo active.
Creiamo il bucket su GCS con il comando gsutil. I nomi dei bucket devono essere unici a livello globale su tutto Google Cloud, quindi sceglietene uno univoco:
$ export GCS_BUCKET_NAME=mycompany-vault-data$ gsutil mb gs://$GCS_BUCKET_NAME$ gsutil versioning set on gs://$GCS_BUCKET_NAMEAnche se i dati sono cifrati in transito e a riposo, impostate sul bucket permessi adeguati per ridurre l'esposizione. Conviene creare un service account che, tramite permessi IAM, limiti le interazioni di Vault con Google Cloud ai soli oggetti del bucket di storage.
Auto-unseal di Vault

Quando Vault viene riavviato, parte in stato sealed e cifrato. Per usarlo bisogna fare l'unseal; esiste una funzionalità relativamente nuova chiamata auto-unseal, che legge automaticamente le master key e il root token da CloudKMS.
Creare il KMS Keyring e la Crypto Key:
In questa sezione creeremo il keyring KMS e la chiave per cifrare e decifrare le master key e il root token di Vault.
Create il keyring KMS vault-helm-unseal-kr:
$ gcloud kms keyrings create vault-helm-unseal-kr \ --location global \ --project ${GCP_PROJECT}Create la chiave di cifratura:
$ gcloud kms keys create vault-helm-unseal-key \ --location global \ --keyring vault-helm-unseal-kr \ --purpose encryption \ --project ${GCP_PROJECT}Creare i service account GCP e i permessi IAM per Vault
Impostazione delle variabili:
$ export VAULT_SA_NAME=vault-server; export VAULT_SA=$VAULT_SA_NAME@$GCP_PROJECT.iam.gserviceaccount.comCreate il service account del server Vault:
$ gcloud iam service-accounts create $VAULT_SA_NAME \ --display-name "Vault server service account" \ --project ${GCP_PROJECT}Generate la chiave del service account del server Vault (file JSON delle credenziali):
$ gcloud iam service-accounts keys create \ --iam-account $VAULT_SA /tmp/vault_gcs_key.jsoncreated key [be22cfe6e30f3a3fcfc6ebaa23ca3ba905dd60ab] of type [json] as [/tmp/vault_gcs_key.json] for [[email protected]] Create il secret in cui salvare il service account Google di Vault$ kubectl create secret generic vault-gcs \ --from-file=/tmp/vault_gcs_key.jsonsecret/vault-gcs createdConcedete a Vault l'accesso al bucket GCS di storage:
$ gsutil iam ch \ serviceAccount:${VAULT_SA}:objectAdmin \ gs://${GCS_BUCKET_NAME}Concedete l'accesso alla chiave KMS di Vault:
$ gcloud kms keys add-iam-policy-binding \ vault-helm-unseal-key \ --location global \ --keyring vault-helm-unseal-kr \ --member serviceAccount:${VAULT_SA} \ --role roles/cloudkms.cryptoKeyEncrypterDecrypter \ --project ${GCP_PROJECT}Updated IAM policy for key [vault-helm-unseal-key].bindings:- members: - serviceAccount:[email protected] role: roles/cloudkms.cryptoKeyEncrypterDecrypteretag: BwWZ6sIYovk=version: 1Nota:se per qualche motivo avete eliminato e ricreato il service account, dovete eliminare la policy IAM sulla chiave; altrimenti passate direttamente alla sezione Get the vault hashicorp official chart$ gcloud kms keys get-iam-policy vault-helm-unseal-key --location global --keyring vault-helm-unseal-kr > kms-policy.yaml modificate il file della policy rimuovendo i membri sotto binding e poi salvate il filebindings:etag: BwWXQz4HjuI=version: 1Riapplicate la policy:
$ gcloud kms keys set-iam-policy vault-helm-unseal-key --location global --keyring vault-helm-unseal-kr kms-policy.yamlScaricate l'Helm chart ufficiale Hashicorp di Vault:

nota:
dalla versione 0.3.0 esiste un'integrazione di Vault con Kubernetes che inietta automaticamente i secret nei Pod renderizzandoli come file su un volume. Consiglio comunque di usare il mio vault secrets webhook: è un modo più sicuro di iniettare un secret in un Pod e automatizza anche il consumo dei secret.
export CHART_VERSION=0.3.0Scaricate il chart e scompattatelo:
$ wget https://github.com/hashicorp/vault-helm/archive/v$CHART_VERSION.tar.gz && tar zxf v$CHART_VERSION.tar.gz && rm v$CHART_VERSION.tar.gzConfigurazione del file values.yaml del chart:
Il gist seguente contiene placeholder per la sostituzione delle variabili.
global: tlsDisable: false
server: extraEnvironmentVars: GOOGLE_APPLICATION_CREDENTIALS: /vault/userconfig/vault-gcs/vault_gcs_key.json extraVolumes: - type: secret name: vault-gcs path: "/vault/userconfig" - type: secret name: vault-tls path: "/etc/tls"
authDelegator: enabled: true
ha: enabled: true config: | ui = true listener "tcp" { tls_disable = 0 tls_cert_file = "/etc/tls/vault-tls/vault.pem" tls_key_file = "/etc/tls/vault-tls/vault-key.pem" tls_client_ca_file = "/etc/tls/vault-tls/ca.pem" tls_min_version = "tls12" address = "[::]:8200" cluster_address = "[::]:8201" } storage "gcs" { bucket = "GCS_BUCKET_NAME" ha_enabled = "true" } seal "gcpckms" { project = "GCP_PROJECT" region = "global" key_ring = "vault-helm-unseal-kr" crypto_key = "vault-helm-unseal-key" }Usate il comando seguente per generare un nuovo file values chiamato vault-gke-values.yaml:
$ curl -s https://gist.githubusercontent.com/innovia/53c05bf69312706fc93ffe3bb685b223/raw/adc169605984da8ba82082191c8f631579b1b199/vault-gke-values.yaml | sed "s/GCP_PROJECT/$GCP_PROJECT/g" | sed "s/GCS_BUCKET_NAME/$GCS_BUCKET_NAME/g" > vault-helm-$CHART_VERSION/vault-gke-values.yamlVerificate il file creato per assicurarvi che project e bucket GCS siano corretti.
$ cat vault-helm-$CHART_VERSION/vault-gke-values.yaml | grep -E 'bucket|project'bucket = "<COMPANY>-vault-data"project = "ami-playground"Con helm 2.x:
Se non avete tiller installato sul cluster, potete saltare la sua configurazione installando il plugin tillerless per helm, che avvia un tiller locale sul vostro computer e lo rende disponibile a helm. Altrimenti passate alla sezione install the vault chart più sotto.
Installare il plugin tillerless di helm:
se non avete ancora helm, installatelo con:
$ brew install helm@2Inizializzate solo il client, in modo da non installare il server tiller:
helm init --client-onlyinstallare il plugin helm-tillerlesshelm plugin install https://github.com/rimusz/helm-tilleravviare tiller tramite helm$ helm tiller startInstalled Helm version v2.16.1Copied found /usr/local/bin/tiller to helm-tiller/binHelm and Tiller are the same version!Starting Tiller...Tiller namespace: kube-systemCon helm 3
$ brew install helmInstallazione del chart di Vault:
nota: con helm 3, l'output non elenca le risorse.
$ helm upgrade --install vault -f vault-helm-$CHART_VERSION/vault-gke-values.yaml vault-helm-$CHART_VERSIONrelease "vault" does not exist. Installing it now.NAME: vaultLAST DEPLOYED: Wed Nov 13 15:41:55 2019NAMESPACE: defaultSTATUS: DEPLOYEDRESOURCES:==> v1/ConfigMapNAME AGEvault-config 0s==> v1/ServiceNAME AGEvault 0s==> v1/ServiceAccountNAME AGEvault 0s==> v1/StatefulSetNAME AGEvault 0s==> v1beta1/ClusterRoleBindingNAME AGEvault-server-binding 0s==> v1beta1/PodDisruptionBudgetNAME AGEvault 0sNOTES:Thank you for installing HashiCorp Vault!Now that you have deployed Vault, you should look over the docs on usingVault with Kubernetes available here:https://www.vaultproject.io/docs/Your release is named vault. To learn more about the release, try:$ helm status vault $ helm get vaultVault dovrebbe partire e trovarsi in stato non inizializzato.I warning seguenti sono normali, dato che Vault non è ancora stato inizializzato:
=> Vault server started! Log data will stream in below:2019-12-17T19:07:37.937Z [INFO] proxy environment: http_proxy= https_proxy= no_proxy=2019-12-17T19:07:38.909Z [INFO] core: stored unseal keys supported, attempting fetch2019-12-17T19:07:39.037Z [WARN] failed to unseal core: error="stored unseal keys are supported, but none were found"2019-12-17T19:07:44.038Z [INFO] core: stored unseal keys supported, attempting fetch2019-12-17T19:07:44.080Z [INFO] core: autoseal: seal configuration missing, but cannot check old path as core is sealed: seal_type=recovery2019-12-17T19:07:44.174Z [WARN] failed to unseal core: error="stored unseal keys are supported, but none were found"---kubectl describe pod vault-0Events: Type Reason Age From Message ---- ------ ---- ---- ------- ... Warning Unhealthy 3s (x9 over 27s) kubelet, minikube Readiness probe failed: Key ValueInizializzare Vault con l'auto-unseal su KMS
Aprite un port-forward verso Vault con il comando:
$ kubectl port-forward vault-0 8200:8200 > /dev/null & export PID=$!; echo "vault port-forward pid: $PID"Connettetevi a Vault usando il certificato CA.pem:
$ export VAULT_ADDR=https://127.0.0.1:8200; export VAULT_CACERT=$PWD/ca.pemmy vault ca.pem for example is at:VAULT_CACERT: /Users/ami/vault-gke-medium/ca.pemInstallate il client Vault (assicuratevi che sia della stessa versione del server):
$ brew install vaultVerificate lo stato:
$ vault statusKey Value--- -----Recovery Seal Type gcpckmsInitialized falseSealed trueTotal Recovery Shares 0Threshold 0Unseal Progress 0/0Unseal Nonce n/aVersion n/aHA Enabled trueOra inizializzate Vault:
vault operator initRecovery Key 1: 33nCanHWgYMR/VPj6bNQdHXJiayL6WeB8Ourx4kHYNaXRecovery Key 2: IMf7RjptFxtGQUbEWUWehanCBiSY7VhElkM7rRVxczGcRecovery Key 3: zGuzk/PhNet9OHL4cW2H7d3XypDxfwWXkmajclLPklK4Recovery Key 4: nCFS0dt0cNGB2LWk0F+3Vmz9TbVNpeIsXbIXDbRarlnTRecovery Key 5: 9GxXr/6T8OJWJrWqyHQxayR0BAK+WTdbT870AzKEFl2VInitial Root Token: s.1ukhSgycySjZUJRD0bZjSEitSuccess! Vault is initializedRecovery key initialized with 5 key shares and a key threshold of 3. Pleasesecurely distribute the key shares printed above.Conservate al sicuro queste chiavi.
Rendere attendibile la Certificate Authority self-signed:
Avendo creato noi stessi il file ca.pem, non sarà considerato attendibile, perché non fa parte del bundle di CA preinstallato sul vostro computer.
Possiamo aggiungerlo come trusted seguendo le istruzioni qui sotto, in base al sistema operativo.
macOS:
Impostando "always trust" sulla CA potrete aprire la UI di Vault dal browser senza errori:
$ sudo security add-trusted-cert -d -k /Library/Keychains/System.keychain $VAULT_CACERTWindows 10:
Seguite queste istruzioni per aggiungere il certificato ai trusted publishers:
Configurare l'autenticazione con backend Kubernetes su Vault
Ora che Vault è attivo e in alta disponibilità, possiamo collegarlo a Kubernetes.
Useremo un service account per il login iniziale di Vault verso Kubernetes.
Il token di questo service account verrà configurato all'interno di Vault tramite la CLI di Vault.
Questo service account ha un permesso speciale, "system:auth-delegator", che permette a Vault di passare a Kubernetes il service account del pod per l'autenticazione; una volta autenticato, Vault restituisce un login token al client, che dialogherà con Vault per ottenere i secret di cui ha bisogno.
Il client userà il login token per autenticarsi su Vault e ottenere il secret.
Vault verificherà il mapping tra ruolo Vault, service account, namespace e policy per consentire o negare l'accesso.
Creiamo dunque il service account vault-reviewer.
https://gist.github.com/innovia/5435f2336e4dd0045dbb5842880b3334#file-vault-reviewer-yaml
Nota: se avete configurato Vault in un altro namespace, ricordate di aggiornare di conseguenza questo file.
kubectl apply -f vault-reviewer.yamlAbilitate il backend di autenticazione Kubernetes:
$ vault login$ vault auth enable kubernetesSuccess! Enabled kubernetes auth method at: kubernetes/Configurare Vault con il token e la ca di vault-reviewer:
nota: se avete configurato Vault in un altro namespace, aggiungete il flag -n dopo ogni comando kubectl.
$ VAULT_SA_TOKEN_NAME=$(kubectl get sa vault-reviewer -o jsonpath="{.secrets[*]['name']}")$ SA_JWT_TOKEN=$(kubectl get secret "$VAULT_SA_TOKEN_NAME" -o jsonpath="{.data.token}" | base64 --decode; echo)$ SA_CA_CRT=$(kubectl get secret "$VAULT_SA_TOKEN_NAME" -o jsonpath="{.data['ca\.crt']}" | base64 --decode; echo)$ vault write auth/kubernetes/config token_reviewer_jwt="$SA_JWT_TOKEN" kubernetes_host=https://kubernetes.default kubernetes_ca_cert="$SA_CA_CRT"Success! Data written to: auth/kubernetes/configRequisiti minimi perché un pod possa accedere a un secret:
- il Pod deve avere un service account
- il secret CA.pem di Vault deve esistere nel namespace in cui gira il Pod
- deve esistere una policy con almeno il permesso di lettura sul secret
path "secret/foo" { capabilities = ["read"]}- deve essere creato un ruolo Vault all'interno di Vault:
vault write auth/kubernetes/role/<role_name> \ bound_service_account_names=<service_account_name> \ bound_service_account_namespaces=<service_account_namespace> \ policies=<policy_name>Si conclude così il setup di Hashicorp Vault su GKE; consiglio vivamente di configurare i vault secrets webhooks per consumare i secret di Vault in modo trasparente, basandosi solo su poche annotazioni.
Come configurare la UI di Vault con Identity-Aware Proxy (IAP) tramite un load balancer

Identity-aware proxy permette di autenticare un utente senza dover configurare una VPN o un Bastion SSH.
Se volete configurare un load balancer per il servizio con identity-aware proxy, seguite i passi qui sotto; altrimenti potete accedere alla UI di Vault tramite kubectl port-forward vault-0 8200.
Il processo seguente non lega in alcun modo un utente Google a Vault: serve solo come autenticazione multi-fattore. Esiste un modo per usare JWT come autenticazione su Vault, ma permetterebbe a qualsiasi utente del vostro dominio di scegliere un ruolo, soluzione meno sicura…
Nota:
Vi serve comunque il certificato self-signed per il servizio Vault stesso; il certificato del load balancer è necessario per abilitare IAP e https.
Prerequisiti:
- Va creato un certificato per il load balancer tramite Google Managed certificate, oppure come secret Kubernetes.
https://cloud.google.com/load-balancing/docs/ssl-certificates
- Il dominio deve essere verificato tramite gli strumenti per webmaster di Google
- Vanno creati un IP statico globale e un record DNS
(se usate il servizio externalDNS, non serve)
$ gcloud compute addresses create vault-ui --globalPotete creare un certificato con il seguente YAML:
https://gist.github.com/innovia/71c219692b003e97bc72feeeb5bc8442
$ kubectl apply -f managed-cert.yamlUna volta creato, attendete 15-20 minuti che lo stato passi da Provisioning ad Active.
Verificate lo stato del certificato:
$ kubectl describe ManagedCertificate vault-ui-certificateName: vault-ui-certificateNamespace: defaultLabels: <none>Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"networking.gke.io/v1beta1","kind":"ManagedCertificate","metadata":{"annotations":{},"name":"vault-ui-certificate","namespac...API Version: networking.gke.io/v1beta1Kind: ManagedCertificateMetadata: Creation Timestamp: 2020-01-13T23:10:28Z Generation: 3 Resource Version: 7120865 Self Link: /apis/networking.gke.io/v1beta1/namespaces/default/managedcertificates/vault-ui-certificate UID: e35e7a1b-3659-11ea-ae90-42010aa80174Spec: Domains: vault.ami-playground.doit-intl.comStatus: Certificate Name: mcrt-9462e1f4-6dd6-4cf2-8769-9693ba29789e Certificate Status: Active Domain Status: Domain: vault.ami-playground.doit-intl.com Status: Active Expire Time: 2020-04-12T15:12:29.000-07:00Events: <none>Configurare IAP per GKE:
Potete decidere di seguire le istruzioni complete al posto del riepilogo qui sotto.
Configurate IAP per il vostro dominio tramite la schermata di consenso OAuth e create le credenziali del client.
Una volta creato il client, copiate il client ID e aggiungetelo nel campo authorized redirect URIs nel formato seguente:
https://iap.googleapis.com/v1/oauth/clientIds/<CLIENT_ID>:handleRedirectCreate il secret che verrà utilizzato dal backend config:
kubectl create secret generic my-secret --from-literal=client_id=client_id_key \ --from-literal=client_secret=client_secret_keyCreate un backend config per IAP:
https://gist.github.com/innovia/4485a253f15cd824d0e6d2a19230a603
Abilitate la sezione in fondo ai file vault-gke.yaml e assicuratevi che i valori dell'IP statico globale e del DNS dell'host siano aggiornati.
Nota:
dovete eliminare l'installazione di Vault e ricrearla con helm, perché l'ingress di GKE ha problemi nell'aggiornare ingress già esistenti.
Riepilogo del file values.yaml:
- abilitiamo il servizio della UI di Vault sulla porta 443 e lo esponiamo tramite un NodePort
- colleghiamo il servizio Vault a IAP tramite un backend config
- abilitiamo l'ingress con un IP statico globale e il DNS come host mappato su di esso
- disabilitiamo HTTP sul load balancer
- configuriamo la comunicazione tra load balancer e pod di Vault esclusivamente in https
- impostiamo il certificato gestito sul load balancer, in modo che funga da listener HTTPS
Una volta deployato, controllando la pagina di IAP vedrete questi errori e warning (potreste vedere entrambi i backend service in stato ERROR se usate una rete VPC condivisa; il vero test è verificare l'URL della UI di Vault dal browser).

Il primo errore riguarda il backend di default (quello che gestisce i 404): segnala semplicemente che IAP non sarà attivo sulle pagine 404, ed è il comportamento atteso.
L'altro è solo un warning; cliccandoci sopra vedrete qualcosa di simile a questo:

Significa solo che GCP ha rilevato che alcune regole firewall bypassano IAP, come le reti interne e la comunicazione tra load balancer e backend di Vault.
Selezionate default/vault nella pagina di IAP e, dal pannello informativo a sinistra, aggiungete i membri che dovranno avere accesso alla vault-ui tramite il load balancer.
Aggiungete il membro con il permesso "IAP-secured Web App User" per consentire a quell'utente di accedere alla UI di Vault.