Some time ago, I made a small shell script to handle Vault on a cluster kubernetes. For documentation purpose.

Install Vault with helm

 1#!/bin/bash
 2
 3## Variables 
 4DIRNAME=$(dirname $0)
 5DEFAULT_VALUE="vault/values-override.yaml"
 6NewAdminPasswd="PASSWORD"
 7PRIVATE_REGISTRY_USER="registry-admin"
 8PRIVATE_REGISTRY_PASSWORD="PASSWORD"
 9PRIVATE_REGISTRY_ADDRESS="registry.example.com"
10DOMAIN="example.com"
11INGRESS="vault.${DOMAIN}"
12
13if [ -z ${CM_NS+x} ];then
14  CM_NS='your-namespace'
15fi
16
17if [ -z ${1+x} ]; then
18  VALUES_FILE="${DIRNAME}/${DEFAULT_VALUE}"
19  echo -e "\n[INFO] Using default values file '${DEFAULT_VALUE}'"
20else
21  if [ -f $1 ]; then
22    echo -e "\n[INFO] Using values file $1"
23    VALUES_FILE=$1
24  else
25    echo -e "\n[ERROR] No file exist $1"
26    exit 1
27  fi
28fi
29
30## Functions 
31function checkComponentsInstall() {
32    componentsArray=("kubectl" "helm")
33    for i in "${componentsArray[@]}"; do
34      command -v "${i}" >/dev/null 2>&1 ||
35        { echo "${i} is required, but it's not installed. Aborting." >&2; exit 1; }
36    done
37}
38
39function createSecret() {
40kubectl get secret -n ${CM_NS} registry-pull-secret --no-headers 2> /dev/null \
41|| \
42kubectl create secret docker-registry -n ${CM_NS} registry-pull-secret \
43  --docker-server=${PRIVATE_REGISTRY_ADDRESS} \
44  --docker-username=${PRIVATE_REGISTRY_USER} \
45  --docker-password=${PRIVATE_REGISTRY_ADDRESS}
46}
47
48function installWithHelm() {
49helm dep update ${DIRNAME}/helm
50
51helm upgrade --install vault ${DIRNAME}/helm \
52--namespace=${CM_NS} --create-namespace \
53--set global.imagePullSecrets.[0]=registry-pull-secret \
54--set global.image.repository=${PRIVATE_REGISTRY_ADDRESS}/hashicorp/vault-k8s \
55--set global.agentImage.repository=${PRIVATE_REGISTRY_ADDRESS}/hashicorp/vault \
56--set ingress.hosts.[0]=${INGRESS} \
57--set ingress.enabled=true \
58--set global.leaderElection.namespace=${CM_NS}
59
60echo -e "\n[INFO] sleep 30s" && sleep 30
61}
62
63checkComponentsInstall
64createSecret
65installWithHelm

Init Vault on kubernetes

Allow local kubernetes to create and reach secret on the Vault

  1#!/usr/bin/bash
  2
  3## Variables 
  4DIRNAME=$(dirname $0)
  5KEY_SHARES="3"
  6KEY_THRESHOLD="2"
  7INIT_LOG="vault.log"
  8
  9if [ -z ${VAULT_NS+x} ];then
 10  VAULT_NS='your-namespace'
 11fi
 12
 13if [ -z ${1+x} ]; then
 14  VALUES_FILE="${DIRNAME}/${DEFAULT_VALUE}"
 15  echo "INFO: Using default values file '${DEFAULT_VALUE}'"
 16else
 17  if [ -f $1 ]; then
 18    echo "INFO: Using values file $1"
 19    VALUES_FILE=$1
 20  else
 21    echo "ERROR: No file exist $1"
 22    exit 1
 23  fi
 24fi
 25
 26function initVault() {
 27  while [[ $(kubectl -n ${VAULT_NS} get pod vault-0 --no-headers | awk '{print $3}') != 'Running' ]]; do
 28    kubectl -n ${VAULT_NS} get pod vault-0 --no-headers; sleep 5;
 29  done
 30
 31  if [[ $(kubectl -n ${VAULT_NS} exec vault-0 -- vault status 2> /dev/null | awk '/Initialized / {print $2}') == "true" ]]; then
 32    echo "Vault is already Initialized!"
 33  else
 34    echo "Vault is not init. Start Initializing...";
 35    kubectl -n ${VAULT_NS} exec -ti vault-0 -- vault operator init -key-shares=${KEY_SHARES} -key-threshold=${KEY_THRESHOLD} > ${INIT_LOG}
 36  fi
 37}
 38
 39function unsealVault() {
 40  if [[ "$(kubectl -n ${VAULT_NS} exec vault-0 -- vault status 2>/dev/null | awk '/Sealed / {print $2}')" == "false" ]]; then
 41    echo "Vault already unsealed!"
 42  else
 43    if [[ -f "${INIT_LOG}" ]]; then
 44      arrayOfVaultKeys=()
 45
 46      echo "Import unseal keys"
 47      for i in $(seq 1 "$(awk '/Unseal Key/ {print $4}' ${INIT_LOG} | wc -l)"); do
 48        arrayOfVaultKeys+=("$(awk "/Unseal Key ${i}:/ {print \$4}" ${INIT_LOG})")
 49      done
 50
 51      echo "Starting unseal..."
 52      for i in "${arrayOfVaultKeys[@]}"; do
 53        if [[ "$(kubectl -n ${VAULT_NS} exec vault-0 -- vault status 2>/dev/null | awk '/Sealed / {print $2}')" == "true" ]]; then
 54          kubectl -n ${VAULT_NS} exec vault-0 -- vault operator unseal "${i}"
 55        else
 56          break
 57        fi
 58      done
 59
 60    else
 61      echo -e "[ERROR] There is no ${INIT_LOG} file with unseal keys and root token. Aborting."; exit 1;
 62    fi
 63  fi
 64}
 65
 66function enableVaultK8sAuth() {
 67
 68  vaultRootToken=$(awk "/Initial Root Token:/ {print \$4}" ${INIT_LOG})
 69  kubectl -n ${VAULT_NS} exec vault-0 -- vault login "${vaultRootToken}";
 70
 71  if [[ $(kubectl -n ${VAULT_NS} exec vault-0 -- vault auth list | awk '/kubernetes/ {print $1}') == "kubernetes/" ]]; then
 72    echo "kubernetes auth already enabled!"
 73  else
 74
 75    kubectl -n ${VAULT_NS} exec vault-0 -- vault auth enable kubernetes;
 76    tokenReviewerJwt=$(kubectl -n ${VAULT_NS} exec vault-0 -- cat /var/run/secrets/kubernetes.io/serviceaccount/token)
 77    k8sAddress=$(kubectl -n ${VAULT_NS} exec vault-0 -- ash -c 'echo $KUBERNETES_SERVICE_HOST')
 78
 79    kubectl -n ${VAULT_NS} exec vault-0 -- vault write auth/kubernetes/config issuer="https://kubernetes.default.svc.cluster.local" \
 80      token_reviewer_jwt="${tokenReviewerJwt}" \
 81      kubernetes_host="https://${k8sAddress}:443" \
 82      kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
 83  fi
 84}
 85
 86function addVaultPermission() {
 87  kubectl -n ${VAULT_NS} exec vault-0 -- ash -c 'cat << EOF > /tmp/policy.hcl
 88path "avp/data/test" { capabilities = ["read"] }
 89EOF'
 90
 91  kubectl -n ${VAULT_NS} exec vault-0 -- vault policy write argocd-repo-server /tmp/policy.hcl
 92
 93  kubectl -n ${VAULT_NS} exec vault-0 -- vault write auth/kubernetes/role/argocd-repo-server \
 94  	bound_service_account_names=argocd-repo-server \
 95    bound_service_account_namespaces=argocd policies=argocd-repo-server
 96}
 97
 98function addVaultSecret() {
 99  if [[ $(kubectl -n ${VAULT_NS} exec vault-0 -- vault secrets list | awk '/avp\// {print $1}') == "avp/" ]]; then
100    echo -e "\n[INFO] Vault avp secret path already exist"
101  else 
102    kubectl -n ${VAULT_NS} exec vault-0 -- vault secrets enable -path=avp -version=2 kv
103  fi
104    kubectl -n ${VAULT_NS} exec vault-0 -- vault kv put avp/test sample=secret
105}
106
107
108function testSampleSecret() {
109  if [[ $(kubectl -n default get secret example-secret -o jsonpath='{.data}') == '{"sample-secret":"c2VjcmV0"}' ]]; then
110    echo -e "\n[OK] Secret created successfully"
111  else
112    echo -e "\n[ERROR] FAIL. Secret created unsuccessfully"
113  fi
114}
115
116function displayVault() {
117    cat << EOF
118Vault available in  http://localhost:8081  with:
119Token: ${vaultRootToken}
120EOF
121
122}
123
124installVault
125initVault
126unsealVault
127enableVaultK8sAuth
128addVaultPermission
129addVaultSecret
130testSampleSecret
131displayVault