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
Comments