From 93ff675562b7c94bfe1ce1012cb3e8b9e40cc957 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Thu, 20 Feb 2020 16:03:28 +1100 Subject: [PATCH 01/14] get a vault server up --- .../server/server-clusterrolebinding.yaml | 14 ++ .../vault/server/server-config-configmap.yaml | 18 +++ .../vault/server/server-disruptionbudget.yaml | 22 +++ hashicorp/vault/server/server-ingress.yaml | 44 ++++++ hashicorp/vault/server/server-pv.yaml | 14 ++ hashicorp/vault/server/server-pvc.yaml | 11 ++ hashicorp/vault/server/server-service.yaml | 25 ++++ .../vault/server/server-serviceaccount.yaml | 6 + .../vault/server/server-statefulset.yaml | 133 ++++++++++++++++++ .../vault/server/server-storageclass.yaml | 6 + hashicorp/vault/server/ui-service.yaml | 20 +++ 11 files changed, 313 insertions(+) create mode 100644 hashicorp/vault/server/server-clusterrolebinding.yaml create mode 100644 hashicorp/vault/server/server-config-configmap.yaml create mode 100644 hashicorp/vault/server/server-disruptionbudget.yaml create mode 100644 hashicorp/vault/server/server-ingress.yaml create mode 100644 hashicorp/vault/server/server-pv.yaml create mode 100644 hashicorp/vault/server/server-pvc.yaml create mode 100644 hashicorp/vault/server/server-service.yaml create mode 100644 hashicorp/vault/server/server-serviceaccount.yaml create mode 100644 hashicorp/vault/server/server-statefulset.yaml create mode 100644 hashicorp/vault/server/server-storageclass.yaml create mode 100644 hashicorp/vault/server/ui-service.yaml diff --git a/hashicorp/vault/server/server-clusterrolebinding.yaml b/hashicorp/vault/server/server-clusterrolebinding.yaml new file mode 100644 index 0000000..66434a4 --- /dev/null +++ b/hashicorp/vault/server/server-clusterrolebinding.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: vault-example-server-binding + labels: + app.kubernetes.io/name: vault-example +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: vault-example + namespace: vault-example diff --git a/hashicorp/vault/server/server-config-configmap.yaml b/hashicorp/vault/server/server-config-configmap.yaml new file mode 100644 index 0000000..9abe1c3 --- /dev/null +++ b/hashicorp/vault/server/server-config-configmap.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: vault-example-config + labels: + app.kubernetes.io/name: vault-example +data: + extraconfig-from-values.hcl: |- + disable_mlock = true + ui = true + listener "tcp" { + tls_disable = 1 + address = "[::]:8200" + cluster_address = "[::]:8201" + } + storage "file" { + path = "/vault/data" + } diff --git a/hashicorp/vault/server/server-disruptionbudget.yaml b/hashicorp/vault/server/server-disruptionbudget.yaml new file mode 100644 index 0000000..7cd2067 --- /dev/null +++ b/hashicorp/vault/server/server-disruptionbudget.yaml @@ -0,0 +1,22 @@ +# {{ template "vault.mode" . }} +# {{- if and (and (eq (.Values.global.enabled | toString) "true") (eq .mode "ha")) (eq (.Values.server.ha.disruptionBudget.enabled | toString) "true") -}} +# # PodDisruptionBudget to prevent degrading the server cluster through +# # voluntary cluster changes. +# apiVersion: policy/v1beta1 +# kind: PodDisruptionBudget +# metadata: +# name: {{ template "vault.fullname" . }} +# namespace: {{ .Release.Namespace }} +# labels: +# helm.sh/chart: {{ include "vault.chart" . }} +# app.kubernetes.io/name: {{ include "vault.name" . }} +# app.kubernetes.io/instance: {{ .Release.Name }} +# app.kubernetes.io/managed-by: {{ .Release.Service }} +# spec: +# maxUnavailable: {{ template "vault.pdb.maxUnavailable" . }} +# selector: +# matchLabels: +# app.kubernetes.io/name: {{ include "vault.name" . }} +# app.kubernetes.io/instance: {{ .Release.Name }} +# component: server +# {{- end -}} diff --git a/hashicorp/vault/server/server-ingress.yaml b/hashicorp/vault/server/server-ingress.yaml new file mode 100644 index 0000000..5b8d7f8 --- /dev/null +++ b/hashicorp/vault/server/server-ingress.yaml @@ -0,0 +1,44 @@ +# {{- if .Values.server.ingress.enabled -}} +# {{- $serviceName := include "vault.fullname" . -}} +# {{- $servicePort := .Values.server.service.port -}} +# apiVersion: extensions/v1beta1 +# kind: Ingress +# metadata: +# name: {{ template "vault.fullname" . }} +# namespace: {{ .Release.Namespace }} +# labels: +# helm.sh/chart: {{ include "vault.chart" . }} +# app.kubernetes.io/name: {{ include "vault.name" . }} +# app.kubernetes.io/instance: {{ .Release.Name }} +# app.kubernetes.io/managed-by: {{ .Release.Service }} +# {{- with .Values.server.ingress.labels }} +# {{- toYaml . | nindent 4 }} +# {{- end }} +# {{- with .Values.server.ingress.annotations }} +# annotations: +# {{- toYaml . | nindent 4 }} +# {{- end }} +# spec: +# {{- if .Values.server.ingress.tls }} +# tls: +# {{- range .Values.server.ingress.tls }} +# - hosts: +# {{- range .hosts }} +# - {{ . | quote }} +# {{- end }} +# secretName: {{ .secretName }} +# {{- end }} +# {{- end }} +# rules: +# {{- range .Values.server.ingress.hosts }} +# - host: {{ .host | quote }} +# http: +# paths: +# {{- range .paths }} +# - path: {{ . }} +# backend: +# serviceName: {{ $serviceName }} +# servicePort: {{ $servicePort }} +# {{- end }} +# {{- end }} +# {{- end }} diff --git a/hashicorp/vault/server/server-pv.yaml b/hashicorp/vault/server/server-pv.yaml new file mode 100644 index 0000000..b93235e --- /dev/null +++ b/hashicorp/vault/server/server-pv.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: vault + labels: + type: local +spec: + storageClassName: manual + capacity: + storage: 1Gi + accessModes: + - ReadWriteOnce + hostPath: + path: "/mnt/data" \ No newline at end of file diff --git a/hashicorp/vault/server/server-pvc.yaml b/hashicorp/vault/server/server-pvc.yaml new file mode 100644 index 0000000..14dae2c --- /dev/null +++ b/hashicorp/vault/server/server-pvc.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: vault-claim +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi \ No newline at end of file diff --git a/hashicorp/vault/server/server-service.yaml b/hashicorp/vault/server/server-service.yaml new file mode 100644 index 0000000..1ed6d4f --- /dev/null +++ b/hashicorp/vault/server/server-service.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Service +metadata: + name: vault-example + labels: + app.kubernetes.io/name: vault-example + annotations: + # This must be set in addition to publishNotReadyAddresses due + # to an open issue where it may not work: + # https://github.com/kubernetes/kubernetes/issues/58662 + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" +spec: + # We want the servers to become available even if they're not ready + # since this DNS is also used for join operations. + publishNotReadyAddresses: true + ports: + - name: http + port: 80 + targetPort: 80 + - name: internal + port: 8201 + targetPort: 8201 + selector: + app.kubernetes.io/name: vault-example + component: server diff --git a/hashicorp/vault/server/server-serviceaccount.yaml b/hashicorp/vault/server/server-serviceaccount.yaml new file mode 100644 index 0000000..efdfb01 --- /dev/null +++ b/hashicorp/vault/server/server-serviceaccount.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: vault-example + labels: + app.kubernetes.io/name: vault-example \ No newline at end of file diff --git a/hashicorp/vault/server/server-statefulset.yaml b/hashicorp/vault/server/server-statefulset.yaml new file mode 100644 index 0000000..81fc2ea --- /dev/null +++ b/hashicorp/vault/server/server-statefulset.yaml @@ -0,0 +1,133 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: vault-example + labels: + app.kubernetes.io/name: vault-example +spec: + serviceName: vault-example + podManagementPolicy: Parallel + replicas: 1 + updateStrategy: + type: "OnDelete" + selector: + matchLabels: + app.kubernetes.io/name: vault-example + component: server + template: + metadata: + labels: + app.kubernetes.io/name: vault-example + component: server + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: vault-example + component: server + topologyKey: kubernetes.io/hostname + terminationGracePeriodSeconds: 10 + serviceAccountName: vault-example + shareProcessNamespace: true + securityContext: + fsGroup: 1000 + volumes: + - name: config + configMap: + name: vault-example-config + - name: data + persistentVolumeClaim: + claimName: vault-claim + initContainers: + - name: setupperms + image: alpine:latest + command: ['sh', '-c', 'echo The app is running! && chown 100 /vault/data && ls -l /vault/'] + volumeMounts: + - name: data + mountPath: /vault/data + containers: + - name: vault + securityContext: + runAsNonRoot: true + runAsGroup: 1000 + runAsUser: 100 + capabilities: + add: ["IPC_LOCK"] + image: vault:1.3.1 + imagePullPolicy: IfNotPresent + command: + - "/bin/sh" + - "-ec" + args: + - | + sed -E "s/HOST_IP/${HOST_IP?}/g" /vault/config/extraconfig-from-values.hcl > /tmp/storageconfig.hcl; + sed -Ei "s/POD_IP/${POD_IP?}/g" /tmp/storageconfig.hcl; + /usr/local/bin/docker-entrypoint.sh vault server -config=/tmp/storageconfig.hcl + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: VAULT_ADDR + value: "http://127.0.0.1:8200" + - name: VAULT_API_ADDR + value: "http://$(POD_IP):8200" + - name: SKIP_CHOWN + value: "true" + - name: SKIP_SETCAP + value: "true" + volumeMounts: + - name: config + mountPath: /vault/config + - name: data + mountPath: /vault/data + ports: + - containerPort: 8200 + name: http + - containerPort: 8201 + name: internal + - containerPort: 8202 + name: replication + readinessProbe: + # Check status; unsealed vault servers return 0 + # The exit code reflects the seal status: + # 0 - unsealed + # 1 - error + # 2 - sealed + exec: + command: ["/bin/sh", "-ec", "vault status -tls-skip-verify"] + failureThreshold: 2 + initialDelaySeconds: 5 + periodSeconds: 3 + successThreshold: 1 + timeoutSeconds: 5 + livenessProbe: + httpGet: + path: "/v1/sys/health?standbyok=true" + port: 8200 + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 3 + successThreshold: 1 + timeoutSeconds: 5 + lifecycle: + # Vault container doesn't receive SIGTERM from Kubernetes + # and after the grace period ends, Kube sends SIGKILL. This + # causes issues with graceful shutdowns such as deregistering itself + # from Consul (zombie services). + preStop: + exec: + command: [ + "/bin/sh", "-c", + # Adding a sleep here to give the pod eviction a + # chance to propagate, so requests will not be made + # to this pod while it's terminating + "sleep 5 && kill -SIGTERM $(pidof vault)", + ] + \ No newline at end of file diff --git a/hashicorp/vault/server/server-storageclass.yaml b/hashicorp/vault/server/server-storageclass.yaml new file mode 100644 index 0000000..fb12735 --- /dev/null +++ b/hashicorp/vault/server/server-storageclass.yaml @@ -0,0 +1,6 @@ +# kind: StorageClass +# apiVersion: storage.k8s.io/v1 +# metadata: +# name: local-storage +# provisioner: kubernetes.io/no-provisioner +# volumeBindingMode: WaitForFirstConsumer \ No newline at end of file diff --git a/hashicorp/vault/server/ui-service.yaml b/hashicorp/vault/server/ui-service.yaml new file mode 100644 index 0000000..4d28847 --- /dev/null +++ b/hashicorp/vault/server/ui-service.yaml @@ -0,0 +1,20 @@ +# Headless service for Vault server DNS entries. This service should only +# point to Vault servers. For access to an agent, one should assume that +# the agent is installed locally on the node and the NODE_IP should be used. +# If the node can't run a Vault agent, then this service can be used to +# communicate directly to a server agent. +apiVersion: v1 +kind: Service +metadata: + name: vault-example-ui + labels: + app.kubernetes.io/name: vault-example-ui +spec: + selector: + app.kubernetes.io/name: vault-example + component: server + publishNotReadyAddresses: true + ports: + - name: http + port: 8080 + targetPort: 8200 \ No newline at end of file From d11a812ec669da5a93194de006683bcbc204f917 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Sun, 23 Feb 2020 17:12:25 +1100 Subject: [PATCH 02/14] remove storage class- not needed --- hashicorp/vault/server/server-storageclass.yaml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 hashicorp/vault/server/server-storageclass.yaml diff --git a/hashicorp/vault/server/server-storageclass.yaml b/hashicorp/vault/server/server-storageclass.yaml deleted file mode 100644 index fb12735..0000000 --- a/hashicorp/vault/server/server-storageclass.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# kind: StorageClass -# apiVersion: storage.k8s.io/v1 -# metadata: -# name: local-storage -# provisioner: kubernetes.io/no-provisioner -# volumeBindingMode: WaitForFirstConsumer \ No newline at end of file From 151b9817fd78ccb3c1e98bf200b00bf1dbb90262 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Mon, 24 Feb 2020 08:25:27 +1100 Subject: [PATCH 03/14] base template from helm chart --- hashicorp/vault/NOTES.txt | 14 + hashicorp/vault/_helpers.tpl | 313 ++++++++++++++++++ .../vault/injector/injector-clusterrole.yaml | 18 + .../injector/injector-clusterrolebinding.yaml | 19 ++ .../vault/injector/injector-deployment.yaml | 90 +++++ .../injector/injector-mutating-webhook.yaml | 27 ++ .../vault/injector/injector-service.yaml | 19 ++ .../injector/injector-serviceaccount.yaml | 11 + 8 files changed, 511 insertions(+) create mode 100644 hashicorp/vault/NOTES.txt create mode 100644 hashicorp/vault/_helpers.tpl create mode 100644 hashicorp/vault/injector/injector-clusterrole.yaml create mode 100644 hashicorp/vault/injector/injector-clusterrolebinding.yaml create mode 100644 hashicorp/vault/injector/injector-deployment.yaml create mode 100644 hashicorp/vault/injector/injector-mutating-webhook.yaml create mode 100644 hashicorp/vault/injector/injector-service.yaml create mode 100644 hashicorp/vault/injector/injector-serviceaccount.yaml diff --git a/hashicorp/vault/NOTES.txt b/hashicorp/vault/NOTES.txt new file mode 100644 index 0000000..b784f57 --- /dev/null +++ b/hashicorp/vault/NOTES.txt @@ -0,0 +1,14 @@ + +Thank you for installing HashiCorp Vault! + +Now that you have deployed Vault, you should look over the docs on using +Vault with Kubernetes available here: + +https://www.vaultproject.io/docs/ + + +Your release is named {{ .Release.Name }}. To learn more about the release, try: + + $ helm status {{ .Release.Name }} + $ helm get {{ .Release.Name }} + diff --git a/hashicorp/vault/_helpers.tpl b/hashicorp/vault/_helpers.tpl new file mode 100644 index 0000000..0098ab1 --- /dev/null +++ b/hashicorp/vault/_helpers.tpl @@ -0,0 +1,313 @@ +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to +this (by the DNS naming spec). If release name contains chart name it will +be used as a full name. +*/}} +{{- define "vault.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "vault.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Expand the name of the chart. +*/}} +{{- define "vault.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Compute the maximum number of unavailable replicas for the PodDisruptionBudget. +This defaults to (n/2)-1 where n is the number of members of the server cluster. +Add a special case for replicas=1, where it should default to 0 as well. +*/}} +{{- define "vault.pdb.maxUnavailable" -}} +{{- if eq (int .Values.server.ha.replicas) 1 -}} +{{ 0 }} +{{- else if .Values.server.ha.disruptionBudget.maxUnavailable -}} +{{ .Values.server.ha.disruptionBudget.maxUnavailable -}} +{{- else -}} +{{- div (sub (div (mul (int .Values.server.ha.replicas) 10) 2) 1) 10 -}} +{{- end -}} +{{- end -}} + +{{/* +Set the variable 'mode' to the server mode requested by the user to simplify +template logic. +*/}} +{{- define "vault.mode" -}} + {{- if eq (.Values.server.dev.enabled | toString) "true" -}} + {{- $_ := set . "mode" "dev" -}} + {{- else if eq (.Values.server.ha.enabled | toString) "true" -}} + {{- $_ := set . "mode" "ha" -}} + {{- else if or (eq (.Values.server.standalone.enabled | toString) "true") (eq (.Values.server.standalone.enabled | toString) "-") -}} + {{- $_ := set . "mode" "standalone" -}} + {{- else -}} + {{- $_ := set . "mode" "" -}} + {{- end -}} +{{- end -}} + +{{/* +Set's the replica count based on the different modes configured by user +*/}} +{{- define "vault.replicas" -}} + {{ if eq .mode "standalone" }} + {{- default 1 -}} + {{ else if eq .mode "ha" }} + {{- .Values.server.ha.replicas | default 3 -}} + {{ else }} + {{- default 1 -}} + {{ end }} +{{- end -}} + +{{/* +Set's up configmap mounts if this isn't a dev deployment and the user +defined a custom configuration. Additionally iterates over any +extra volumes the user may have specified (such as a secret with TLS). +*/}} +{{- define "vault.volumes" -}} + {{- if and (ne .mode "dev") (or (ne .Values.server.standalone.config "") (ne .Values.server.ha.config "")) }} + - name: config + configMap: + name: {{ template "vault.fullname" . }}-config + {{ end }} + {{- range .Values.server.extraVolumes }} + - name: userconfig-{{ .name }} + {{ .type }}: + {{- if (eq .type "configMap") }} + name: {{ .name }} + {{- else if (eq .type "secret") }} + secretName: {{ .name }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Set's a command to override the entrypoint defined in the image +so we can make the user experience nicer. This works in with +"vault.args" to specify what commands /bin/sh should run. +*/}} +{{- define "vault.command" -}} + {{ if or (eq .mode "standalone") (eq .mode "ha") }} + - "/bin/sh" + - "-ec" + {{ end }} +{{- end -}} + +{{/* +Set's the args for custom command to render the Vault configuration +file with IP addresses to make the out of box experience easier +for users looking to use this chart with Consul Helm. +*/}} +{{- define "vault.args" -}} + {{ if or (eq .mode "standalone") (eq .mode "ha") }} + - | + sed -E "s/HOST_IP/${HOST_IP?}/g" /vault/config/extraconfig-from-values.hcl > /tmp/storageconfig.hcl; + sed -Ei "s/POD_IP/${POD_IP?}/g" /tmp/storageconfig.hcl; + /usr/local/bin/docker-entrypoint.sh vault server -config=/tmp/storageconfig.hcl {{ .Values.server.extraArgs }} + {{ end }} +{{- end -}} + +{{/* +Set's additional environment variables based on the mode. +*/}} +{{- define "vault.envs" -}} + {{ if eq .mode "dev" }} + - name: VAULT_DEV_ROOT_TOKEN_ID + value: "root" + {{ end }} +{{- end -}} + +{{/* +Set's which additional volumes should be mounted to the container +based on the mode configured. +*/}} +{{- define "vault.mounts" -}} + {{ if eq (.Values.server.auditStorage.enabled | toString) "true" }} + - name: audit + mountPath: /vault/audit + {{ end }} + {{ if eq .mode "standalone" }} + {{ if eq (.Values.server.dataStorage.enabled | toString) "true" }} + - name: data + mountPath: /vault/data + {{ end }} + {{ end }} + {{ if and (ne .mode "dev") (or (ne .Values.server.standalone.config "") (ne .Values.server.ha.config "")) }} + - name: config + mountPath: /vault/config + {{ end }} + {{- range .Values.server.extraVolumes }} + - name: userconfig-{{ .name }} + readOnly: true + mountPath: {{ .path | default "/vault/userconfig" }}/{{ .name }} + {{- end }} +{{- end -}} + +{{/* +Set's up the volumeClaimTemplates when data or audit storage is required. HA +might not use data storage since Consul is likely it's backend, however, audit +storage might be desired by the user. +*/}} +{{- define "vault.volumeclaims" -}} + {{- if and (ne .mode "dev") (or .Values.server.dataStorage.enabled .Values.server.auditStorage.enabled) }} + volumeClaimTemplates: + {{- if and (eq (.Values.server.dataStorage.enabled | toString) "true") (eq .mode "standalone") }} + - metadata: + name: data + spec: + accessModes: + - {{ .Values.server.dataStorage.accessMode | default "ReadWriteOnce" }} + resources: + requests: + storage: {{ .Values.server.dataStorage.size }} + {{- if .Values.server.dataStorage.storageClass }} + storageClassName: {{ .Values.server.dataStorage.storageClass }} + {{- end }} + {{ end }} + {{- if eq (.Values.server.auditStorage.enabled | toString) "true" }} + - metadata: + name: audit + spec: + accessModes: + - {{ .Values.server.auditStorage.accessMode | default "ReadWriteOnce" }} + resources: + requests: + storage: {{ .Values.server.auditStorage.size }} + {{- if .Values.server.auditStorage.storageClass }} + storageClassName: {{ .Values.server.auditStorage.storageClass }} + {{- end }} + {{ end }} + {{ end }} +{{- end -}} + +{{/* +Set's the affinity for pod placement when running in standalone and HA modes. +*/}} +{{- define "vault.affinity" -}} + {{- if and (ne .mode "dev") .Values.server.affinity }} + affinity: + {{ tpl .Values.server.affinity . | nindent 8 | trim }} + {{ end }} +{{- end -}} + +{{/* +Set's the toleration for pod placement when running in standalone and HA modes. +*/}} +{{- define "vault.tolerations" -}} + {{- if and (ne .mode "dev") .Values.server.tolerations }} + tolerations: + {{ tpl .Values.server.tolerations . | nindent 8 | trim }} + {{- end }} +{{- end -}} + +{{/* +Set's the node selector for pod placement when running in standalone and HA modes. +*/}} +{{- define "vault.nodeselector" -}} + {{- if and (ne .mode "dev") .Values.server.nodeSelector }} + nodeSelector: + {{ tpl .Values.server.nodeSelector . | indent 8 | trim }} + {{- end }} +{{- end -}} + +{{/* +Sets extra pod annotations +*/}} +{{- define "vault.annotations" -}} + {{- if and (ne .mode "dev") .Values.server.annotations }} + annotations: + {{- tpl .Values.server.annotations . | nindent 8 }} + {{- end }} +{{- end -}} + +{{/* +Sets extra ui service annotations +*/}} +{{- define "vault.ui.annotations" -}} + {{- if .Values.ui.annotations }} + annotations: + {{- toYaml .Values.ui.annotations | nindent 4 }} + {{- end }} +{{- end -}} + +{{/* +Sets extra service account annotations +*/}} +{{- define "vault.serviceAccount.annotations" -}} + {{- if and (ne .mode "dev") .Values.server.serviceAccount.annotations }} + annotations: + {{- toYaml .Values.server.serviceAccount.annotations | nindent 4 }} + {{- end }} +{{- end -}} + +{{/* +Set's the container resources if the user has set any. +*/}} +{{- define "vault.resources" -}} + {{- if .Values.server.resources -}} + resources: +{{ toYaml .Values.server.resources | indent 12}} + {{ end }} +{{- end -}} + +{{/* +Sets the container resources if the user has set any. +*/}} +{{- define "injector.resources" -}} + {{- if .Values.injector.resources -}} + resources: +{{ toYaml .Values.injector.resources | indent 12}} + {{ end }} +{{- end -}} + +{{/* +Inject extra environment vars in the format key:value, if populated +*/}} +{{- define "vault.extraEnvironmentVars" -}} +{{- if .extraEnvironmentVars -}} +{{- range $key, $value := .extraEnvironmentVars }} +- name: {{ $key }} + value: {{ $value | quote }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Inject extra environment populated by secrets, if populated +*/}} +{{- define "vault.extraSecretEnvironmentVars" -}} +{{- if .extraSecretEnvironmentVars -}} +{{- range .extraSecretEnvironmentVars }} +- name: {{ .envName }} + valueFrom: + secretKeyRef: + name: {{ .secretName }} + key: {{ .secretKey }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* Scheme for health check and local endpoint */}} +{{- define "vault.scheme" -}} +{{- if .Values.global.tlsDisable -}} +{{ "http" }} +{{- else -}} +{{ "https" }} +{{- end -}} +{{- end -}} diff --git a/hashicorp/vault/injector/injector-clusterrole.yaml b/hashicorp/vault/injector/injector-clusterrole.yaml new file mode 100644 index 0000000..4ff25ab --- /dev/null +++ b/hashicorp/vault/injector/injector-clusterrole.yaml @@ -0,0 +1,18 @@ +{{- if and (eq (.Values.injector.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-clusterrole + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: ["admissionregistration.k8s.io"] + resources: ["mutatingwebhookconfigurations"] + verbs: + - "get" + - "list" + - "watch" + - "patch" +{{ end }} diff --git a/hashicorp/vault/injector/injector-clusterrolebinding.yaml b/hashicorp/vault/injector/injector-clusterrolebinding.yaml new file mode 100644 index 0000000..9826693 --- /dev/null +++ b/hashicorp/vault/injector/injector-clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if and (eq (.Values.injector.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-binding + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "vault.fullname" . }}-agent-injector-clusterrole +subjects: +- kind: ServiceAccount + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ .Release.Namespace }} +{{ end }} diff --git a/hashicorp/vault/injector/injector-deployment.yaml b/hashicorp/vault/injector/injector-deployment.yaml new file mode 100644 index 0000000..86c54ff --- /dev/null +++ b/hashicorp/vault/injector/injector-deployment.yaml @@ -0,0 +1,90 @@ +{{- if and (eq (.Values.injector.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} +# Deployment for the injector +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + component: webhook +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook + spec: + serviceAccountName: "{{ template "vault.fullname" . }}-agent-injector" + securityContext: + runAsNonRoot: true + runAsGroup: {{ .Values.injector.gid | default 1000 }} + runAsUser: {{ .Values.injector.uid | default 100 }} + containers: + - name: sidecar-injector + {{ template "injector.resources" . }} + image: "{{ .Values.injector.image.repository }}:{{ .Values.injector.image.tag }}" + imagePullPolicy: "{{ .Values.injector.image.pullPolicy }}" + env: + - name: AGENT_INJECT_LISTEN + value: ":8080" + - name: AGENT_INJECT_LOG_LEVEL + value: {{ .Values.injector.logLevel | default "info" }} + - name: AGENT_INJECT_VAULT_ADDR + value: {{ include "vault.scheme" . }}://{{ template "vault.fullname" . }}.{{ .Release.Namespace }}.svc:{{ .Values.server.service.port }} + - name: AGENT_INJECT_VAULT_IMAGE + value: "{{ .Values.injector.agentImage.repository }}:{{ .Values.injector.agentImage.tag }}" + {{- if .Values.injector.certs.secretName }} + - name: AGENT_INJECT_TLS_CERT_FILE + value: "/etc/webhook/certs/{{ .Values.injector.certs.certName }}" + - name: AGENT_INJECT_TLS_KEY_FILE + value: "/etc/webhook/certs/{{ .Values.injector.certs.keyName }}" + {{- else }} + - name: AGENT_INJECT_TLS_AUTO + value: {{ template "vault.fullname" . }}-agent-injector-cfg + - name: AGENT_INJECT_TLS_AUTO_HOSTS + value: {{ template "vault.fullname" . }}-agent-injector-svc,{{ template "vault.fullname" . }}-agent-injector-svc.{{ .Release.Namespace }},{{ template "vault.fullname" . }}-agent-injector-svc.{{ .Release.Namespace }}.svc + {{- end }} + args: + - agent-inject + - 2>&1 + livenessProbe: + httpGet: + path: /health/ready + port: 8080 + scheme: HTTPS + failureThreshold: 2 + initialDelaySeconds: 1 + periodSeconds: 2 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /health/ready + port: 8080 + scheme: HTTPS + failureThreshold: 2 + initialDelaySeconds: 2 + periodSeconds: 2 + successThreshold: 1 + timeoutSeconds: 5 +{{- if .Values.injector.certs.secretName }} + volumeMounts: + - name: webhook-certs + mountPath: /etc/webhook/certs + readOnly: true + volumes: + - name: webhook-certs + secret: + secretName: "{{ .Values.injector.certs.secretName }}" +{{- end }} +{{ end }} diff --git a/hashicorp/vault/injector/injector-mutating-webhook.yaml b/hashicorp/vault/injector/injector-mutating-webhook.yaml new file mode 100644 index 0000000..3f0d27e --- /dev/null +++ b/hashicorp/vault/injector/injector-mutating-webhook.yaml @@ -0,0 +1,27 @@ +{{- if and (eq (.Values.injector.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} +apiVersion: admissionregistration.k8s.io/v1beta1 +kind: MutatingWebhookConfiguration +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-cfg + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +webhooks: + - name: vault.hashicorp.com + clientConfig: + service: + name: {{ template "vault.fullname" . }}-agent-injector-svc + namespace: {{ .Release.Namespace }} + path: "/mutate" + caBundle: {{ .Values.injector.certs.caBundle }} + rules: + - operations: ["CREATE", "UPDATE"] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] +{{- if .Values.injector.namespaceSelector }} + namespaceSelector: +{{ toYaml .Values.injector.namespaceSelector | indent 6}} +{{ end }} +{{ end }} diff --git a/hashicorp/vault/injector/injector-service.yaml b/hashicorp/vault/injector/injector-service.yaml new file mode 100644 index 0000000..79d818f --- /dev/null +++ b/hashicorp/vault/injector/injector-service.yaml @@ -0,0 +1,19 @@ +{{- if and (eq (.Values.injector.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-svc + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + ports: + - port: 443 + targetPort: 8080 + selector: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook +{{- end }} diff --git a/hashicorp/vault/injector/injector-serviceaccount.yaml b/hashicorp/vault/injector/injector-serviceaccount.yaml new file mode 100644 index 0000000..a28d38f --- /dev/null +++ b/hashicorp/vault/injector/injector-serviceaccount.yaml @@ -0,0 +1,11 @@ +{{- if and (eq (.Values.injector.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +{{ end }} From 1f6ccdc4bbbbc902552300657b3a0abce17cdfb5 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Mon, 24 Feb 2020 08:26:56 +1100 Subject: [PATCH 04/14] remove notes txt --- hashicorp/vault/NOTES.txt | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 hashicorp/vault/NOTES.txt diff --git a/hashicorp/vault/NOTES.txt b/hashicorp/vault/NOTES.txt deleted file mode 100644 index b784f57..0000000 --- a/hashicorp/vault/NOTES.txt +++ /dev/null @@ -1,14 +0,0 @@ - -Thank you for installing HashiCorp Vault! - -Now that you have deployed Vault, you should look over the docs on using -Vault with Kubernetes available here: - -https://www.vaultproject.io/docs/ - - -Your release is named {{ .Release.Name }}. To learn more about the release, try: - - $ helm status {{ .Release.Name }} - $ helm get {{ .Release.Name }} - From e454f2783b1947e66bf4be9427473d64cc107685 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Sun, 23 Feb 2020 23:14:17 +0000 Subject: [PATCH 05/14] basic injector --- .../vault/injector/injector-clusterrole.yaml | 8 +-- .../injector/injector-clusterrolebinding.yaml | 15 ++---- .../vault/injector/injector-deployment.yaml | 54 +++++-------------- .../injector/injector-mutating-webhook.yaml | 27 +++++----- .../vault/injector/injector-service.yaml | 12 ++--- .../injector/injector-serviceaccount.yaml | 9 +--- hashicorp/vault/server/server-service.yaml | 4 +- 7 files changed, 42 insertions(+), 87 deletions(-) diff --git a/hashicorp/vault/injector/injector-clusterrole.yaml b/hashicorp/vault/injector/injector-clusterrole.yaml index 4ff25ab..1f58f4f 100644 --- a/hashicorp/vault/injector/injector-clusterrole.yaml +++ b/hashicorp/vault/injector/injector-clusterrole.yaml @@ -1,12 +1,9 @@ -{{- if and (eq (.Values.injector.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: {{ template "vault.fullname" . }}-agent-injector-clusterrole + name: vault-example-agent-injector-clusterrole labels: - app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: vault-example-agent-injector rules: - apiGroups: ["admissionregistration.k8s.io"] resources: ["mutatingwebhookconfigurations"] @@ -15,4 +12,3 @@ rules: - "list" - "watch" - "patch" -{{ end }} diff --git a/hashicorp/vault/injector/injector-clusterrolebinding.yaml b/hashicorp/vault/injector/injector-clusterrolebinding.yaml index 9826693..4e883f1 100644 --- a/hashicorp/vault/injector/injector-clusterrolebinding.yaml +++ b/hashicorp/vault/injector/injector-clusterrolebinding.yaml @@ -1,19 +1,14 @@ -{{- if and (eq (.Values.injector.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: {{ template "vault.fullname" . }}-agent-injector-binding - namespace: {{ .Release.Namespace }} + name: vault-example-agent-injector-binding labels: - app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: vault-example-agent-injector roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: {{ template "vault.fullname" . }}-agent-injector-clusterrole + name: vault-example-agent-injector-clusterrole subjects: - kind: ServiceAccount - name: {{ template "vault.fullname" . }}-agent-injector - namespace: {{ .Release.Namespace }} -{{ end }} + name: vault-example-agent-injector + namespace: vault-example diff --git a/hashicorp/vault/injector/injector-deployment.yaml b/hashicorp/vault/injector/injector-deployment.yaml index 86c54ff..f4c142f 100644 --- a/hashicorp/vault/injector/injector-deployment.yaml +++ b/hashicorp/vault/injector/injector-deployment.yaml @@ -1,59 +1,44 @@ -{{- if and (eq (.Values.injector.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} -# Deployment for the injector apiVersion: apps/v1 kind: Deployment metadata: - name: {{ template "vault.fullname" . }}-agent-injector - namespace: {{ .Release.Namespace }} + name: vault-example-agent-injector labels: - app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: vault-example-agent-injector component: webhook spec: replicas: 1 selector: matchLabels: - app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector - app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: vault-example-agent-injector component: webhook template: metadata: labels: - app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector - app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: vault-example-agent-injector component: webhook spec: - serviceAccountName: "{{ template "vault.fullname" . }}-agent-injector" + serviceAccountName: vault-example-agent-injector securityContext: runAsNonRoot: true - runAsGroup: {{ .Values.injector.gid | default 1000 }} - runAsUser: {{ .Values.injector.uid | default 100 }} + runAsGroup: 1000 + runAsUser: 100 containers: - name: sidecar-injector - {{ template "injector.resources" . }} - image: "{{ .Values.injector.image.repository }}:{{ .Values.injector.image.tag }}" - imagePullPolicy: "{{ .Values.injector.image.pullPolicy }}" + image: "hashicorp/vault-k8s:0.1.2" + imagePullPolicy: IfNotPresent env: - name: AGENT_INJECT_LISTEN value: ":8080" - name: AGENT_INJECT_LOG_LEVEL - value: {{ .Values.injector.logLevel | default "info" }} + value: "info" - name: AGENT_INJECT_VAULT_ADDR - value: {{ include "vault.scheme" . }}://{{ template "vault.fullname" . }}.{{ .Release.Namespace }}.svc:{{ .Values.server.service.port }} + value: http://vault-example:8200 - name: AGENT_INJECT_VAULT_IMAGE - value: "{{ .Values.injector.agentImage.repository }}:{{ .Values.injector.agentImage.tag }}" - {{- if .Values.injector.certs.secretName }} - - name: AGENT_INJECT_TLS_CERT_FILE - value: "/etc/webhook/certs/{{ .Values.injector.certs.certName }}" - - name: AGENT_INJECT_TLS_KEY_FILE - value: "/etc/webhook/certs/{{ .Values.injector.certs.keyName }}" - {{- else }} + value: "vault:1.3.1" - name: AGENT_INJECT_TLS_AUTO - value: {{ template "vault.fullname" . }}-agent-injector-cfg + value: vault-example-agent-injector-cfg - name: AGENT_INJECT_TLS_AUTO_HOSTS - value: {{ template "vault.fullname" . }}-agent-injector-svc,{{ template "vault.fullname" . }}-agent-injector-svc.{{ .Release.Namespace }},{{ template "vault.fullname" . }}-agent-injector-svc.{{ .Release.Namespace }}.svc - {{- end }} + value: vault-example-agent-injector-svc,vault-example-agent-injector-svc.vault-example,vault-example-agent-injector-svc.vault-example.svc args: - agent-inject - 2>&1 @@ -77,14 +62,3 @@ spec: periodSeconds: 2 successThreshold: 1 timeoutSeconds: 5 -{{- if .Values.injector.certs.secretName }} - volumeMounts: - - name: webhook-certs - mountPath: /etc/webhook/certs - readOnly: true - volumes: - - name: webhook-certs - secret: - secretName: "{{ .Values.injector.certs.secretName }}" -{{- end }} -{{ end }} diff --git a/hashicorp/vault/injector/injector-mutating-webhook.yaml b/hashicorp/vault/injector/injector-mutating-webhook.yaml index 3f0d27e..caf6ba2 100644 --- a/hashicorp/vault/injector/injector-mutating-webhook.yaml +++ b/hashicorp/vault/injector/injector-mutating-webhook.yaml @@ -1,27 +1,28 @@ -{{- if and (eq (.Values.injector.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: - name: {{ template "vault.fullname" . }}-agent-injector-cfg + name: vault-example-agent-injector-cfg labels: - app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: vault-example-agent-injector webhooks: - name: vault.hashicorp.com clientConfig: service: - name: {{ template "vault.fullname" . }}-agent-injector-svc - namespace: {{ .Release.Namespace }} + name: vault-example-agent-injector-svc + namespace: vault-example path: "/mutate" - caBundle: {{ .Values.injector.certs.caBundle }} + caBundle: "" rules: - operations: ["CREATE", "UPDATE"] apiGroups: [""] apiVersions: ["v1"] resources: ["pods"] -{{- if .Values.injector.namespaceSelector }} namespaceSelector: -{{ toYaml .Values.injector.namespaceSelector | indent 6}} -{{ end }} -{{ end }} + matchExpressions: + - key: name + operator: In + values: + - example-app + sideEffects: None + admissionReviewVersions: + - "v1" \ No newline at end of file diff --git a/hashicorp/vault/injector/injector-service.yaml b/hashicorp/vault/injector/injector-service.yaml index 79d818f..2a4430b 100644 --- a/hashicorp/vault/injector/injector-service.yaml +++ b/hashicorp/vault/injector/injector-service.yaml @@ -1,19 +1,13 @@ -{{- if and (eq (.Values.injector.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} apiVersion: v1 kind: Service metadata: - name: {{ template "vault.fullname" . }}-agent-injector-svc - namespace: {{ .Release.Namespace }} + name: vault-example-agent-injector-svc labels: - app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: vault-example-agent-injector spec: ports: - port: 443 targetPort: 8080 selector: - app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector - app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: vault-example-agent-injector component: webhook -{{- end }} diff --git a/hashicorp/vault/injector/injector-serviceaccount.yaml b/hashicorp/vault/injector/injector-serviceaccount.yaml index a28d38f..fdb55b1 100644 --- a/hashicorp/vault/injector/injector-serviceaccount.yaml +++ b/hashicorp/vault/injector/injector-serviceaccount.yaml @@ -1,11 +1,6 @@ -{{- if and (eq (.Values.injector.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} apiVersion: v1 kind: ServiceAccount metadata: - name: {{ template "vault.fullname" . }}-agent-injector - namespace: {{ .Release.Namespace }} + name: vault-example-agent-injector labels: - app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} -{{ end }} + app.kubernetes.io/name: vault-example-agent-injector \ No newline at end of file diff --git a/hashicorp/vault/server/server-service.yaml b/hashicorp/vault/server/server-service.yaml index 1ed6d4f..e329d0f 100644 --- a/hashicorp/vault/server/server-service.yaml +++ b/hashicorp/vault/server/server-service.yaml @@ -15,8 +15,8 @@ spec: publishNotReadyAddresses: true ports: - name: http - port: 80 - targetPort: 80 + port: 8200 + targetPort: 8200 - name: internal port: 8201 targetPort: 8201 From 8d893d63d8c74187940266a5778378712bab1f84 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Wed, 26 Feb 2020 16:56:09 +1100 Subject: [PATCH 06/14] example TLS enable --- .../vault/server/server-config-configmap.yaml | 6 ++-- .../vault/server/server-statefulset.yaml | 29 +++++++++---------- hashicorp/vault/server/server-tls-secret.yaml | 9 ++++++ .../vault/server/ssl_generate_self_signed.txt | 29 +++++++++++++++++++ hashicorp/vault/tls/ca-config.json | 13 +++++++++ hashicorp/vault/tls/ca-csr.json | 18 ++++++++++++ hashicorp/vault/tls/vault-csr.json | 16 ++++++++++ 7 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 hashicorp/vault/server/server-tls-secret.yaml create mode 100644 hashicorp/vault/server/ssl_generate_self_signed.txt create mode 100644 hashicorp/vault/tls/ca-config.json create mode 100644 hashicorp/vault/tls/ca-csr.json create mode 100644 hashicorp/vault/tls/vault-csr.json diff --git a/hashicorp/vault/server/server-config-configmap.yaml b/hashicorp/vault/server/server-config-configmap.yaml index 9abe1c3..4cd3f68 100644 --- a/hashicorp/vault/server/server-config-configmap.yaml +++ b/hashicorp/vault/server/server-config-configmap.yaml @@ -9,8 +9,10 @@ data: disable_mlock = true ui = true listener "tcp" { - tls_disable = 1 - address = "[::]:8200" + address = "0.0.0.0:8200" + tls_cert_file = "/vault/ssl/vault-example.pem" + tls_key_file = "/vault/ssl/vault-example-key.pem" + tls_min_version = "tls12" cluster_address = "[::]:8201" } storage "file" { diff --git a/hashicorp/vault/server/server-statefulset.yaml b/hashicorp/vault/server/server-statefulset.yaml index 81fc2ea..d9bdba0 100644 --- a/hashicorp/vault/server/server-statefulset.yaml +++ b/hashicorp/vault/server/server-statefulset.yaml @@ -40,6 +40,9 @@ spec: - name: data persistentVolumeClaim: claimName: vault-claim + - name: tls-secret + secret: + secretName: vault-example-tls-secret initContainers: - name: setupperms image: alpine:latest @@ -75,14 +78,18 @@ spec: fieldRef: fieldPath: status.podIP - name: VAULT_ADDR - value: "http://127.0.0.1:8200" + value: "https://127.0.0.1:8200" - name: VAULT_API_ADDR - value: "http://$(POD_IP):8200" + value: "https://$(POD_IP):8200" - name: SKIP_CHOWN value: "true" - name: SKIP_SETCAP value: "true" + - name: VAULT_CACERT + value: "/vault/ssl/ca.pem" volumeMounts: + - name: tls-secret + mountPath: /vault/ssl - name: config mountPath: /vault/config - name: data @@ -95,23 +102,15 @@ spec: - containerPort: 8202 name: replication readinessProbe: - # Check status; unsealed vault servers return 0 - # The exit code reflects the seal status: - # 0 - unsealed - # 1 - error - # 2 - sealed - exec: - command: ["/bin/sh", "-ec", "vault status -tls-skip-verify"] - failureThreshold: 2 - initialDelaySeconds: 5 - periodSeconds: 3 - successThreshold: 1 - timeoutSeconds: 5 + httpGet: + path: "/v1/sys/health?standbyok=true" + port: 8200 + scheme: HTTPS livenessProbe: httpGet: path: "/v1/sys/health?standbyok=true" port: 8200 - scheme: HTTP + scheme: HTTPS initialDelaySeconds: 60 periodSeconds: 3 successThreshold: 1 diff --git a/hashicorp/vault/server/server-tls-secret.yaml b/hashicorp/vault/server/server-tls-secret.yaml new file mode 100644 index 0000000..60ce94a --- /dev/null +++ b/hashicorp/vault/server/server-tls-secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: vault-example-tls-secret +type: Opaque +data: + vault-example.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVLVENDQXhHZ0F3SUJBZ0lVUDFOZWNYQ3RMM3cvQVJsREdkWmJvV292Vm5jd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdNakkyCk1EUXlNREF3V2hjTk1qRXdNakkxTURReU1EQXdXakJ1TVFzd0NRWURWUVFHRXdKVlV6RVBNQTBHQTFVRUNCTUcKVDNKbFoyOXVNUkV3RHdZRFZRUUhFd2hRYjNKMGJHRnVaREVUTUJFR0ExVUVDaE1LUzNWaVpYSnVaWFJsY3pFTwpNQXdHQTFVRUN4TUZWbUYxYkhReEZqQVVCZ05WQkFNVERYWmhkV3gwTFdWNFlXMXdiR1V3Z2dFaU1BMEdDU3FHClNJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURGbHdwekxwWkJScmpZNFJ6NExpci91bWlsUEFNbXVDVWEKVFY2TjQ1R2lSWVlMbk5hNmhkVW1vRmk3M3NzRFpiT1Q4eHE3eTJUZVI3eVZUV0FORUhodEViSFhNYXgrcnhoSApZYWQ3N2NpWGl1L1U3YXlUYk44QWVFTCtLc0UzU3F2OXpOK0E5QURXUjZlc01TSC9iRDY1dE1YRHBOU3F3dC9YClM4UkwrYldzbHEzY0hmT3VpeVg4NFRwUitONmNwUWNHNVZhNzd3Njltb2x2S21nM0xuZVRKM3EzUy9SeVJ4VjkKVXRWc21NTENwN3c1cVdOUStFcFdRb0xPQmFZTUpMbUZDWFM2YTRubTVld3dmaVFsOS9hd0NUVVVwWVR5UU1oOApnZU43NnEveExaTW51ZWE0Q3hkMEF2QTliK01KY24zZkc2TXN1N3MwbE9yTmVva2dSZ0VqQWdNQkFBR2pnZG93CmdkY3dEZ1lEVlIwUEFRSC9CQVFEQWdXZ01CMEdBMVVkSlFRV01CUUdDQ3NHQVFVRkJ3TUJCZ2dyQmdFRkJRY0QKQWpBTUJnTlZIUk1CQWY4RUFqQUFNQjBHQTFVZERnUVdCQlNwaHV5VW5Ic0VYT0RkcXphNEhkU2kxZVlBZERBZgpCZ05WSFNNRUdEQVdnQlNwaWFWY1FvUEoybnpuRlgyZzZMMHhmWmR4empCWUJnTlZIUkVFVVRCUGdnMTJZWFZzCmRDMWxlR0Z0Y0d4bGdpMTJZWFZzZEMxbGVHRnRjR3hsTG5aaGRXeDBMV1Y0WVcxd2JHVXVjM1pqTG1Oc2RYTjAKWlhJdWJHOWpZV3lDQ1d4dlkyRnNhRzl6ZEljRWZ3QUFBVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBa0VuTAozUnA0b1FNZGN3K0t3QnVONWo3MXBHTjZySXVwZGlTdlkraThJRzhqcVRiR1JqdEQyeFBuWUlja1pRakhTN2VvCnIrYWx5eC82S21oYm0wNzBROFdpdUgxZ2NuNVhqa1FJVW1qdDZLZ0F1QjBsdkdxUFlvZmV6TXVFdkoxTXEzUG0KMTcxa29oYktUME1sRFpzYXBGaHhtdnFIMDY0VHNjdTVrSVVVVGFINW1ZZkZhS0dNR0cvUGJLMWpCQkNwdTl5OApMZUVVeEMvbTFKbjh1M1hVZmRVMm0zaHZ1NnNmMVdrc0c2Sy9NQjI1ckxxZW1ZTjk3OWJQcGt5cnlBRkc4Um1WCkZ1VGl6cVc4UFA5aXNhNDdDUlpQelQ2YldDSndsc1MwT1JaWDcyRGRjODc0YzdXVDF1anFURWh0VWk4NEVlK0sKeElva25Gd1Z5Zno0YWwyWFlBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + vault-example-key.pem: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBeFpjS2N5NldRVWE0Mk9FYytDNHEvN3BvcFR3REpyZ2xHazFlamVPUm9rV0dDNXpXCnVvWFZKcUJZdTk3TEEyV3prL01hdTh0azNrZThsVTFnRFJCNGJSR3gxekdzZnE4WVIyR25lKzNJbDRydjFPMnMKazJ6ZkFIaEMvaXJCTjBxci9jemZnUFFBMWtlbnJERWgvMncrdWJURnc2VFVxc0xmMTB2RVMvbTFySmF0M0Izegpyb3NsL09FNlVmamVuS1VIQnVWV3UrOE92WnFKYnlwb055NTNreWQ2dDB2MGNrY1ZmVkxWYkpqQ3dxZThPYWxqClVQaEtWa0tDemdXbURDUzVoUWwwdW11SjV1WHNNSDRrSmZmMnNBazFGS1dFOGtESWZJSGplK3F2OFMyVEo3bm0KdUFzWGRBTHdQVy9qQ1hKOTN4dWpMTHU3TkpUcXpYcUpJRVlCSXdJREFRQUJBb0lCQUYxNW92dnlvaXFuWm5OVApxL3pNK3BLWWdVRUtMd04yUWpjN091d3RLSXg0RDM0VzZJNjlHYVY0WGdJaTJDLzNRUWxSRE9paXhFbFQ3cWREClA1bHVuVW9jQU9JcEljMmMwQU9VODBMeHJ0L2lYcXVBOVErWmhiWVhMcnBIUjdqOG5ua25IdVZHaWM3VmYwRTYKelRhazR0ZS82WDh3ejFzcGJmUFFhRUQ1RlRWY0RUaUp5QlRDTHpTWXE1alZKTjdRejlQdzRXR1B5WERTNzF6YwpKNHFndDVSTkxGc2tiMnQ2dzJDQjFlOEhSUHhMU0ZycU1SL3hrbWJQM2NnSXl3MEpLVUlFTUR1WWhZY0RhZCtTCkV4TDg2UUVKSUw5VU5FZnY3K1VDMzFURGdzd3loUmZ1N1hIb1BtS0tFSTNXcHZ5aGtINXRJOUEzV0ZwUWZTcmIKTmt4S3YrRUNnWUVBeVpVdGxuT3VlZFVXU1RaMGVaaEJIekI0WWhOOVlhck55TWNvenJNb3dITFdJZWVQdHo4NQpuKzJvRjN1bEh0QmFqKzI1MzU0ZFJrU0hLQkhsRTRmMFlYVGVWTTdqZDFONzVLZWpzQzdNN2JnVHFoMFlJOFdKCmlWaVBONHpKTGNGZEtFcVd4bDRuMEV0TEZzL0lDdWliblBTUm9QUmV5c29nWkpPSWFwVzFpUDhDZ1lFQSt1M3YKekM3YXFIZGtLRGdEb3kwWmtoK3RCT001WjVQV1M4NE8rUUo4QU42TmhMeHd2N29Oa1ZnQk9OMUIwVXdySGFXbQowY3JQeEZybk5mRkg4d0pTTGNMV2hYdWdYelJpaGxaakVXYTBLdGJZOVhxQUd3V2tVcTltL2s4V04zSmpQODdlCmN5VTZMQllOdXNkM0h3TWtoS0xTWXpaU2YyRmRrdnNHT1V4TVE5MENnWUVBcU5QdjRsbndmc2tnYVNEYVhCeFEKTGpjQ0crSUcySTJjMjlNeE1peUtyT09BdzlTVVlQenEzaTdFNFNZRkhOR1RoNGVxYk1hWDdnbm15SUIwUXU5UwpsV3l6NklOOXJxcVUwT1EyQzVDbXdWR3g1bitIZ0M0cENvYkpLOVVWaU9TeGlOVXZnZVBKcElIcTJhZ2Ira2JtClRZWG5rYzRZdGU2alFwanRYNWNTK3pFQ2dZQStWa2ZoU0s2SGRZbUxPRWNuRFhneHhlNjhyUnBBc2dobHNwNGoKbkV0a0IrWE9XT1lGcTFuZGhxaGZFUkJkeDNkYW1TRjFNdFlrcUpTUjRRd0h3Y2JhbVhHam5ZKzh0dzNXNDdVZQp5STN2cW9vaGlib3pmRlpUT0VIMDRYN2FiVzljbGE3TG1pNzJidEFnVzVjclBDT2hVN1hDY2VkU3Y4UjRWQ1k2CnE4cXlmUUtCZ1FDbkt5TEpjZXhZMnpPL0lBZUtmclNLaVNoNHJsaEFhNFJHRHQwUlJGQ3Rhck80dzRNalcvNkEKMHNscUoyazRZT3gzaU1DT3J1RklGcVR5RzFoUDEzSFlhT0N0S3lLYjh5YXZWeklYUzVEZXE4cVpiZlJsUWJPdQoyeUNKS010SVVhT0E5OGd3a3pLSVlsNkNZWXRNQy9HeVg1c0QxWDMyeURmZVo0SUVkVWx4Qnc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= + ca.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURtRENDQW9DZ0F3SUJBZ0lVUnY5bXF2Q3U3akI5ejByN0JoR2JRWWlWZndJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdNakkyCk1EUXhPREF3V2hjTk1qVXdNakkwTURReE9EQXdXakJTTVFzd0NRWURWUVFHRXdKQlZURVFNQTRHQTFVRUNCTUgKUlhoaGJYQnNaVEVTTUJBR0ExVUVCeE1KVFdWc1ltOTFjbTVsTVJBd0RnWURWUVFLRXdkRmVHRnRjR3hsTVFzdwpDUVlEVlFRTEV3SkRRVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFNdXhDM2RMCmlPcE4zYVI1bE9XQmFkV1lONXFkdndzUmU5ekFTNmhQbkJIVUVnUXcveG82MkV2bDRvY2pnYkRPSXMra1YrVGkKYWZkeGhublRJSUdNMDJUaFp1cUpRSFhjN2hsWDRLcjdsaG4yVzdadTM1eWRSZW9jRGZnb1Z6cTM3aytydXd0OAptVFIyTFNQcUhJZmU2Lzd4czRud242MGs3b20xdlNRTzN4TGVOZm9xSWJENk01ZGNkdXNTT01NSjZLU2gxNmF1CjJHZkNrdUgzdEZuMWtBdE1RWDZPc3VJbnpuNTFzdjRRbW52WnowTUZoanVUSHpTR2pZYnB3KzFGcksveGNnRmcKU1M1eGtkYU55SjNpaG4rWjBYWkxYUHMvZEdiSWNKMnVibDk4OCthUWp6Z2JvZ09rMFRBQnlyWnZPYnBMWWNjWQpuR1AxaW1Bdm5uTlRmK2tDQXdFQUFhTm1NR1F3RGdZRFZSMFBBUUgvQkFRREFnRUdNQklHQTFVZEV3RUIvd1FJCk1BWUJBZjhDQVFJd0hRWURWUjBPQkJZRUZLbUpwVnhDZzhuYWZPY1ZmYURvdlRGOWwzSE9NQjhHQTFVZEl3UVkKTUJhQUZLbUpwVnhDZzhuYWZPY1ZmYURvdlRGOWwzSE9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNRU2hCNgpNV0hXTTNTSmNNNkFEWGFRK3Y0SkltUWJ0Ym4xRUlpMkFKVUNIa0tORlhSaHNiYml5OFVhVldmUnZCRnFyMGFzCnA3TlpNUnB5cytRaUYzWTZDSzVFVmZSMUc2YUF6Q25QN1FkTWZzOWFraU9ydlZFaURGYlp0TDhHL3dyV0hTTGwKRWhrajZUR3JsR2FwM2tyZDFGQ1VKTE9BREpNS2VXK3FqYVdjbFRwM01hZ1Q1NStBcEkxeStqdEE4bmdRMGlzcgpBMWNVSVlGbUR6clZudmFxSkVMdlJIak1nTkR3R1lGQUh1dFdrclUybW1wNUMxN29LU1o2dnZ2M05GL3RDTFZYClFjZEt3TUtKbkc3bkYwTmdzTUdDckVXdG1FRHhNb3dJYzdTZXRieWN1aklqdHVVZTNyZktxNkdUUE5aVk1za2sKZ29rVnQvQVFmSWhJL05UMQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== \ No newline at end of file diff --git a/hashicorp/vault/server/ssl_generate_self_signed.txt b/hashicorp/vault/server/ssl_generate_self_signed.txt new file mode 100644 index 0000000..3689f61 --- /dev/null +++ b/hashicorp/vault/server/ssl_generate_self_signed.txt @@ -0,0 +1,29 @@ + + +cd ./hashicorp/vault/tls/ + +docker run -it --rm -v ${PWD}:/work -w /work debian:buster bash +apt-get update && apt-get install -y curl && +curl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl && \ +curl https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson && \ +chmod +x /usr/local/bin/cfssl && \ +chmod +x /usr/local/bin/cfssljson + +#generate certificate +cfssl gencert -initca ca-csr.json | cfssljson -bare ca +cfssl gencert \ + -ca=ca.pem \ + -ca-key=ca-key.pem \ + -config=ca-config.json \ + -hostname="vault-example,vault-example.vault-example.svc.cluster.local,localhost,127.0.0.1" \ + -profile=default \ + vault-csr.json | cfssljson -bare vault-example + +#get values to make a secret +cat ca.pem | base64 | tr -d '\n' +cat vault-example.pem | base64 | tr -d '\n' +cat vault-example-key.pem | base64 | tr -d '\n' + +#TEST +vault login +vault kv put cubbyhole/hello foo=world \ No newline at end of file diff --git a/hashicorp/vault/tls/ca-config.json b/hashicorp/vault/tls/ca-config.json new file mode 100644 index 0000000..2d4b37a --- /dev/null +++ b/hashicorp/vault/tls/ca-config.json @@ -0,0 +1,13 @@ +{ + "signing": { + "default": { + "expiry": "8760h" + }, + "profiles": { + "default": { + "usages": ["signing", "key encipherment", "server auth", "client auth"], + "expiry": "8760h" + } + } + } +} diff --git a/hashicorp/vault/tls/ca-csr.json b/hashicorp/vault/tls/ca-csr.json new file mode 100644 index 0000000..1c863ca --- /dev/null +++ b/hashicorp/vault/tls/ca-csr.json @@ -0,0 +1,18 @@ +{ + "hosts": [ + "cluster.local" + ], + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "AU", + "L": "Melbourne", + "O": "Example", + "OU": "CA", + "ST": "Example" + } + ] +} diff --git a/hashicorp/vault/tls/vault-csr.json b/hashicorp/vault/tls/vault-csr.json new file mode 100644 index 0000000..75e8677 --- /dev/null +++ b/hashicorp/vault/tls/vault-csr.json @@ -0,0 +1,16 @@ +{ + "CN": "vault-example", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "AU", + "L": "Melbourne", + "O": "Kubernetes", + "OU": "Vault", + "ST": "Victoria" + } + ] +} From aebfab763c467490fab26db95f4a8db9da435ecd Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Fri, 28 Feb 2020 21:37:02 +1100 Subject: [PATCH 07/14] updates to pvc and steps list --- hashicorp/vault/_helpers.tpl | 313 ------------------ hashicorp/vault/server/server-pvc.yaml | 2 +- .../ssl_generate_self_signed.txt | 3 + 3 files changed, 4 insertions(+), 314 deletions(-) delete mode 100644 hashicorp/vault/_helpers.tpl rename hashicorp/vault/{server => tls}/ssl_generate_self_signed.txt (90%) diff --git a/hashicorp/vault/_helpers.tpl b/hashicorp/vault/_helpers.tpl deleted file mode 100644 index 0098ab1..0000000 --- a/hashicorp/vault/_helpers.tpl +++ /dev/null @@ -1,313 +0,0 @@ -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to -this (by the DNS naming spec). If release name contains chart name it will -be used as a full name. -*/}} -{{- define "vault.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "vault.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Expand the name of the chart. -*/}} -{{- define "vault.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Compute the maximum number of unavailable replicas for the PodDisruptionBudget. -This defaults to (n/2)-1 where n is the number of members of the server cluster. -Add a special case for replicas=1, where it should default to 0 as well. -*/}} -{{- define "vault.pdb.maxUnavailable" -}} -{{- if eq (int .Values.server.ha.replicas) 1 -}} -{{ 0 }} -{{- else if .Values.server.ha.disruptionBudget.maxUnavailable -}} -{{ .Values.server.ha.disruptionBudget.maxUnavailable -}} -{{- else -}} -{{- div (sub (div (mul (int .Values.server.ha.replicas) 10) 2) 1) 10 -}} -{{- end -}} -{{- end -}} - -{{/* -Set the variable 'mode' to the server mode requested by the user to simplify -template logic. -*/}} -{{- define "vault.mode" -}} - {{- if eq (.Values.server.dev.enabled | toString) "true" -}} - {{- $_ := set . "mode" "dev" -}} - {{- else if eq (.Values.server.ha.enabled | toString) "true" -}} - {{- $_ := set . "mode" "ha" -}} - {{- else if or (eq (.Values.server.standalone.enabled | toString) "true") (eq (.Values.server.standalone.enabled | toString) "-") -}} - {{- $_ := set . "mode" "standalone" -}} - {{- else -}} - {{- $_ := set . "mode" "" -}} - {{- end -}} -{{- end -}} - -{{/* -Set's the replica count based on the different modes configured by user -*/}} -{{- define "vault.replicas" -}} - {{ if eq .mode "standalone" }} - {{- default 1 -}} - {{ else if eq .mode "ha" }} - {{- .Values.server.ha.replicas | default 3 -}} - {{ else }} - {{- default 1 -}} - {{ end }} -{{- end -}} - -{{/* -Set's up configmap mounts if this isn't a dev deployment and the user -defined a custom configuration. Additionally iterates over any -extra volumes the user may have specified (such as a secret with TLS). -*/}} -{{- define "vault.volumes" -}} - {{- if and (ne .mode "dev") (or (ne .Values.server.standalone.config "") (ne .Values.server.ha.config "")) }} - - name: config - configMap: - name: {{ template "vault.fullname" . }}-config - {{ end }} - {{- range .Values.server.extraVolumes }} - - name: userconfig-{{ .name }} - {{ .type }}: - {{- if (eq .type "configMap") }} - name: {{ .name }} - {{- else if (eq .type "secret") }} - secretName: {{ .name }} - {{- end }} - {{- end }} -{{- end -}} - -{{/* -Set's a command to override the entrypoint defined in the image -so we can make the user experience nicer. This works in with -"vault.args" to specify what commands /bin/sh should run. -*/}} -{{- define "vault.command" -}} - {{ if or (eq .mode "standalone") (eq .mode "ha") }} - - "/bin/sh" - - "-ec" - {{ end }} -{{- end -}} - -{{/* -Set's the args for custom command to render the Vault configuration -file with IP addresses to make the out of box experience easier -for users looking to use this chart with Consul Helm. -*/}} -{{- define "vault.args" -}} - {{ if or (eq .mode "standalone") (eq .mode "ha") }} - - | - sed -E "s/HOST_IP/${HOST_IP?}/g" /vault/config/extraconfig-from-values.hcl > /tmp/storageconfig.hcl; - sed -Ei "s/POD_IP/${POD_IP?}/g" /tmp/storageconfig.hcl; - /usr/local/bin/docker-entrypoint.sh vault server -config=/tmp/storageconfig.hcl {{ .Values.server.extraArgs }} - {{ end }} -{{- end -}} - -{{/* -Set's additional environment variables based on the mode. -*/}} -{{- define "vault.envs" -}} - {{ if eq .mode "dev" }} - - name: VAULT_DEV_ROOT_TOKEN_ID - value: "root" - {{ end }} -{{- end -}} - -{{/* -Set's which additional volumes should be mounted to the container -based on the mode configured. -*/}} -{{- define "vault.mounts" -}} - {{ if eq (.Values.server.auditStorage.enabled | toString) "true" }} - - name: audit - mountPath: /vault/audit - {{ end }} - {{ if eq .mode "standalone" }} - {{ if eq (.Values.server.dataStorage.enabled | toString) "true" }} - - name: data - mountPath: /vault/data - {{ end }} - {{ end }} - {{ if and (ne .mode "dev") (or (ne .Values.server.standalone.config "") (ne .Values.server.ha.config "")) }} - - name: config - mountPath: /vault/config - {{ end }} - {{- range .Values.server.extraVolumes }} - - name: userconfig-{{ .name }} - readOnly: true - mountPath: {{ .path | default "/vault/userconfig" }}/{{ .name }} - {{- end }} -{{- end -}} - -{{/* -Set's up the volumeClaimTemplates when data or audit storage is required. HA -might not use data storage since Consul is likely it's backend, however, audit -storage might be desired by the user. -*/}} -{{- define "vault.volumeclaims" -}} - {{- if and (ne .mode "dev") (or .Values.server.dataStorage.enabled .Values.server.auditStorage.enabled) }} - volumeClaimTemplates: - {{- if and (eq (.Values.server.dataStorage.enabled | toString) "true") (eq .mode "standalone") }} - - metadata: - name: data - spec: - accessModes: - - {{ .Values.server.dataStorage.accessMode | default "ReadWriteOnce" }} - resources: - requests: - storage: {{ .Values.server.dataStorage.size }} - {{- if .Values.server.dataStorage.storageClass }} - storageClassName: {{ .Values.server.dataStorage.storageClass }} - {{- end }} - {{ end }} - {{- if eq (.Values.server.auditStorage.enabled | toString) "true" }} - - metadata: - name: audit - spec: - accessModes: - - {{ .Values.server.auditStorage.accessMode | default "ReadWriteOnce" }} - resources: - requests: - storage: {{ .Values.server.auditStorage.size }} - {{- if .Values.server.auditStorage.storageClass }} - storageClassName: {{ .Values.server.auditStorage.storageClass }} - {{- end }} - {{ end }} - {{ end }} -{{- end -}} - -{{/* -Set's the affinity for pod placement when running in standalone and HA modes. -*/}} -{{- define "vault.affinity" -}} - {{- if and (ne .mode "dev") .Values.server.affinity }} - affinity: - {{ tpl .Values.server.affinity . | nindent 8 | trim }} - {{ end }} -{{- end -}} - -{{/* -Set's the toleration for pod placement when running in standalone and HA modes. -*/}} -{{- define "vault.tolerations" -}} - {{- if and (ne .mode "dev") .Values.server.tolerations }} - tolerations: - {{ tpl .Values.server.tolerations . | nindent 8 | trim }} - {{- end }} -{{- end -}} - -{{/* -Set's the node selector for pod placement when running in standalone and HA modes. -*/}} -{{- define "vault.nodeselector" -}} - {{- if and (ne .mode "dev") .Values.server.nodeSelector }} - nodeSelector: - {{ tpl .Values.server.nodeSelector . | indent 8 | trim }} - {{- end }} -{{- end -}} - -{{/* -Sets extra pod annotations -*/}} -{{- define "vault.annotations" -}} - {{- if and (ne .mode "dev") .Values.server.annotations }} - annotations: - {{- tpl .Values.server.annotations . | nindent 8 }} - {{- end }} -{{- end -}} - -{{/* -Sets extra ui service annotations -*/}} -{{- define "vault.ui.annotations" -}} - {{- if .Values.ui.annotations }} - annotations: - {{- toYaml .Values.ui.annotations | nindent 4 }} - {{- end }} -{{- end -}} - -{{/* -Sets extra service account annotations -*/}} -{{- define "vault.serviceAccount.annotations" -}} - {{- if and (ne .mode "dev") .Values.server.serviceAccount.annotations }} - annotations: - {{- toYaml .Values.server.serviceAccount.annotations | nindent 4 }} - {{- end }} -{{- end -}} - -{{/* -Set's the container resources if the user has set any. -*/}} -{{- define "vault.resources" -}} - {{- if .Values.server.resources -}} - resources: -{{ toYaml .Values.server.resources | indent 12}} - {{ end }} -{{- end -}} - -{{/* -Sets the container resources if the user has set any. -*/}} -{{- define "injector.resources" -}} - {{- if .Values.injector.resources -}} - resources: -{{ toYaml .Values.injector.resources | indent 12}} - {{ end }} -{{- end -}} - -{{/* -Inject extra environment vars in the format key:value, if populated -*/}} -{{- define "vault.extraEnvironmentVars" -}} -{{- if .extraEnvironmentVars -}} -{{- range $key, $value := .extraEnvironmentVars }} -- name: {{ $key }} - value: {{ $value | quote }} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Inject extra environment populated by secrets, if populated -*/}} -{{- define "vault.extraSecretEnvironmentVars" -}} -{{- if .extraSecretEnvironmentVars -}} -{{- range .extraSecretEnvironmentVars }} -- name: {{ .envName }} - valueFrom: - secretKeyRef: - name: {{ .secretName }} - key: {{ .secretKey }} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* Scheme for health check and local endpoint */}} -{{- define "vault.scheme" -}} -{{- if .Values.global.tlsDisable -}} -{{ "http" }} -{{- else -}} -{{ "https" }} -{{- end -}} -{{- end -}} diff --git a/hashicorp/vault/server/server-pvc.yaml b/hashicorp/vault/server/server-pvc.yaml index 14dae2c..258976a 100644 --- a/hashicorp/vault/server/server-pvc.yaml +++ b/hashicorp/vault/server/server-pvc.yaml @@ -3,7 +3,7 @@ kind: PersistentVolumeClaim metadata: name: vault-claim spec: - storageClassName: manual + storageClassName: hostpath accessModes: - ReadWriteOnce resources: diff --git a/hashicorp/vault/server/ssl_generate_self_signed.txt b/hashicorp/vault/tls/ssl_generate_self_signed.txt similarity index 90% rename from hashicorp/vault/server/ssl_generate_self_signed.txt rename to hashicorp/vault/tls/ssl_generate_self_signed.txt index 3689f61..0e125e5 100644 --- a/hashicorp/vault/server/ssl_generate_self_signed.txt +++ b/hashicorp/vault/tls/ssl_generate_self_signed.txt @@ -25,5 +25,8 @@ cat vault-example.pem | base64 | tr -d '\n' cat vault-example-key.pem | base64 | tr -d '\n' #TEST +vault operator init #grab keys +vault operator unseal #unseal 3 times + vault login vault kv put cubbyhole/hello foo=world \ No newline at end of file From f2c3647b7d2019edfdb8105bfd1284f75aad7597 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Sat, 29 Feb 2020 22:21:08 +1100 Subject: [PATCH 08/14] WIP - injector examples --- hashicorp/readme.md | 5 +++++ hashicorp/vault/injector/injector-deployment.yaml | 2 +- hashicorp/vault/injector/kind.yaml | 4 ++++ hashicorp/vault/server/server-pvc.yaml | 3 ++- 4 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 hashicorp/readme.md create mode 100644 hashicorp/vault/injector/kind.yaml diff --git a/hashicorp/readme.md b/hashicorp/readme.md new file mode 100644 index 0000000..4056add --- /dev/null +++ b/hashicorp/readme.md @@ -0,0 +1,5 @@ +# Hashicorp Vault Guide + +# Vault + +For the exact files I used during my video guide, refer to commit: diff --git a/hashicorp/vault/injector/injector-deployment.yaml b/hashicorp/vault/injector/injector-deployment.yaml index f4c142f..379934f 100644 --- a/hashicorp/vault/injector/injector-deployment.yaml +++ b/hashicorp/vault/injector/injector-deployment.yaml @@ -32,7 +32,7 @@ spec: - name: AGENT_INJECT_LOG_LEVEL value: "info" - name: AGENT_INJECT_VAULT_ADDR - value: http://vault-example:8200 + value: https://vault-example:8200 - name: AGENT_INJECT_VAULT_IMAGE value: "vault:1.3.1" - name: AGENT_INJECT_TLS_AUTO diff --git a/hashicorp/vault/injector/kind.yaml b/hashicorp/vault/injector/kind.yaml new file mode 100644 index 0000000..e11e6e9 --- /dev/null +++ b/hashicorp/vault/injector/kind.yaml @@ -0,0 +1,4 @@ + +# #https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/ + +#kind create cluster --name vault --image kindest/node:v1.17.0@sha256:9512edae126da271b66b990b6fff768fbb7cd786c7d39e86bdf55906352fdf62 --config kind.yaml \ No newline at end of file diff --git a/hashicorp/vault/server/server-pvc.yaml b/hashicorp/vault/server/server-pvc.yaml index 258976a..55b51fe 100644 --- a/hashicorp/vault/server/server-pvc.yaml +++ b/hashicorp/vault/server/server-pvc.yaml @@ -3,7 +3,8 @@ kind: PersistentVolumeClaim metadata: name: vault-claim spec: - storageClassName: hostpath + storageClassName: standard + #storageClassName: hostpath accessModes: - ReadWriteOnce resources: From 428fc51e76905e7914c2271a3ec03616c39636df Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Sun, 1 Mar 2020 18:23:22 +1100 Subject: [PATCH 09/14] updates --- hashicorp/readme.md | 54 ++++++++++++++++++- hashicorp/vault/example-app/deployment.yaml | 27 ++++++++++ hashicorp/vault/example-app/patch.yaml | 39 ++++++++++++++ .../vault/injector/injector-deployment.yaml | 2 +- .../injector/injector-mutating-webhook.yaml | 12 +---- hashicorp/vault/injector/kind.yaml | 4 -- hashicorp/vault/policies/app-policy.md | 15 ++++++ hashicorp/vault/policies/example-secret.md | 11 ++++ .../vault/policies/vault-enable-auth-k8s.md | 20 +++++++ hashicorp/vault/server/server-tls-secret.yaml | 6 +-- .../vault/tls/ssl_generate_self_signed.txt | 2 +- 11 files changed, 172 insertions(+), 20 deletions(-) create mode 100644 hashicorp/vault/example-app/deployment.yaml create mode 100644 hashicorp/vault/example-app/patch.yaml delete mode 100644 hashicorp/vault/injector/kind.yaml create mode 100644 hashicorp/vault/policies/app-policy.md create mode 100644 hashicorp/vault/policies/example-secret.md create mode 100644 hashicorp/vault/policies/vault-enable-auth-k8s.md diff --git a/hashicorp/readme.md b/hashicorp/readme.md index 4056add..49e3fe1 100644 --- a/hashicorp/readme.md +++ b/hashicorp/readme.md @@ -2,4 +2,56 @@ # Vault -For the exact files I used during my video guide, refer to commit: +For this tutorial, I use Kuberentes 1.17 +It's critical because we'll need certain [admission controllers](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) enabled. + +To get 1.17 for Linux\Windows, just use `kind` since you can create a 1.17 with admissions all setup. + +``` +kind create cluster --name vault --image kindest/node:v1.17.0@sha256:9512edae126da271b66b990b6fff768fbb7cd786c7d39e86bdf55906352fdf62 +``` + +## TLS End to End Encryption + +See steps in `hashicorp/vault/tls/ssl_generate_self_signed.txt` +You'll need to generate TLS certs (or bring your own) +Create base64 strings from the files, place it in the `server-tls-secret.yaml` and apply it. +Remember not to check-in your TLS to GIT :) + +## Deployment + +``` +kubectl create ns vault-example +kubectl -n vault-example apply -f .\hashicorp\vault\server\ +``` + +## Storage + +``` +kubectl -n vault-example get pvc +``` +ensure vault-claim is bound, if not, `kubectl -n vault-example describe pvc vault-claim` +ensure correct storage class is used for your cluster. +if you need to change the storage class, deleve the pvc , edit YAML and re-apply + +## Initialising Vault + +``` +kubectl -n vault-example exec -it vault-example-0 vault operator init +kubectl -n vault-example exec -it vault-example-0 vault operator unseal +``` + +## Depploy the Injector + +Injector allows pods to automatically get secrets from the vault. + +``` +kubectl -n vault-example apply -f .\hashicorp\vault\injector\ +``` + + + + + + + diff --git a/hashicorp/vault/example-app/deployment.yaml b/hashicorp/vault/example-app/deployment.yaml new file mode 100644 index 0000000..01a480e --- /dev/null +++ b/hashicorp/vault/example-app/deployment.yaml @@ -0,0 +1,27 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: app + labels: + app: vault-agent-demo +spec: + selector: + matchLabels: + app: vault-agent-demo + replicas: 1 + template: + metadata: + labels: + app: vault-agent-demo + spec: + serviceAccountName: app + containers: + - name: app + image: jweissig/app:0.0.1 +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: app + labels: + app: vault-agent-demo \ No newline at end of file diff --git a/hashicorp/vault/example-app/patch.yaml b/hashicorp/vault/example-app/patch.yaml new file mode 100644 index 0000000..b2679e1 --- /dev/null +++ b/hashicorp/vault/example-app/patch.yaml @@ -0,0 +1,39 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: app + labels: + app: vault-agent-demo +spec: + selector: + matchLabels: + app: vault-agent-demo + replicas: 1 + template: + metadata: + annotations: + vault.hashicorp.com/agent-inject: "true" + vault.hashicorp.com/tls-skip-verify: "true" + vault.hashicorp.com/agent-inject-secret-helloworld: "secret/helloworld" + vault.hashicorp.com/agent-inject-template-helloworld: | + {{- with secret "secret/helloworld" -}} + { + "username" : "{{ .Data.username }}", + "password" : "{{ .Data.password }}" + } + {{- end }} + vault.hashicorp.com/role: "myapp" + labels: + app: vault-agent-demo + spec: + serviceAccountName: app + containers: + - name: app + image: jweissig/app:0.0.1 +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: app + labels: + app: vault-agent-demo \ No newline at end of file diff --git a/hashicorp/vault/injector/injector-deployment.yaml b/hashicorp/vault/injector/injector-deployment.yaml index 379934f..f7769fb 100644 --- a/hashicorp/vault/injector/injector-deployment.yaml +++ b/hashicorp/vault/injector/injector-deployment.yaml @@ -32,7 +32,7 @@ spec: - name: AGENT_INJECT_LOG_LEVEL value: "info" - name: AGENT_INJECT_VAULT_ADDR - value: https://vault-example:8200 + value: https://vault-example.vault-example.svc:8200 - name: AGENT_INJECT_VAULT_IMAGE value: "vault:1.3.1" - name: AGENT_INJECT_TLS_AUTO diff --git a/hashicorp/vault/injector/injector-mutating-webhook.yaml b/hashicorp/vault/injector/injector-mutating-webhook.yaml index caf6ba2..7a455b1 100644 --- a/hashicorp/vault/injector/injector-mutating-webhook.yaml +++ b/hashicorp/vault/injector/injector-mutating-webhook.yaml @@ -1,4 +1,4 @@ -apiVersion: admissionregistration.k8s.io/v1 +apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: name: vault-example-agent-injector-cfg @@ -17,12 +17,4 @@ webhooks: apiGroups: [""] apiVersions: ["v1"] resources: ["pods"] - namespaceSelector: - matchExpressions: - - key: name - operator: In - values: - - example-app - sideEffects: None - admissionReviewVersions: - - "v1" \ No newline at end of file + namespaceSelector: \ No newline at end of file diff --git a/hashicorp/vault/injector/kind.yaml b/hashicorp/vault/injector/kind.yaml deleted file mode 100644 index e11e6e9..0000000 --- a/hashicorp/vault/injector/kind.yaml +++ /dev/null @@ -1,4 +0,0 @@ - -# #https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/ - -#kind create cluster --name vault --image kindest/node:v1.17.0@sha256:9512edae126da271b66b990b6fff768fbb7cd786c7d39e86bdf55906352fdf62 --config kind.yaml \ No newline at end of file diff --git a/hashicorp/vault/policies/app-policy.md b/hashicorp/vault/policies/app-policy.md new file mode 100644 index 0000000..920a593 --- /dev/null +++ b/hashicorp/vault/policies/app-policy.md @@ -0,0 +1,15 @@ +# Create an App policy + +``` +kubectl -n vault-example exec -it vault-example-0 sh + +cat < /home/vault/app-policy.hcl +path "secret*" { + capabilities = ["read"] +} +EOF + +vault login +vault policy write app /home/vault/app-policy.hcl + +``` \ No newline at end of file diff --git a/hashicorp/vault/policies/example-secret.md b/hashicorp/vault/policies/example-secret.md new file mode 100644 index 0000000..cee711e --- /dev/null +++ b/hashicorp/vault/policies/example-secret.md @@ -0,0 +1,11 @@ +# Create example secret + +``` +kubectl -n vault-example exec -it vault-example-0 sh + +vault login + +vault secrets enable -path=secret/ kv +vault kv put secret/helloworld username=foobaruser password=foobarbazpass + +``` \ No newline at end of file diff --git a/hashicorp/vault/policies/vault-enable-auth-k8s.md b/hashicorp/vault/policies/vault-enable-auth-k8s.md new file mode 100644 index 0000000..7afc45a --- /dev/null +++ b/hashicorp/vault/policies/vault-enable-auth-k8s.md @@ -0,0 +1,20 @@ +# Enable Kubernetes Vault Auth + +``` +kubectl -n vault-example exec -it vault-example-0 sh + +vault login +vault auth enable kubernetes + +vault write auth/kubernetes/config \ + token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ + kubernetes_host=https://${KUBERNETES_PORT_443_TCP_ADDR}:443 \ + kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt + +vault write auth/kubernetes/role/myapp \ + bound_service_account_names=app \ + bound_service_account_namespaces=vault-example \ + policies=app \ + ttl=1h + +``` \ No newline at end of file diff --git a/hashicorp/vault/server/server-tls-secret.yaml b/hashicorp/vault/server/server-tls-secret.yaml index 60ce94a..bfb4100 100644 --- a/hashicorp/vault/server/server-tls-secret.yaml +++ b/hashicorp/vault/server/server-tls-secret.yaml @@ -4,6 +4,6 @@ metadata: name: vault-example-tls-secret type: Opaque data: - vault-example.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVLVENDQXhHZ0F3SUJBZ0lVUDFOZWNYQ3RMM3cvQVJsREdkWmJvV292Vm5jd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdNakkyCk1EUXlNREF3V2hjTk1qRXdNakkxTURReU1EQXdXakJ1TVFzd0NRWURWUVFHRXdKVlV6RVBNQTBHQTFVRUNCTUcKVDNKbFoyOXVNUkV3RHdZRFZRUUhFd2hRYjNKMGJHRnVaREVUTUJFR0ExVUVDaE1LUzNWaVpYSnVaWFJsY3pFTwpNQXdHQTFVRUN4TUZWbUYxYkhReEZqQVVCZ05WQkFNVERYWmhkV3gwTFdWNFlXMXdiR1V3Z2dFaU1BMEdDU3FHClNJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURGbHdwekxwWkJScmpZNFJ6NExpci91bWlsUEFNbXVDVWEKVFY2TjQ1R2lSWVlMbk5hNmhkVW1vRmk3M3NzRFpiT1Q4eHE3eTJUZVI3eVZUV0FORUhodEViSFhNYXgrcnhoSApZYWQ3N2NpWGl1L1U3YXlUYk44QWVFTCtLc0UzU3F2OXpOK0E5QURXUjZlc01TSC9iRDY1dE1YRHBOU3F3dC9YClM4UkwrYldzbHEzY0hmT3VpeVg4NFRwUitONmNwUWNHNVZhNzd3Njltb2x2S21nM0xuZVRKM3EzUy9SeVJ4VjkKVXRWc21NTENwN3c1cVdOUStFcFdRb0xPQmFZTUpMbUZDWFM2YTRubTVld3dmaVFsOS9hd0NUVVVwWVR5UU1oOApnZU43NnEveExaTW51ZWE0Q3hkMEF2QTliK01KY24zZkc2TXN1N3MwbE9yTmVva2dSZ0VqQWdNQkFBR2pnZG93CmdkY3dEZ1lEVlIwUEFRSC9CQVFEQWdXZ01CMEdBMVVkSlFRV01CUUdDQ3NHQVFVRkJ3TUJCZ2dyQmdFRkJRY0QKQWpBTUJnTlZIUk1CQWY4RUFqQUFNQjBHQTFVZERnUVdCQlNwaHV5VW5Ic0VYT0RkcXphNEhkU2kxZVlBZERBZgpCZ05WSFNNRUdEQVdnQlNwaWFWY1FvUEoybnpuRlgyZzZMMHhmWmR4empCWUJnTlZIUkVFVVRCUGdnMTJZWFZzCmRDMWxlR0Z0Y0d4bGdpMTJZWFZzZEMxbGVHRnRjR3hsTG5aaGRXeDBMV1Y0WVcxd2JHVXVjM1pqTG1Oc2RYTjAKWlhJdWJHOWpZV3lDQ1d4dlkyRnNhRzl6ZEljRWZ3QUFBVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBa0VuTAozUnA0b1FNZGN3K0t3QnVONWo3MXBHTjZySXVwZGlTdlkraThJRzhqcVRiR1JqdEQyeFBuWUlja1pRakhTN2VvCnIrYWx5eC82S21oYm0wNzBROFdpdUgxZ2NuNVhqa1FJVW1qdDZLZ0F1QjBsdkdxUFlvZmV6TXVFdkoxTXEzUG0KMTcxa29oYktUME1sRFpzYXBGaHhtdnFIMDY0VHNjdTVrSVVVVGFINW1ZZkZhS0dNR0cvUGJLMWpCQkNwdTl5OApMZUVVeEMvbTFKbjh1M1hVZmRVMm0zaHZ1NnNmMVdrc0c2Sy9NQjI1ckxxZW1ZTjk3OWJQcGt5cnlBRkc4Um1WCkZ1VGl6cVc4UFA5aXNhNDdDUlpQelQ2YldDSndsc1MwT1JaWDcyRGRjODc0YzdXVDF1anFURWh0VWk4NEVlK0sKeElva25Gd1Z5Zno0YWwyWFlBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= - vault-example-key.pem: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBeFpjS2N5NldRVWE0Mk9FYytDNHEvN3BvcFR3REpyZ2xHazFlamVPUm9rV0dDNXpXCnVvWFZKcUJZdTk3TEEyV3prL01hdTh0azNrZThsVTFnRFJCNGJSR3gxekdzZnE4WVIyR25lKzNJbDRydjFPMnMKazJ6ZkFIaEMvaXJCTjBxci9jemZnUFFBMWtlbnJERWgvMncrdWJURnc2VFVxc0xmMTB2RVMvbTFySmF0M0Izegpyb3NsL09FNlVmamVuS1VIQnVWV3UrOE92WnFKYnlwb055NTNreWQ2dDB2MGNrY1ZmVkxWYkpqQ3dxZThPYWxqClVQaEtWa0tDemdXbURDUzVoUWwwdW11SjV1WHNNSDRrSmZmMnNBazFGS1dFOGtESWZJSGplK3F2OFMyVEo3bm0KdUFzWGRBTHdQVy9qQ1hKOTN4dWpMTHU3TkpUcXpYcUpJRVlCSXdJREFRQUJBb0lCQUYxNW92dnlvaXFuWm5OVApxL3pNK3BLWWdVRUtMd04yUWpjN091d3RLSXg0RDM0VzZJNjlHYVY0WGdJaTJDLzNRUWxSRE9paXhFbFQ3cWREClA1bHVuVW9jQU9JcEljMmMwQU9VODBMeHJ0L2lYcXVBOVErWmhiWVhMcnBIUjdqOG5ua25IdVZHaWM3VmYwRTYKelRhazR0ZS82WDh3ejFzcGJmUFFhRUQ1RlRWY0RUaUp5QlRDTHpTWXE1alZKTjdRejlQdzRXR1B5WERTNzF6YwpKNHFndDVSTkxGc2tiMnQ2dzJDQjFlOEhSUHhMU0ZycU1SL3hrbWJQM2NnSXl3MEpLVUlFTUR1WWhZY0RhZCtTCkV4TDg2UUVKSUw5VU5FZnY3K1VDMzFURGdzd3loUmZ1N1hIb1BtS0tFSTNXcHZ5aGtINXRJOUEzV0ZwUWZTcmIKTmt4S3YrRUNnWUVBeVpVdGxuT3VlZFVXU1RaMGVaaEJIekI0WWhOOVlhck55TWNvenJNb3dITFdJZWVQdHo4NQpuKzJvRjN1bEh0QmFqKzI1MzU0ZFJrU0hLQkhsRTRmMFlYVGVWTTdqZDFONzVLZWpzQzdNN2JnVHFoMFlJOFdKCmlWaVBONHpKTGNGZEtFcVd4bDRuMEV0TEZzL0lDdWliblBTUm9QUmV5c29nWkpPSWFwVzFpUDhDZ1lFQSt1M3YKekM3YXFIZGtLRGdEb3kwWmtoK3RCT001WjVQV1M4NE8rUUo4QU42TmhMeHd2N29Oa1ZnQk9OMUIwVXdySGFXbQowY3JQeEZybk5mRkg4d0pTTGNMV2hYdWdYelJpaGxaakVXYTBLdGJZOVhxQUd3V2tVcTltL2s4V04zSmpQODdlCmN5VTZMQllOdXNkM0h3TWtoS0xTWXpaU2YyRmRrdnNHT1V4TVE5MENnWUVBcU5QdjRsbndmc2tnYVNEYVhCeFEKTGpjQ0crSUcySTJjMjlNeE1peUtyT09BdzlTVVlQenEzaTdFNFNZRkhOR1RoNGVxYk1hWDdnbm15SUIwUXU5UwpsV3l6NklOOXJxcVUwT1EyQzVDbXdWR3g1bitIZ0M0cENvYkpLOVVWaU9TeGlOVXZnZVBKcElIcTJhZ2Ira2JtClRZWG5rYzRZdGU2alFwanRYNWNTK3pFQ2dZQStWa2ZoU0s2SGRZbUxPRWNuRFhneHhlNjhyUnBBc2dobHNwNGoKbkV0a0IrWE9XT1lGcTFuZGhxaGZFUkJkeDNkYW1TRjFNdFlrcUpTUjRRd0h3Y2JhbVhHam5ZKzh0dzNXNDdVZQp5STN2cW9vaGlib3pmRlpUT0VIMDRYN2FiVzljbGE3TG1pNzJidEFnVzVjclBDT2hVN1hDY2VkU3Y4UjRWQ1k2CnE4cXlmUUtCZ1FDbkt5TEpjZXhZMnpPL0lBZUtmclNLaVNoNHJsaEFhNFJHRHQwUlJGQ3Rhck80dzRNalcvNkEKMHNscUoyazRZT3gzaU1DT3J1RklGcVR5RzFoUDEzSFlhT0N0S3lLYjh5YXZWeklYUzVEZXE4cVpiZlJsUWJPdQoyeUNKS010SVVhT0E5OGd3a3pLSVlsNkNZWXRNQy9HeVg1c0QxWDMyeURmZVo0SUVkVWx4Qnc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= - ca.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURtRENDQW9DZ0F3SUJBZ0lVUnY5bXF2Q3U3akI5ejByN0JoR2JRWWlWZndJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdNakkyCk1EUXhPREF3V2hjTk1qVXdNakkwTURReE9EQXdXakJTTVFzd0NRWURWUVFHRXdKQlZURVFNQTRHQTFVRUNCTUgKUlhoaGJYQnNaVEVTTUJBR0ExVUVCeE1KVFdWc1ltOTFjbTVsTVJBd0RnWURWUVFLRXdkRmVHRnRjR3hsTVFzdwpDUVlEVlFRTEV3SkRRVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFNdXhDM2RMCmlPcE4zYVI1bE9XQmFkV1lONXFkdndzUmU5ekFTNmhQbkJIVUVnUXcveG82MkV2bDRvY2pnYkRPSXMra1YrVGkKYWZkeGhublRJSUdNMDJUaFp1cUpRSFhjN2hsWDRLcjdsaG4yVzdadTM1eWRSZW9jRGZnb1Z6cTM3aytydXd0OAptVFIyTFNQcUhJZmU2Lzd4czRud242MGs3b20xdlNRTzN4TGVOZm9xSWJENk01ZGNkdXNTT01NSjZLU2gxNmF1CjJHZkNrdUgzdEZuMWtBdE1RWDZPc3VJbnpuNTFzdjRRbW52WnowTUZoanVUSHpTR2pZYnB3KzFGcksveGNnRmcKU1M1eGtkYU55SjNpaG4rWjBYWkxYUHMvZEdiSWNKMnVibDk4OCthUWp6Z2JvZ09rMFRBQnlyWnZPYnBMWWNjWQpuR1AxaW1Bdm5uTlRmK2tDQXdFQUFhTm1NR1F3RGdZRFZSMFBBUUgvQkFRREFnRUdNQklHQTFVZEV3RUIvd1FJCk1BWUJBZjhDQVFJd0hRWURWUjBPQkJZRUZLbUpwVnhDZzhuYWZPY1ZmYURvdlRGOWwzSE9NQjhHQTFVZEl3UVkKTUJhQUZLbUpwVnhDZzhuYWZPY1ZmYURvdlRGOWwzSE9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNRU2hCNgpNV0hXTTNTSmNNNkFEWGFRK3Y0SkltUWJ0Ym4xRUlpMkFKVUNIa0tORlhSaHNiYml5OFVhVldmUnZCRnFyMGFzCnA3TlpNUnB5cytRaUYzWTZDSzVFVmZSMUc2YUF6Q25QN1FkTWZzOWFraU9ydlZFaURGYlp0TDhHL3dyV0hTTGwKRWhrajZUR3JsR2FwM2tyZDFGQ1VKTE9BREpNS2VXK3FqYVdjbFRwM01hZ1Q1NStBcEkxeStqdEE4bmdRMGlzcgpBMWNVSVlGbUR6clZudmFxSkVMdlJIak1nTkR3R1lGQUh1dFdrclUybW1wNUMxN29LU1o2dnZ2M05GL3RDTFZYClFjZEt3TUtKbkc3bkYwTmdzTUdDckVXdG1FRHhNb3dJYzdTZXRieWN1aklqdHVVZTNyZktxNkdUUE5aVk1za2sKZ29rVnQvQVFmSWhJL05UMQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== \ No newline at end of file + vault-example.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVUVENDQXpXZ0F3SUJBZ0lVRU1JUSs4cFc3MDJjdzJUdFlYN2VmM2ZsUnYwd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdNekF4Ck1ETXlOakF3V2hjTk1qRXdNekF4TURNeU5qQXdXakJ4TVFzd0NRWURWUVFHRXdKQlZURVJNQThHQTFVRUNCTUkKVm1samRHOXlhV0V4RWpBUUJnTlZCQWNUQ1UxbGJHSnZkWEp1WlRFVE1CRUdBMVVFQ2hNS1MzVmlaWEp1WlhSbApjekVPTUF3R0ExVUVDeE1GVm1GMWJIUXhGakFVQmdOVkJBTVREWFpoZFd4MExXVjRZVzF3YkdVd2dnRWlNQTBHCkNTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFEQ0VNaERwQ3RjZG9uVS9GT1BGdjIxb0xiejVMSU4KS1ppanNZM1EvWHVWZG8vY1pFSW9uazd5SFZJdTA1NU9xWTJDQnJiM2dwVHpDWVoxZFozb3lsRVdtV1hFakR5UQoyZEFPTFM2SEdoTUZLZ3FvYWlKV3pPb1JPeVhYakVXanBzTGQxWVdnVFRlY0FxMDN0R3lBVjY1WVg5dUpFY3hxCnpSMEFBVDdPZWh4aFNzSUMzeFFyczRNbURSbjdnSVNwTHErcU5RZmc3VEtMOEtleUNBNWFkMVZOWnJ3cktZZ1AKZlNwRUt6ZGhVSGZMaFlEa3M4L0NZUTFLZEJjMnc3THVSMnJDTm9ISmF5ajcwUnVpeUNubGErWU5MeHd4REhGNgpxbEFEUXh6SmZFNWtRRmljVS9HblpLV2dyNVoyNWhpYUdkZjQ2SDk1RE9lMzVzUi8rL21IcFlKbEFnTUJBQUdqCmdmc3dnZmd3RGdZRFZSMFBBUUgvQkFRREFnV2dNQjBHQTFVZEpRUVdNQlFHQ0NzR0FRVUZCd01CQmdnckJnRUYKQlFjREFqQU1CZ05WSFJNQkFmOEVBakFBTUIwR0ExVWREZ1FXQkJROGk3VnFrWXRxclVYckp5c3dKL3NSc2dTYwpMREFmQmdOVkhTTUVHREFXZ0JRMVhlQVFUcG9xS25CbjNPQk5VQ1NVc0tYNk56QjVCZ05WSFJFRWNqQndnZzEyCllYVnNkQzFsZUdGdGNHeGxnaTEyWVhWc2RDMWxlR0Z0Y0d4bExuWmhkV3gwTFdWNFlXMXdiR1V1YzNaakxtTnMKZFhOMFpYSXViRzlqWVd5Q0gzWmhkV3gwTFdWNFlXMXdiR1V1ZG1GMWJIUXRaWGhoYlhCc1pTNXpkbU9DQ1d4dgpZMkZzYUc5emRJY0Vmd0FBQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQUNLUlJHYmw5OUxuYnFBbHlRRzd5CjNFcE1COXdmRUdtOG1hMzZwc05nODhPY1Q1K2hpWnRJR3hQT0w1dEJVRURWYWFjREtpaUg0WG1hdGN2THhHVmgKSW5NYXNIbHB2RlBoUTRONDdqdjBRMk1tL2x4ZzBuOGZTNjYwMU5LNkEycmxBNXl6blZBNGlxeVV5dzZ1K2NmVwpOL3gwWUtINTRLTlA5WEZhQy9aQStoWWNFSG5ZRGZHa01vYXZHVnE1ZnB5T2Zqd2dLT1llVDhTZkJ0VG9zRUNqCkFjR3FmVHp1VGlpSkozaFlNMVViMGVUdzVSU21Gc0tGNm5icG5RYnYzQm1iNjR1WStVbzZaYUM2RXh0SmsxcWYKcjVpbmxjTDA0Sk1UYVhVQ3lMSW5mdjZMZXVXTllldmpmN1dyblJiZ2xuUGJYVDEvazREVDJlWkRiaWFTVHNHcApGUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + vault-example-key.pem: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBd2hESVE2UXJYSGFKMVB4VGp4Yjl0YUMyOCtTeURTbVlvN0dOMFAxN2xYYVAzR1JDCktKNU84aDFTTHRPZVRxbU5nZ2EyOTRLVTh3bUdkWFdkNk1wUkZwbGx4SXc4a05uUURpMHVoeG9UQlNvS3FHb2kKVnN6cUVUc2wxNHhGbzZiQzNkV0ZvRTAzbkFLdE43UnNnRmV1V0YvYmlSSE1hczBkQUFFK3pub2NZVXJDQXQ4VQpLN09ESmcwWis0Q0VxUzZ2cWpVSDRPMHlpL0Nuc2dnT1duZFZUV2E4S3ltSUQzMHFSQ3MzWVZCM3k0V0E1TFBQCndtRU5TblFYTnNPeTdrZHF3amFCeVdzbys5RWJvc2dwNVd2bURTOGNNUXh4ZXFwUUEwTWN5WHhPWkVCWW5GUHgKcDJTbG9LK1dkdVlZbWhuWCtPaC9lUXpudCtiRWYvdjVoNldDWlFJREFRQUJBb0lCQUh1UGNlTFhZU0JTL1BrVgoyeUhzOG9hMUdDZDdnZjR0Y05rd2tHbnpLcitFS0o2Yld5QS9nMlpXVXVBcnJzekkyYWRqSFJYRUY1QVNqWUMxCjdWK3RpU21KYTZsVDNMQWhibjNJT0txZWFHUE9XOURWR3A0SGhEU0tZMUsxSmhYSGRLVUhjVGdhVWdETUYzdXoKTGE0ZHBZenhJM2RIVk03Zlg4cUVBSGc0ZVY5YnZQdTN4M0NQNm9yV1l0bzZzbUhEcjN2ZkZPM0RMQnIwVHRzRwpVVS9mbjcrU1U3Y2FmQTRJemc0TTlKdXl2aHZzZm91SENCajVXczJvWWxOY2FoV2pxY0tGZnA0WUoya0hkK2dlClR4VlVIejBKTDIrY0pQdThLQ0IxdllKanlwRnhvRlRUZC81cXptK3ZsK2pRNUprY2Nxd3luaXJXYVVKRm5XU3kKank3dnlyVUNnWUVBMmkxRzhHM050YkJHZHFNeVJjQmdGUHZrNXVqTUlGT1hJNHNIVkZ1TEluYzF1MGZZNkR3dQpObEJzNmFCU0ZYOSsybk1seVFDMzlzelVyWlRQakRmRkZvcGczR2FpQ0hvY09yYUVFUWhPSDBWaVpUNGJjMWE0ClNuV3F6aWRhdmkzN3FMZjB2aXladCtsYmg2NllPUWxBSHFPSW4wUlhoUzk1TjBsTzlXYkhCUjhDZ1lFQTQ3VngKRFVSS2xWL1V3REJBa3F6cVpxSWdESklwdGRGL2Yvam9uUXlVYnBLM2llYWUyN3pmaHNLZEFTRGZBcHA5aTd5KwpST1NWdnNWUGRidU9vWGJKQWxzcVJlSVBYdmVYODdGWlluNVZhWkdVdjBteHlwQXZ0NTcrdFdWT1E1aGZydGNYCk1DMyttWFFUTkxhZUxGMThySW11UktENlBxNW1JVk5kS3hibjQvc0NnWUVBeFpFT2xoVzRtL2grTmx4ZDM4L3UKc2RIUVhGRWUxMzhhYy9NbnRmb1hxaVF0SWVSVHhTa0o1K0U0WHU3d3Bjc0lRaVRYYUljZ0QzczRjOTgzZW8vZQpCeVZUeFFHalpPMit0bVFrZjQvM3ZsV0VYbzI1S2Q2emo2bXgvSENpdVdqR1pPZi8xbDVvN0tPQ1lRRjNrdDZQCms2OGV2cXFTWG1hNDY1bVV5S0JEUkowQ2dZRUF3Y2llcmppbzlGZzZ1VmdYQy93bCt6UUw3RWJUUWsxSW9VTFYKeXhseWxHczkwUmkzcHE4azF3MTJDZ2pNWU8zUzNBSEROdVFGWC9XUXV0UGovUnNXMDI5OEdUN1o3K3Jyb05NVQpDNU1SNHlhbW5PZjlhektydVN1US9oUjV0MkxNUXdIL1ZOdy9xSjQwM2c1dnE3ZmZxd0g4a2FFaGRnaDdGKzlYCkFaMmJ1Tk1DZ1lBZWJEaTMrQ3VmQzFOOGlwWUdVS1hSOFRSaFJPdDlmTzdGYjJRM25NdE1UZUx2YzJxNXlaY3oKdThIVUZCbk56Mmx6WDV3N2VwOUtSNzhvRFhRaVZGTnBYY1JwYm9ONS9YZHNFbUlXemNlN0V4ZFI4TGE4TS9YcQpKazkwdis0T2ovd013enlBZm9ZT0NHZ3Y0ZWdCNmZ0MXRwMVBjUG1QcTZCcnF3am1wNERYYmc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= + ca.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURtRENDQW9DZ0F3SUJBZ0lVZnFKeTY5QXlnY1l5MGgvbC9XdTRkeVU4MlRFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdNekF4Ck1ETXlOVEF3V2hjTk1qVXdNakk0TURNeU5UQXdXakJTTVFzd0NRWURWUVFHRXdKQlZURVFNQTRHQTFVRUNCTUgKUlhoaGJYQnNaVEVTTUJBR0ExVUVCeE1KVFdWc1ltOTFjbTVsTVJBd0RnWURWUVFLRXdkRmVHRnRjR3hsTVFzdwpDUVlEVlFRTEV3SkRRVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFNelVkWGlOCjRiN3dDK3JrRlFkTFlsclpleWttNkQrYk16T3B2N0JnZUkrdnIrVy9GZE9HR1ZkMnQwbWpDMVhvcWgrSCtERU0Kc3Z0bFpLOW9DT080RnlleUZuSXhqcktDNXp0REJJSlNJYzhYR2NjUTVFY1VXdDRiMnVOVXVKM1dMVFlYcFpFeApqVnd3YzY4aHJ6cC82TDVuMUJxVERxaWxCYk5JUi91OUdmeU40bWpXQlRUbzArTFhkakpkZ3BvOWxmWC83aEFhCnRxT0FIcFJqRWhJM0RreEZyREdSVlJsQ1ZBZlo2MWt5bFRWLzJNMW5CalJWU2RTbDlJK0lWeU4xbXpMM3AzTGwKQ3lwYWxpbGtTWS9LaTNsSFRpNnZGeEJ6c042c3N5SktmeDdpMVJmNDk2MjlKQWZNNXFad0x4enp5OFFNeEw0ZQpMN1VyYmdNMWgwRUhCa0VDQXdFQUFhTm1NR1F3RGdZRFZSMFBBUUgvQkFRREFnRUdNQklHQTFVZEV3RUIvd1FJCk1BWUJBZjhDQVFJd0hRWURWUjBPQkJZRUZEVmQ0QkJPbWlvcWNHZmM0RTFRSkpTd3BmbzNNQjhHQTFVZEl3UVkKTUJhQUZEVmQ0QkJPbWlvcWNHZmM0RTFRSkpTd3BmbzNNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUFnMkZBWApnTUF4UXlndzVrcGkrSFpNWDg5K0QxQ1ptVHhGUXBhUk5vSzdOR1NTVGZLS1Z0Vjdaa1IxVVhJWVJhZTF0R2o2Cm1YeHRpOS9xd281ZlpBckNEaloyVVVNV29EVHFTNHY3ZGVaVmxiRmlVWnl2VXRPb0hjTEhhWitLdmlkVG0yL3UKMDJ0TjhscGtEMDFzeXU5akIyK2wrT01CMUtlRGpXNS8wcDk0ay8xMUd5U2dJRDF1RVVyaFUrai9CMFp1L09GegpXNE00akcrRWlsK1puMHpzcm1wVStmQk1RK20wQzFXZ05mU3NKU0FCYlZxSEVMQ05USUYzVG91V3lNdEE1YUZxCnJ1SFQwNUxxUzl6QVVKNTZ0Q2dqbGdHMDUrUG9FQjFSZUtvV1JURnBNQ0JSL0RxWjk4SnprRDNLYTJyVkMwOXgKUCs1TTNobzl0Q3J4SW42bQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== \ No newline at end of file diff --git a/hashicorp/vault/tls/ssl_generate_self_signed.txt b/hashicorp/vault/tls/ssl_generate_self_signed.txt index 0e125e5..75f9571 100644 --- a/hashicorp/vault/tls/ssl_generate_self_signed.txt +++ b/hashicorp/vault/tls/ssl_generate_self_signed.txt @@ -15,7 +15,7 @@ cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ - -hostname="vault-example,vault-example.vault-example.svc.cluster.local,localhost,127.0.0.1" \ + -hostname="vault-example,vault-example.vault-example.svc.cluster.local,vault-example.vault-example.svc,localhost,127.0.0.1" \ -profile=default \ vault-csr.json | cfssljson -bare vault-example From 2415cb33b2f3ae5c07730ce0d0959b193f22e233 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Mon, 2 Mar 2020 22:00:58 +0000 Subject: [PATCH 10/14] example basic secret injection --- hashicorp/readme.md | 158 +++++++++++------- hashicorp/vault/example-app/deployment.yaml | 27 --- .../basic-secret/deployment.yaml} | 18 +- hashicorp/vault/example-apps/readme.md | 41 +++++ hashicorp/vault/policies/app-policy.md | 15 -- hashicorp/vault/policies/example-secret.md | 11 -- .../vault/policies/vault-enable-auth-k8s.md | 20 --- 7 files changed, 151 insertions(+), 139 deletions(-) delete mode 100644 hashicorp/vault/example-app/deployment.yaml rename hashicorp/vault/{example-app/patch.yaml => example-apps/basic-secret/deployment.yaml} (67%) create mode 100644 hashicorp/vault/example-apps/readme.md delete mode 100644 hashicorp/vault/policies/app-policy.md delete mode 100644 hashicorp/vault/policies/example-secret.md delete mode 100644 hashicorp/vault/policies/vault-enable-auth-k8s.md diff --git a/hashicorp/readme.md b/hashicorp/readme.md index 49e3fe1..afee566 100644 --- a/hashicorp/readme.md +++ b/hashicorp/readme.md @@ -1,57 +1,101 @@ -# Hashicorp Vault Guide - -# Vault - -For this tutorial, I use Kuberentes 1.17 -It's critical because we'll need certain [admission controllers](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) enabled. - -To get 1.17 for Linux\Windows, just use `kind` since you can create a 1.17 with admissions all setup. - -``` -kind create cluster --name vault --image kindest/node:v1.17.0@sha256:9512edae126da271b66b990b6fff768fbb7cd786c7d39e86bdf55906352fdf62 -``` - -## TLS End to End Encryption - -See steps in `hashicorp/vault/tls/ssl_generate_self_signed.txt` -You'll need to generate TLS certs (or bring your own) -Create base64 strings from the files, place it in the `server-tls-secret.yaml` and apply it. -Remember not to check-in your TLS to GIT :) - -## Deployment - -``` -kubectl create ns vault-example -kubectl -n vault-example apply -f .\hashicorp\vault\server\ -``` - -## Storage - -``` -kubectl -n vault-example get pvc -``` -ensure vault-claim is bound, if not, `kubectl -n vault-example describe pvc vault-claim` -ensure correct storage class is used for your cluster. -if you need to change the storage class, deleve the pvc , edit YAML and re-apply - -## Initialising Vault - -``` -kubectl -n vault-example exec -it vault-example-0 vault operator init -kubectl -n vault-example exec -it vault-example-0 vault operator unseal -``` - -## Depploy the Injector - -Injector allows pods to automatically get secrets from the vault. - -``` -kubectl -n vault-example apply -f .\hashicorp\vault\injector\ -``` - - - - - - - +# Hashicorp Vault Guide + +# Vault + +For this tutorial, I use Kuberentes 1.17 +It's critical because we'll need certain [admission controllers](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) enabled. + +To get 1.17 for Linux\Windows, just use `kind` since you can create a 1.17 with admissions all setup. + +``` +kind create cluster --name vault --image kindest/node:v1.17.0@sha256:9512edae126da271b66b990b6fff768fbb7cd786c7d39e86bdf55906352fdf62 + +#Linux +kind create cluster --name vault --kubeconfig ~/.kube/kind-vault --image kindest/node:v1.17.0@sha256:9512edae126da271b66b990b6fff768fbb7cd786c7d39e86bdf55906352fdf62 +``` + +## TLS End to End Encryption + +VIDEO: +See steps in `hashicorp/vault/tls/ssl_generate_self_signed.txt` +You'll need to generate TLS certs (or bring your own) +Create base64 strings from the files, place it in the `server-tls-secret.yaml` and apply it. +Remember not to check-in your TLS to GIT :) + +## Deployment + +``` +kubectl create ns vault-example +kubectl -n vault-example apply -f ./hashicorp/vault/server/ +``` + +## Storage + +``` +kubectl -n vault-example get pvc +``` +ensure vault-claim is bound, if not, `kubectl -n vault-example describe pvc vault-claim` +ensure correct storage class is used for your cluster. +if you need to change the storage class, deleve the pvc , edit YAML and re-apply + +## Initialising Vault + +``` +kubectl -n vault-example exec -it vault-example-0 vault operator init +#unseal 3 times +kubectl -n vault-example exec -it vault-example-0 vault operator unseal +``` + +## Depploy the Injector + +VIDEO: + +Injector allows pods to automatically get secrets from the vault. + +``` +kubectl -n vault-example apply -f ./hashicorp/vault/injector\ +``` + +## Injector Kubernetes Auth Policy + +For the injector to be authorised to access vault, we need to enable K8s auth + +``` +kubectl -n vault-example exec -it vault-example-0 vault login +kubectl -n vault-example exec -it vault-example-0 vault auth enable kubernetes + + +kubectl -n vault-example exec -it vault-example-0 sh +vault write auth/kubernetes/config \ +token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ +kubernetes_host=https://${KUBERNETES_PORT_443_TCP_ADDR}:443 \ +kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt + +``` + +# Summary + +So we have a vault, an injector, TLS end to end, stateful storage. +The injector can now inject secrets for pods from the vault. + +Now we are ready to use the platform for different types of secrets: + +## Secret Injection Guides + +I've broken this down into basic guides to avoid this document from becoming too large. + +### Basic Secrets + +Objective: +---------- +* Let's create a basic secret in vault manually +* Application consumes the secret automatically + +[Try it](./vault/example-apps/basic-secret/readme.md) + + + + + + + diff --git a/hashicorp/vault/example-app/deployment.yaml b/hashicorp/vault/example-app/deployment.yaml deleted file mode 100644 index 01a480e..0000000 --- a/hashicorp/vault/example-app/deployment.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: vault-agent-demo -spec: - selector: - matchLabels: - app: vault-agent-demo - replicas: 1 - template: - metadata: - labels: - app: vault-agent-demo - spec: - serviceAccountName: app - containers: - - name: app - image: jweissig/app:0.0.1 ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: app - labels: - app: vault-agent-demo \ No newline at end of file diff --git a/hashicorp/vault/example-app/patch.yaml b/hashicorp/vault/example-apps/basic-secret/deployment.yaml similarity index 67% rename from hashicorp/vault/example-app/patch.yaml rename to hashicorp/vault/example-apps/basic-secret/deployment.yaml index b2679e1..b4affd0 100644 --- a/hashicorp/vault/example-app/patch.yaml +++ b/hashicorp/vault/example-apps/basic-secret/deployment.yaml @@ -1,32 +1,32 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: app + name: basic-secret labels: - app: vault-agent-demo + app: basic-secret spec: selector: matchLabels: - app: vault-agent-demo + app: basic-secret replicas: 1 template: metadata: annotations: vault.hashicorp.com/agent-inject: "true" vault.hashicorp.com/tls-skip-verify: "true" - vault.hashicorp.com/agent-inject-secret-helloworld: "secret/helloworld" + vault.hashicorp.com/agent-inject-secret-helloworld: "secret/basic-secret/helloworld" vault.hashicorp.com/agent-inject-template-helloworld: | - {{- with secret "secret/helloworld" -}} + {{- with secret "secret/basic-secret/helloworld" -}} { "username" : "{{ .Data.username }}", "password" : "{{ .Data.password }}" } {{- end }} - vault.hashicorp.com/role: "myapp" + vault.hashicorp.com/role: "basic-secret-role" labels: - app: vault-agent-demo + app: basic-secret spec: - serviceAccountName: app + serviceAccountName: basic-secret containers: - name: app image: jweissig/app:0.0.1 @@ -36,4 +36,4 @@ kind: ServiceAccount metadata: name: app labels: - app: vault-agent-demo \ No newline at end of file + app: basic-secret \ No newline at end of file diff --git a/hashicorp/vault/example-apps/readme.md b/hashicorp/vault/example-apps/readme.md new file mode 100644 index 0000000..91e7795 --- /dev/null +++ b/hashicorp/vault/example-apps/readme.md @@ -0,0 +1,41 @@ +# Basic Secret Injection + + +In order for us to start using secrets in vault, we need to setup a policy. + + +``` +#Create a role for our app + +kubectl -n vault-example exec -it vault-example-0 vault write auth/kubernetes/role/basic-secret-role \ + bound_service_account_names=basic-secret \ + bound_service_account_namespaces=vault-example \ + policies=basic-secret-policy \ + ttl=1h +``` + +The above maps our Kubernetes service account, used by our pod, to a policy. +Now lets create the policy to map our service account to a bunch of secrets + + +``` +kubectl -n vault-example exec -it vault-example-0 sh +cat < /home/vault/app-policy.hcl +path "secret/basic-secret/*" { + capabilities = ["read"] +} +EOF +vault policy write basic-secret-policy /home/vault/app-policy.hcl +exit +``` + +Now our service account for our pod can access all secrets under `secret/basic-secret/*` +Lets create some secrets. + + +``` +kubectl -n vault-example exec -it vault-example-0 sh +vault secrets enable -path=secret/ kv +vault kv put secret/basic-secret/helloworld username=dbuser password=sUp3rS3cUr3P@ssw0rd +exit +``` \ No newline at end of file diff --git a/hashicorp/vault/policies/app-policy.md b/hashicorp/vault/policies/app-policy.md deleted file mode 100644 index 920a593..0000000 --- a/hashicorp/vault/policies/app-policy.md +++ /dev/null @@ -1,15 +0,0 @@ -# Create an App policy - -``` -kubectl -n vault-example exec -it vault-example-0 sh - -cat < /home/vault/app-policy.hcl -path "secret*" { - capabilities = ["read"] -} -EOF - -vault login -vault policy write app /home/vault/app-policy.hcl - -``` \ No newline at end of file diff --git a/hashicorp/vault/policies/example-secret.md b/hashicorp/vault/policies/example-secret.md deleted file mode 100644 index cee711e..0000000 --- a/hashicorp/vault/policies/example-secret.md +++ /dev/null @@ -1,11 +0,0 @@ -# Create example secret - -``` -kubectl -n vault-example exec -it vault-example-0 sh - -vault login - -vault secrets enable -path=secret/ kv -vault kv put secret/helloworld username=foobaruser password=foobarbazpass - -``` \ No newline at end of file diff --git a/hashicorp/vault/policies/vault-enable-auth-k8s.md b/hashicorp/vault/policies/vault-enable-auth-k8s.md deleted file mode 100644 index 7afc45a..0000000 --- a/hashicorp/vault/policies/vault-enable-auth-k8s.md +++ /dev/null @@ -1,20 +0,0 @@ -# Enable Kubernetes Vault Auth - -``` -kubectl -n vault-example exec -it vault-example-0 sh - -vault login -vault auth enable kubernetes - -vault write auth/kubernetes/config \ - token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ - kubernetes_host=https://${KUBERNETES_PORT_443_TCP_ADDR}:443 \ - kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt - -vault write auth/kubernetes/role/myapp \ - bound_service_account_names=app \ - bound_service_account_namespaces=vault-example \ - policies=app \ - ttl=1h - -``` \ No newline at end of file From e711ed29fad5415197d7fe6bbd61f2283b37a03d Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Wed, 4 Mar 2020 08:52:23 +1100 Subject: [PATCH 11/14] dynamic secrets and docos --- .gitignore | 4 +- .../example-apps/basic-secret/deployment.yaml | 2 +- .../example-apps/{ => basic-secret}/readme.md | 6 ++ .../dynamic-postgresql/postgres.yaml | 41 ++++++++++ .../example-apps/dynamic-postgresql/readme.md | 68 ++++++++++++++++ hashicorp/vault/server/server-tls-secret.yaml | 6 +- .../vault/tls/ssl_generate_self_signed.txt | 78 +++++++++++-------- 7 files changed, 168 insertions(+), 37 deletions(-) rename hashicorp/vault/example-apps/{ => basic-secret}/readme.md (88%) create mode 100644 hashicorp/vault/example-apps/dynamic-postgresql/postgres.yaml create mode 100644 hashicorp/vault/example-apps/dynamic-postgresql/readme.md diff --git a/.gitignore b/.gitignore index 81d7197..3e438a8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ c#/src/bin/ c#/src/obj/ node_modules/ -__pycache__/ \ No newline at end of file +__pycache__/ +*.pem +*.csr diff --git a/hashicorp/vault/example-apps/basic-secret/deployment.yaml b/hashicorp/vault/example-apps/basic-secret/deployment.yaml index b4affd0..6afa3d8 100644 --- a/hashicorp/vault/example-apps/basic-secret/deployment.yaml +++ b/hashicorp/vault/example-apps/basic-secret/deployment.yaml @@ -34,6 +34,6 @@ spec: apiVersion: v1 kind: ServiceAccount metadata: - name: app + name: basic-secret labels: app: basic-secret \ No newline at end of file diff --git a/hashicorp/vault/example-apps/readme.md b/hashicorp/vault/example-apps/basic-secret/readme.md similarity index 88% rename from hashicorp/vault/example-apps/readme.md rename to hashicorp/vault/example-apps/basic-secret/readme.md index 91e7795..693ea9e 100644 --- a/hashicorp/vault/example-apps/readme.md +++ b/hashicorp/vault/example-apps/basic-secret/readme.md @@ -38,4 +38,10 @@ kubectl -n vault-example exec -it vault-example-0 sh vault secrets enable -path=secret/ kv vault kv put secret/basic-secret/helloworld username=dbuser password=sUp3rS3cUr3P@ssw0rd exit +``` + +Lets deploy our app and see if it works: + +``` +kubectl -n vault-example apply -f ./hashicorp/vault/example-apps/basic-secret/deployment.yaml ``` \ No newline at end of file diff --git a/hashicorp/vault/example-apps/dynamic-postgresql/postgres.yaml b/hashicorp/vault/example-apps/dynamic-postgresql/postgres.yaml new file mode 100644 index 0000000..467bb11 --- /dev/null +++ b/hashicorp/vault/example-apps/dynamic-postgresql/postgres.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: ConfigMap +metadata: +  name: postgres-config +  labels: +    app: postgres +data: +  POSTGRES_DB: postgresdb +  POSTGRES_USER: postgresadmin +  POSTGRES_PASSWORD: admin123 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgres +spec: + selector: + matchLabels: + app: postgres + replicas: 1 + template: + metadata: + labels: + app: postgres + spec: + containers: + - name: postgres + image: postgres:10.4 + imagePullPolicy: "IfNotPresent" + ports: + - containerPort: 5432 + envFrom: + - configMapRef: + name: postgres-config + # volumeMounts: + # - mountPath: /var/lib/postgresql/data + # name: postgredb + # volumes: + # - name: postgredb + # persistentVolumeClaim: + # claimName: postgres-pv-claim \ No newline at end of file diff --git a/hashicorp/vault/example-apps/dynamic-postgresql/readme.md b/hashicorp/vault/example-apps/dynamic-postgresql/readme.md new file mode 100644 index 0000000..ea75f31 --- /dev/null +++ b/hashicorp/vault/example-apps/dynamic-postgresql/readme.md @@ -0,0 +1,68 @@ +# Dynamic Secret Creation [PostgreSQL] + + +Enable the database engine + +``` +kubectl -n vault-example exec -it vault-example-0 vault login +kubectl -n vault-example exec -it vault-example-0 vault secrets enable database + +#map connection details to a role +kubectl -n vault-example exec -it vault-example-0 vault write database/config/my-postgresql-database \ + plugin_name=postgresql-database-plugin \ + allowed_roles="my-role" \ + connection_url="postgresql://{{username}}:{{password}}@localhost:5432/" \ + username="root" \ + password="root" + +#create the role +kubectl -n vault-example exec -it vault-example-0 vault write database/roles/my-role \ + db_name=my-postgresql-database \ + creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \ + GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \ + default_ttl="1h" \ + max_ttl="24h" + +``` + +``` +#Create a role for our app + +kubectl -n vault-example exec -it vault-example-0 vault write auth/kubernetes/role/basic-secret-role \ + bound_service_account_names=basic-secret \ + bound_service_account_namespaces=vault-example \ + policies=basic-secret-policy \ + ttl=1h +``` + +The above maps our Kubernetes service account, used by our pod, to a policy. +Now lets create the policy to map our service account to a bunch of secrets + + +``` +kubectl -n vault-example exec -it vault-example-0 sh +cat < /home/vault/app-policy.hcl +path "secret/basic-secret/*" { + capabilities = ["read"] +} +EOF +vault policy write basic-secret-policy /home/vault/app-policy.hcl +exit +``` + +Now our service account for our pod can access all secrets under `secret/basic-secret/*` +Lets create some secrets. + + +``` +kubectl -n vault-example exec -it vault-example-0 sh +vault secrets enable -path=secret/ kv +vault kv put secret/basic-secret/helloworld username=dbuser password=sUp3rS3cUr3P@ssw0rd +exit +``` + +Lets deploy our app and see if it works: + +``` +kubectl -n vault-example apply -f ./hashicorp/vault/example-apps/basic-secret/deployment.yaml +``` \ No newline at end of file diff --git a/hashicorp/vault/server/server-tls-secret.yaml b/hashicorp/vault/server/server-tls-secret.yaml index bfb4100..6e7997a 100644 --- a/hashicorp/vault/server/server-tls-secret.yaml +++ b/hashicorp/vault/server/server-tls-secret.yaml @@ -4,6 +4,6 @@ metadata: name: vault-example-tls-secret type: Opaque data: - vault-example.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVUVENDQXpXZ0F3SUJBZ0lVRU1JUSs4cFc3MDJjdzJUdFlYN2VmM2ZsUnYwd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdNekF4Ck1ETXlOakF3V2hjTk1qRXdNekF4TURNeU5qQXdXakJ4TVFzd0NRWURWUVFHRXdKQlZURVJNQThHQTFVRUNCTUkKVm1samRHOXlhV0V4RWpBUUJnTlZCQWNUQ1UxbGJHSnZkWEp1WlRFVE1CRUdBMVVFQ2hNS1MzVmlaWEp1WlhSbApjekVPTUF3R0ExVUVDeE1GVm1GMWJIUXhGakFVQmdOVkJBTVREWFpoZFd4MExXVjRZVzF3YkdVd2dnRWlNQTBHCkNTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFEQ0VNaERwQ3RjZG9uVS9GT1BGdjIxb0xiejVMSU4KS1ppanNZM1EvWHVWZG8vY1pFSW9uazd5SFZJdTA1NU9xWTJDQnJiM2dwVHpDWVoxZFozb3lsRVdtV1hFakR5UQoyZEFPTFM2SEdoTUZLZ3FvYWlKV3pPb1JPeVhYakVXanBzTGQxWVdnVFRlY0FxMDN0R3lBVjY1WVg5dUpFY3hxCnpSMEFBVDdPZWh4aFNzSUMzeFFyczRNbURSbjdnSVNwTHErcU5RZmc3VEtMOEtleUNBNWFkMVZOWnJ3cktZZ1AKZlNwRUt6ZGhVSGZMaFlEa3M4L0NZUTFLZEJjMnc3THVSMnJDTm9ISmF5ajcwUnVpeUNubGErWU5MeHd4REhGNgpxbEFEUXh6SmZFNWtRRmljVS9HblpLV2dyNVoyNWhpYUdkZjQ2SDk1RE9lMzVzUi8rL21IcFlKbEFnTUJBQUdqCmdmc3dnZmd3RGdZRFZSMFBBUUgvQkFRREFnV2dNQjBHQTFVZEpRUVdNQlFHQ0NzR0FRVUZCd01CQmdnckJnRUYKQlFjREFqQU1CZ05WSFJNQkFmOEVBakFBTUIwR0ExVWREZ1FXQkJROGk3VnFrWXRxclVYckp5c3dKL3NSc2dTYwpMREFmQmdOVkhTTUVHREFXZ0JRMVhlQVFUcG9xS25CbjNPQk5VQ1NVc0tYNk56QjVCZ05WSFJFRWNqQndnZzEyCllYVnNkQzFsZUdGdGNHeGxnaTEyWVhWc2RDMWxlR0Z0Y0d4bExuWmhkV3gwTFdWNFlXMXdiR1V1YzNaakxtTnMKZFhOMFpYSXViRzlqWVd5Q0gzWmhkV3gwTFdWNFlXMXdiR1V1ZG1GMWJIUXRaWGhoYlhCc1pTNXpkbU9DQ1d4dgpZMkZzYUc5emRJY0Vmd0FBQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQUNLUlJHYmw5OUxuYnFBbHlRRzd5CjNFcE1COXdmRUdtOG1hMzZwc05nODhPY1Q1K2hpWnRJR3hQT0w1dEJVRURWYWFjREtpaUg0WG1hdGN2THhHVmgKSW5NYXNIbHB2RlBoUTRONDdqdjBRMk1tL2x4ZzBuOGZTNjYwMU5LNkEycmxBNXl6blZBNGlxeVV5dzZ1K2NmVwpOL3gwWUtINTRLTlA5WEZhQy9aQStoWWNFSG5ZRGZHa01vYXZHVnE1ZnB5T2Zqd2dLT1llVDhTZkJ0VG9zRUNqCkFjR3FmVHp1VGlpSkozaFlNMVViMGVUdzVSU21Gc0tGNm5icG5RYnYzQm1iNjR1WStVbzZaYUM2RXh0SmsxcWYKcjVpbmxjTDA0Sk1UYVhVQ3lMSW5mdjZMZXVXTllldmpmN1dyblJiZ2xuUGJYVDEvazREVDJlWkRiaWFTVHNHcApGUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - vault-example-key.pem: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBd2hESVE2UXJYSGFKMVB4VGp4Yjl0YUMyOCtTeURTbVlvN0dOMFAxN2xYYVAzR1JDCktKNU84aDFTTHRPZVRxbU5nZ2EyOTRLVTh3bUdkWFdkNk1wUkZwbGx4SXc4a05uUURpMHVoeG9UQlNvS3FHb2kKVnN6cUVUc2wxNHhGbzZiQzNkV0ZvRTAzbkFLdE43UnNnRmV1V0YvYmlSSE1hczBkQUFFK3pub2NZVXJDQXQ4VQpLN09ESmcwWis0Q0VxUzZ2cWpVSDRPMHlpL0Nuc2dnT1duZFZUV2E4S3ltSUQzMHFSQ3MzWVZCM3k0V0E1TFBQCndtRU5TblFYTnNPeTdrZHF3amFCeVdzbys5RWJvc2dwNVd2bURTOGNNUXh4ZXFwUUEwTWN5WHhPWkVCWW5GUHgKcDJTbG9LK1dkdVlZbWhuWCtPaC9lUXpudCtiRWYvdjVoNldDWlFJREFRQUJBb0lCQUh1UGNlTFhZU0JTL1BrVgoyeUhzOG9hMUdDZDdnZjR0Y05rd2tHbnpLcitFS0o2Yld5QS9nMlpXVXVBcnJzekkyYWRqSFJYRUY1QVNqWUMxCjdWK3RpU21KYTZsVDNMQWhibjNJT0txZWFHUE9XOURWR3A0SGhEU0tZMUsxSmhYSGRLVUhjVGdhVWdETUYzdXoKTGE0ZHBZenhJM2RIVk03Zlg4cUVBSGc0ZVY5YnZQdTN4M0NQNm9yV1l0bzZzbUhEcjN2ZkZPM0RMQnIwVHRzRwpVVS9mbjcrU1U3Y2FmQTRJemc0TTlKdXl2aHZzZm91SENCajVXczJvWWxOY2FoV2pxY0tGZnA0WUoya0hkK2dlClR4VlVIejBKTDIrY0pQdThLQ0IxdllKanlwRnhvRlRUZC81cXptK3ZsK2pRNUprY2Nxd3luaXJXYVVKRm5XU3kKank3dnlyVUNnWUVBMmkxRzhHM050YkJHZHFNeVJjQmdGUHZrNXVqTUlGT1hJNHNIVkZ1TEluYzF1MGZZNkR3dQpObEJzNmFCU0ZYOSsybk1seVFDMzlzelVyWlRQakRmRkZvcGczR2FpQ0hvY09yYUVFUWhPSDBWaVpUNGJjMWE0ClNuV3F6aWRhdmkzN3FMZjB2aXladCtsYmg2NllPUWxBSHFPSW4wUlhoUzk1TjBsTzlXYkhCUjhDZ1lFQTQ3VngKRFVSS2xWL1V3REJBa3F6cVpxSWdESklwdGRGL2Yvam9uUXlVYnBLM2llYWUyN3pmaHNLZEFTRGZBcHA5aTd5KwpST1NWdnNWUGRidU9vWGJKQWxzcVJlSVBYdmVYODdGWlluNVZhWkdVdjBteHlwQXZ0NTcrdFdWT1E1aGZydGNYCk1DMyttWFFUTkxhZUxGMThySW11UktENlBxNW1JVk5kS3hibjQvc0NnWUVBeFpFT2xoVzRtL2grTmx4ZDM4L3UKc2RIUVhGRWUxMzhhYy9NbnRmb1hxaVF0SWVSVHhTa0o1K0U0WHU3d3Bjc0lRaVRYYUljZ0QzczRjOTgzZW8vZQpCeVZUeFFHalpPMit0bVFrZjQvM3ZsV0VYbzI1S2Q2emo2bXgvSENpdVdqR1pPZi8xbDVvN0tPQ1lRRjNrdDZQCms2OGV2cXFTWG1hNDY1bVV5S0JEUkowQ2dZRUF3Y2llcmppbzlGZzZ1VmdYQy93bCt6UUw3RWJUUWsxSW9VTFYKeXhseWxHczkwUmkzcHE4azF3MTJDZ2pNWU8zUzNBSEROdVFGWC9XUXV0UGovUnNXMDI5OEdUN1o3K3Jyb05NVQpDNU1SNHlhbW5PZjlhektydVN1US9oUjV0MkxNUXdIL1ZOdy9xSjQwM2c1dnE3ZmZxd0g4a2FFaGRnaDdGKzlYCkFaMmJ1Tk1DZ1lBZWJEaTMrQ3VmQzFOOGlwWUdVS1hSOFRSaFJPdDlmTzdGYjJRM25NdE1UZUx2YzJxNXlaY3oKdThIVUZCbk56Mmx6WDV3N2VwOUtSNzhvRFhRaVZGTnBYY1JwYm9ONS9YZHNFbUlXemNlN0V4ZFI4TGE4TS9YcQpKazkwdis0T2ovd013enlBZm9ZT0NHZ3Y0ZWdCNmZ0MXRwMVBjUG1QcTZCcnF3am1wNERYYmc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= - ca.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURtRENDQW9DZ0F3SUJBZ0lVZnFKeTY5QXlnY1l5MGgvbC9XdTRkeVU4MlRFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdNekF4Ck1ETXlOVEF3V2hjTk1qVXdNakk0TURNeU5UQXdXakJTTVFzd0NRWURWUVFHRXdKQlZURVFNQTRHQTFVRUNCTUgKUlhoaGJYQnNaVEVTTUJBR0ExVUVCeE1KVFdWc1ltOTFjbTVsTVJBd0RnWURWUVFLRXdkRmVHRnRjR3hsTVFzdwpDUVlEVlFRTEV3SkRRVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFNelVkWGlOCjRiN3dDK3JrRlFkTFlsclpleWttNkQrYk16T3B2N0JnZUkrdnIrVy9GZE9HR1ZkMnQwbWpDMVhvcWgrSCtERU0Kc3Z0bFpLOW9DT080RnlleUZuSXhqcktDNXp0REJJSlNJYzhYR2NjUTVFY1VXdDRiMnVOVXVKM1dMVFlYcFpFeApqVnd3YzY4aHJ6cC82TDVuMUJxVERxaWxCYk5JUi91OUdmeU40bWpXQlRUbzArTFhkakpkZ3BvOWxmWC83aEFhCnRxT0FIcFJqRWhJM0RreEZyREdSVlJsQ1ZBZlo2MWt5bFRWLzJNMW5CalJWU2RTbDlJK0lWeU4xbXpMM3AzTGwKQ3lwYWxpbGtTWS9LaTNsSFRpNnZGeEJ6c042c3N5SktmeDdpMVJmNDk2MjlKQWZNNXFad0x4enp5OFFNeEw0ZQpMN1VyYmdNMWgwRUhCa0VDQXdFQUFhTm1NR1F3RGdZRFZSMFBBUUgvQkFRREFnRUdNQklHQTFVZEV3RUIvd1FJCk1BWUJBZjhDQVFJd0hRWURWUjBPQkJZRUZEVmQ0QkJPbWlvcWNHZmM0RTFRSkpTd3BmbzNNQjhHQTFVZEl3UVkKTUJhQUZEVmQ0QkJPbWlvcWNHZmM0RTFRSkpTd3BmbzNNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUFnMkZBWApnTUF4UXlndzVrcGkrSFpNWDg5K0QxQ1ptVHhGUXBhUk5vSzdOR1NTVGZLS1Z0Vjdaa1IxVVhJWVJhZTF0R2o2Cm1YeHRpOS9xd281ZlpBckNEaloyVVVNV29EVHFTNHY3ZGVaVmxiRmlVWnl2VXRPb0hjTEhhWitLdmlkVG0yL3UKMDJ0TjhscGtEMDFzeXU5akIyK2wrT01CMUtlRGpXNS8wcDk0ay8xMUd5U2dJRDF1RVVyaFUrai9CMFp1L09GegpXNE00akcrRWlsK1puMHpzcm1wVStmQk1RK20wQzFXZ05mU3NKU0FCYlZxSEVMQ05USUYzVG91V3lNdEE1YUZxCnJ1SFQwNUxxUzl6QVVKNTZ0Q2dqbGdHMDUrUG9FQjFSZUtvV1JURnBNQ0JSL0RxWjk4SnprRDNLYTJyVkMwOXgKUCs1TTNobzl0Q3J4SW42bQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== \ No newline at end of file + vault-example.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVUVENDQXpXZ0F3SUJBZ0lVUkJaRmlSVXZnMTRJMFF6NkU0N3RJKzQ0R21Nd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdNekF5Ck1qSTBOakF3V2hjTk1qRXdNekF5TWpJME5qQXdXakJ4TVFzd0NRWURWUVFHRXdKQlZURVJNQThHQTFVRUNCTUkKVm1samRHOXlhV0V4RWpBUUJnTlZCQWNUQ1UxbGJHSnZkWEp1WlRFVE1CRUdBMVVFQ2hNS1MzVmlaWEp1WlhSbApjekVPTUF3R0ExVUVDeE1GVm1GMWJIUXhGakFVQmdOVkJBTVREWFpoZFd4MExXVjRZVzF3YkdVd2dnRWlNQTBHCkNTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDa2JHVHNzSEQ1N3FKVXVIRElsZGpsZHM5QytOWEoKZXpFekNkbEQwdFlsZkVtQU56eURFdnZqbTJielI1MnlCd1VxRGZkeElMdE0xYlQzVFZjYWdSWkVNWkJOVnBtWgpxMUh6aXV1ZkhJMnNVN1pBcmxFbnNyV25oZEdrb0lPd0FyUGl6NXZFVDVJYXh1bXQzUlc3b2hEaE9QdnF0M3ZsCmtBTW9LZXJvMm9QdWp0K0hoQ3ppVDNkMGdjNUlGZWZVbkNiTDBQUmpselBXeFdzQ1ByWDJpYmJaZzkzb2IvNFgKOHlTRVVmZlk4eC9aaytWZDRqZXc3TnhzYllZdGFhUkwzU0M2My9FNERpMkgxSWVtQkRFOGNBNGZiVGpEZGVqKwp5WGcwR1BvYTlWUkVsUlJjMEU1RUQ0eG9IRFFoTFFCeFJqWHJoT1Z1Mmp2cXlvR25OSHQ4MDViQkFnTUJBQUdqCmdmc3dnZmd3RGdZRFZSMFBBUUgvQkFRREFnV2dNQjBHQTFVZEpRUVdNQlFHQ0NzR0FRVUZCd01CQmdnckJnRUYKQlFjREFqQU1CZ05WSFJNQkFmOEVBakFBTUIwR0ExVWREZ1FXQkJSeGg5U3JXTzhESlBkMjFqR091OW04d0Q1RQpSVEFmQmdOVkhTTUVHREFXZ0JUdDhnaDErS3pRZTc2N3I0cldaazhUU0FEc0REQjVCZ05WSFJFRWNqQndnZzEyCllYVnNkQzFsZUdGdGNHeGxnaTEyWVhWc2RDMWxlR0Z0Y0d4bExuWmhkV3gwTFdWNFlXMXdiR1V1YzNaakxtTnMKZFhOMFpYSXViRzlqWVd5Q0gzWmhkV3gwTFdWNFlXMXdiR1V1ZG1GMWJIUXRaWGhoYlhCc1pTNXpkbU9DQ1d4dgpZMkZzYUc5emRJY0Vmd0FBQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWJ1V3VIbkJORnVKbCttSDlwVndhCnhDcGd4NHNPVDdZeFhJS2RXZ1QrREpPanlKYjFFMkt2ZTJLdVoxZ0tiazZua3pMRzlGZXlDbUFzNmdPTW95cmkKZm1uQ0QzR2FDaFV1OTNlVEtudlgxNVl5UDdoYldNaHVqT3c3Tmo2U0VpQkxTL08yanhHRkwzb0p6cWFRQTFtSwp3bjNsWGY0QVkyUTFFSWxuQ0JvU3lRTFRZS0lISUlNbk5GaWJjRG5jY0lUbG1IdktKd2hVTFk2REJ0WGR0QXFYCmgvam1OSVF4THZNSzFwL0JnRzZrai9XNlBkdXNoZjdLaWgvWU9La3N2WlJWZlhnRjdNeUZQR2NESXNLVk05bHUKRUdRQnBYcDJFa0NjNElXMmM5MGlPaU9wRlZqb0ZvSDFOVHE0TGM5RFk0WDNNa0FSck5RVitoa016M2M5bitWbwpDdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + vault-example-key.pem: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBcEd4azdMQncrZTZpVkxod3lKWFk1WGJQUXZqVnlYc3hNd25aUTlMV0pYeEpnRGM4Cmd4TDc0NXRtODBlZHNnY0ZLZzMzY1NDN1ROVzA5MDFYR29FV1JER1FUVmFabWF0Ujg0cnJueHlOckZPMlFLNVIKSjdLMXA0WFJwS0NEc0FLejRzK2J4RStTR3NicHJkMFZ1NklRNFRqNzZyZDc1WkFES0NucTZOcUQ3bzdmaDRRcwo0azkzZElIT1NCWG4xSndteTlEMFk1Y3oxc1ZyQWo2MTlvbTIyWVBkNkcvK0YvTWtoRkgzMlBNZjJaUGxYZUkzCnNPemNiRzJHTFdta1M5MGd1dC94T0E0dGg5U0hwZ1F4UEhBT0gyMDR3M1hvL3NsNE5CajZHdlZVUkpVVVhOQk8KUkErTWFCdzBJUzBBY1VZMTY0VGxidG83NnNxQnB6UjdmTk9Xd1FJREFRQUJBb0lCQUJtY1NKd1ZYNE9PaC9wcQpRQ2IrTUNxTnR2clhoM1U2bXc4NEdYOVc5OFFlOTlQZ3hxd2o2TmdxL0g0b1NZZlJVQnljMEUzdXF6M3NpNk41CmlIZTRZNTk3bU41eS9yblExWkw1c0htNEdOa2VzT1NpUWtITXREN0R1VVBMUExmTnMvZEFIeU1Vd2MwcDdud0cKVTd4R0locnlwVXFLQ2VKWDdDWDFZWUdqaDZsQWwrYWR0YmFCaG1MSkRaek53WmZTcnlneVVPSnVjQXpOZCtxRwpxUXBmU1Y0c0Z6WGdQL3F3REtHcGg0anFYRnBFWkNCQzgyNE9rdUVQL0k2TVBrK3M5N2xjQXlmaWVGamRwT2E3CnVHUm1sV3BUNG9QZXNFTmF0YkNid1dsR25jamJtL1VxSldVRndJdjRFYlhlQ1JOVlRBM1VOSjlWMlRQVHFIRVUKb2FScFo0RUNnWUVBemhvWUR6R0c0S2xDdjAvclE4MDN5dHJwVzNqWEpOWlBNa1ZpcFNEUVV3MFp5SWpDeVdQWAo1WEhtaG1uc0I5YkpYbFpjK1pRTTBtalBYUGFOZXgzek1NSkp0L1VIM0Roc0FZL3dUOW0zQk1VbjhNeU4rWCt3CjFvUUhOMmZTSFhQNUx6bSs5YWQwUGpIRkVLOGlFQ2J1a1FmQkUwOGc0QjkyU3liN3F6VVM3RGNDZ1lFQXpEc2YKK0VTcUsvUEpleWs4Vmd1eTFISVNUY054d0htejVYcEpoTVYzRnRKTDJyM0l2dHloNGxiaExsenNlcHB5U3JsLwo3d3BlQW1aQklUblpia3dnVW9WVlR0VHdwT05TSEF1aEpNc1RFbzhBdnZGQ0hUQXMzbVQvcDBuT3hoTmgvbVdGCjJLSHgxakcxNUlBWHppWkZNNmhmY2lLcjV6QWZWMGpzR3hhRnlNY0NnWUJoWmUxMnlLWC81NTFXZ2JNaHdJcWMKUCtYRng0Nk1wd2FZTURnVTV6UHIrNlh5b2NiRG0zNTh2TjMvS1hGVXB3bFVucVdqZ0hhcXZNTTZJSDN0NzlKcwplWFNURGFYZ1NYMnBJMWVpdExXTCtJd09mT3lmT3R2Y0ZGckFzVHlYbEtYdXpuQlM4UWE3R1pRU2RXRTRsdDFwCkJtd1U3dkVQV1c3eXh3SnAvMVBvOHdLQmdGTVMwY1JKR2ZkYTZOL2lQQnE4RTNmN0ZwcnZIend0eFJGWkZzS2QKRi8zK2VNQjNaa3JNc0VUREZrR25wc0dRUldGRDUxZ3luVjdZZlRHb3VGcjNPRWFZMmNTQk5ZbTh0YytXbzJ1MQo5d0lialRBZUxzaDBxaXVrWmFHRWtrbGI1UVo0QVdQSEsvbjJxb2hSMmwwT2tDT2RINFhydUlVSHZCZmpIN2M5CkNCcE5Bb0dBYzdBUHh2UGRMemJlQkhmYTEvcFhkYm1VQ3hFd25YMEwwYWdSOUxpQk8wWmJmUHhwWFpKV2wrVDMKOXFMQWFwMFFQMFhpQU9RS3g2M1ZWcks1dDZRdzJUTlhSOWcrRnZDS1lwVkt0aHVvbU9yeUpTQ2pOTFFlVTBpTApKa1hVd3lPK0lhampVNVdCSk1lWSt1cTlFaW9jaUdNRU1ONDBWQUZhdzhTUnhaVlA4SDA9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== + ca.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURtRENDQW9DZ0F3SUJBZ0lVY0c2TVdaVDJka3Rla24vRk5XZUxQdG16SWp3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdNekF5Ck1qSTBOakF3V2hjTk1qVXdNekF4TWpJME5qQXdXakJTTVFzd0NRWURWUVFHRXdKQlZURVFNQTRHQTFVRUNCTUgKUlhoaGJYQnNaVEVTTUJBR0ExVUVCeE1KVFdWc1ltOTFjbTVsTVJBd0RnWURWUVFLRXdkRmVHRnRjR3hsTVFzdwpDUVlEVlFRTEV3SkRRVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFLMm94UkFhCmF6MUs5VGVQdmxiL24rQUxOUCtET2h2eHorSHdxUXo0b0llSEV5NkEwUGZVcnVSRCtMcktrbTA4VVJyeXBKcjYKZXI3QWJKVmFqcXNNYXUxazQ3NTJkdFhzek9pcnlPUlpZeVFSTWF1M2MrK1VycnZHWi9nd2dSWGNleEhZRHlIYgptUDFTQjdiUXAzK2cvQ053OUVmL0N0dXFkMi8ydVc1clY4VFZYZldzMVNILyszT1VVY1ZzZ1E1RWYvbnVpOWN0CjhCT3JRUW5kQndjYWxYenlSV1A3MEswTXhleDU2M3UwU1pBTndYbWRLN21RcXVNREV6VEtwU0ZveC9RRTdIMDQKd3V3SHp1MFRiLzIwYlk2eWlzMVVRajJMSU02SDNHMU55TThNK2V2ZUJzaGxGckVQMzRRSWtzZldpVFl5RUdudwppT3N0MzBvekM1TkhkdDBDQXdFQUFhTm1NR1F3RGdZRFZSMFBBUUgvQkFRREFnRUdNQklHQTFVZEV3RUIvd1FJCk1BWUJBZjhDQVFJd0hRWURWUjBPQkJZRUZPM3lDSFg0ck5CN3ZydXZpdFptVHhOSUFPd01NQjhHQTFVZEl3UVkKTUJhQUZPM3lDSFg0ck5CN3ZydXZpdFptVHhOSUFPd01NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUFjalE2YgpNRWZkWUQzd3FUUVhXY1ovYjFHTEFXWHNsTFU5VDYyNVJUUDV1MjFyc1FnaGJHWi9XcUgwT0JLa2FzVjc3c1JTCm9rRUJuVzd1UmpJbFBlS1pXS0tibHZ2ZGhyU2RDRmpraUVVYTBLdHkwNWtQTWt6bnhTdENQMzg3S2dQWWhYa0wKZGVlVkpwWFFURzZkNGx5blBUNDZmbmFvSjRoU052Y1RZdHUweXFBT3NqdEhuM2NMeW1GbS96L1U4cEZONWtTVApocUdSanhWbldQN09scW5hQ0txSjJuZDFwUUlMcWp5bFNScURrYzI0WXhHcVRPM3cyRndPS2VPbmhPelRpWk0yCk83WFVGMmE0cnNHQUdEejNQMEVENlJJZFpaWWRwQWwyN2VrZTJsSXFHTHBBcGJGMHJjUVg0aEdIUkZqaUt3WTgKU2F6YWM2cm8zRThIN3h3SwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== diff --git a/hashicorp/vault/tls/ssl_generate_self_signed.txt b/hashicorp/vault/tls/ssl_generate_self_signed.txt index 75f9571..ae8d476 100644 --- a/hashicorp/vault/tls/ssl_generate_self_signed.txt +++ b/hashicorp/vault/tls/ssl_generate_self_signed.txt @@ -1,32 +1,46 @@ - - -cd ./hashicorp/vault/tls/ - -docker run -it --rm -v ${PWD}:/work -w /work debian:buster bash -apt-get update && apt-get install -y curl && -curl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl && \ -curl https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson && \ -chmod +x /usr/local/bin/cfssl && \ -chmod +x /usr/local/bin/cfssljson - -#generate certificate -cfssl gencert -initca ca-csr.json | cfssljson -bare ca -cfssl gencert \ - -ca=ca.pem \ - -ca-key=ca-key.pem \ - -config=ca-config.json \ - -hostname="vault-example,vault-example.vault-example.svc.cluster.local,vault-example.vault-example.svc,localhost,127.0.0.1" \ - -profile=default \ - vault-csr.json | cfssljson -bare vault-example - -#get values to make a secret -cat ca.pem | base64 | tr -d '\n' -cat vault-example.pem | base64 | tr -d '\n' -cat vault-example-key.pem | base64 | tr -d '\n' - -#TEST -vault operator init #grab keys -vault operator unseal #unseal 3 times - -vault login -vault kv put cubbyhole/hello foo=world \ No newline at end of file + + +cd ./hashicorp/vault/tls/ + +docker run -it --rm -v ${PWD}:/work -w /work debian:buster bash +apt-get update && apt-get install -y curl && +curl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl && \ +curl https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson && \ +chmod +x /usr/local/bin/cfssl && \ +chmod +x /usr/local/bin/cfssljson + +#generate certificate +cfssl gencert -initca ca-csr.json | cfssljson -bare ca +cfssl gencert \ + -ca=ca.pem \ + -ca-key=ca-key.pem \ + -config=ca-config.json \ + -hostname="vault-example,vault-example.vault-example.svc.cluster.local,vault-example.vault-example.svc,localhost,127.0.0.1" \ + -profile=default \ + vault-csr.json | cfssljson -bare vault-example + +#get values to make a secret +cat ca.pem | base64 | tr -d '\n' +cat vault-example.pem | base64 | tr -d '\n' +cat vault-example-key.pem | base64 | tr -d '\n' + +#linux - make the secret automatically +cat < ./server-tls-secret.yaml +apiVersion: v1 +kind: Secret +metadata: + name: vault-example-tls-secret +type: Opaque +data: + vault-example.pem: $(cat vault-example.pem | base64 | tr -d '\n') + vault-example-key.pem: $(cat vault-example-key.pem | base64 | tr -d '\n') + ca.pem: $(cat ca.pem | base64 | tr -d '\n') +EOF + + +#TEST +vault operator init #grab keys +vault operator unseal #unseal 3 times + +vault login +vault kv put cubbyhole/hello foo=world From c12a0f14435afa84091f880b21fbe5459807b750 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Wed, 4 Mar 2020 15:38:24 +1100 Subject: [PATCH 12/14] dynamic secret injection --- .../vault/example-apps/basic-secret/readme.md | 5 +- .../dynamic-postgresql/deployment.yaml | 38 ++++++++ .../dynamic-postgresql/postgres.yaml | 34 ++++--- .../example-apps/dynamic-postgresql/readme.md | 89 +++++++++++-------- hashicorp/{ => vault}/readme.md | 11 ++- 5 files changed, 122 insertions(+), 55 deletions(-) create mode 100644 hashicorp/vault/example-apps/dynamic-postgresql/deployment.yaml rename hashicorp/{ => vault}/readme.md (91%) diff --git a/hashicorp/vault/example-apps/basic-secret/readme.md b/hashicorp/vault/example-apps/basic-secret/readme.md index 693ea9e..09bae17 100644 --- a/hashicorp/vault/example-apps/basic-secret/readme.md +++ b/hashicorp/vault/example-apps/basic-secret/readme.md @@ -7,7 +7,9 @@ In order for us to start using secrets in vault, we need to setup a policy. ``` #Create a role for our app -kubectl -n vault-example exec -it vault-example-0 vault write auth/kubernetes/role/basic-secret-role \ +kubectl -n vault-example exec -it vault-example-0 sh + +vault write auth/kubernetes/role/basic-secret-role \ bound_service_account_names=basic-secret \ bound_service_account_namespaces=vault-example \ policies=basic-secret-policy \ @@ -44,4 +46,5 @@ Lets deploy our app and see if it works: ``` kubectl -n vault-example apply -f ./hashicorp/vault/example-apps/basic-secret/deployment.yaml +kubectl -n vault-example get pods ``` \ No newline at end of file diff --git a/hashicorp/vault/example-apps/dynamic-postgresql/deployment.yaml b/hashicorp/vault/example-apps/dynamic-postgresql/deployment.yaml new file mode 100644 index 0000000..d57d3d4 --- /dev/null +++ b/hashicorp/vault/example-apps/dynamic-postgresql/deployment.yaml @@ -0,0 +1,38 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dynamic-postgres + labels: + app: dynamic-postgres +spec: + selector: + matchLabels: + app: dynamic-postgres + replicas: 1 + template: + metadata: + annotations: + vault.hashicorp.com/agent-inject: "true" + vault.hashicorp.com/tls-skip-verify: "true" + vault.hashicorp.com/agent-inject-secret-sql-role: "database/creds/sql-role" + vault.hashicorp.com/agent-inject-template-sql-role: | + { + {{- with secret "database/creds/sql-role" -}} + "db_connection": "host=postgres.postgress port=5432 user={{ .Data.username }} password={{ .Data.password }} dbname=postgresdb sslmode=disable" + {{- end }} + } + vault.hashicorp.com/role: "sql-role" + labels: + app: dynamic-postgres + spec: + serviceAccountName: dynamic-postgres + containers: + - name: app + image: jweissig/app:0.0.1 +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: dynamic-postgres + labels: + app: dynamic-postgres \ No newline at end of file diff --git a/hashicorp/vault/example-apps/dynamic-postgresql/postgres.yaml b/hashicorp/vault/example-apps/dynamic-postgresql/postgres.yaml index 467bb11..4010743 100644 --- a/hashicorp/vault/example-apps/dynamic-postgresql/postgres.yaml +++ b/hashicorp/vault/example-apps/dynamic-postgresql/postgres.yaml @@ -1,13 +1,13 @@ apiVersion: v1 kind: ConfigMap metadata: -  name: postgres-config -  labels: -    app: postgres + name: postgres-config + labels: + app: postgres data: -  POSTGRES_DB: postgresdb -  POSTGRES_USER: postgresadmin -  POSTGRES_PASSWORD: admin123 + POSTGRES_DB: postgresdb + POSTGRES_USER: postgresadmin + POSTGRES_PASSWORD: admin123 --- apiVersion: apps/v1 kind: Deployment @@ -32,10 +32,18 @@ spec: envFrom: - configMapRef: name: postgres-config - # volumeMounts: - # - mountPath: /var/lib/postgresql/data - # name: postgredb - # volumes: - # - name: postgredb - # persistentVolumeClaim: - # claimName: postgres-pv-claim \ No newline at end of file +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres + labels: + app: postgres +spec: + selector: + app: postgres + ports: + - protocol: TCP + name: http + port: 5432 + targetPort: 5432 \ No newline at end of file diff --git a/hashicorp/vault/example-apps/dynamic-postgresql/readme.md b/hashicorp/vault/example-apps/dynamic-postgresql/readme.md index ea75f31..425f3c5 100644 --- a/hashicorp/vault/example-apps/dynamic-postgresql/readme.md +++ b/hashicorp/vault/example-apps/dynamic-postgresql/readme.md @@ -1,68 +1,79 @@ # Dynamic Secret Creation [PostgreSQL] +Deploy our test database + +``` +kubectl create ns postgres +kubectl -n postgres apply -f ./hashicorp/vault/example-apps/dynamic-postgresql/postgres.yaml +kubectl -n postgres get pods + +kubectl -n postgres exec -it bash +psql --username=postgresadmin postgresdb +``` + +``` Enable the database engine ``` kubectl -n vault-example exec -it vault-example-0 vault login kubectl -n vault-example exec -it vault-example-0 vault secrets enable database +``` -#map connection details to a role -kubectl -n vault-example exec -it vault-example-0 vault write database/config/my-postgresql-database \ +## Configure DB Credential creation + +``` +kubectl -n vault-example exec -it vault-example-0 sh + +vault write database/config/postgresdb \ plugin_name=postgresql-database-plugin \ - allowed_roles="my-role" \ - connection_url="postgresql://{{username}}:{{password}}@localhost:5432/" \ - username="root" \ - password="root" + allowed_roles="sql-role" \ + connection_url="postgresql://{{username}}:{{password}}@postgres.postgres:5432/postgresdb?sslmode=disable" \ + username="postgresadmin" \ + password="admin123" -#create the role -kubectl -n vault-example exec -it vault-example-0 vault write database/roles/my-role \ - db_name=my-postgresql-database \ + vault write database/roles/sql-role \ + db_name=postgresdb \ creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \ GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \ default_ttl="1h" \ max_ttl="24h" -``` +#test +vault read database/creds/sql-role ``` -#Create a role for our app -kubectl -n vault-example exec -it vault-example-0 vault write auth/kubernetes/role/basic-secret-role \ - bound_service_account_names=basic-secret \ - bound_service_account_namespaces=vault-example \ - policies=basic-secret-policy \ - ttl=1h +## Example Application + +Create a policy to control access to secrets + +``` +kubectl -n vault-example exec -it vault-example-0 sh + +cat < /home/vault/postgres-app-policy.hcl +path "database/creds/sql-role" { + capabilities = ["read"] +} +EOF + +vault policy write postgres-app-policy /home/vault/postgres-app-policy.hcl + ``` -The above maps our Kubernetes service account, used by our pod, to a policy. -Now lets create the policy to map our service account to a bunch of secrets + +Bind our role to a service account for our application ``` kubectl -n vault-example exec -it vault-example-0 sh -cat < /home/vault/app-policy.hcl -path "secret/basic-secret/*" { - capabilities = ["read"] -} -EOF -vault policy write basic-secret-policy /home/vault/app-policy.hcl -exit -``` - -Now our service account for our pod can access all secrets under `secret/basic-secret/*` -Lets create some secrets. +vault write auth/kubernetes/role/sql-role \ + bound_service_account_names=dynamic-postgres \ + bound_service_account_namespaces=vault-example \ + policies=postgres-app-policy \ + ttl=1h -``` -kubectl -n vault-example exec -it vault-example-0 sh -vault secrets enable -path=secret/ kv -vault kv put secret/basic-secret/helloworld username=dbuser password=sUp3rS3cUr3P@ssw0rd -exit ``` -Lets deploy our app and see if it works: - -``` -kubectl -n vault-example apply -f ./hashicorp/vault/example-apps/basic-secret/deployment.yaml -``` \ No newline at end of file +kubectl -n vault-example apply -f .\hashicorp\vault\example-apps\dynamic-postgresql\deployment.yaml \ No newline at end of file diff --git a/hashicorp/readme.md b/hashicorp/vault/readme.md similarity index 91% rename from hashicorp/readme.md rename to hashicorp/vault/readme.md index afee566..1e5a5c2 100644 --- a/hashicorp/readme.md +++ b/hashicorp/vault/readme.md @@ -8,6 +8,7 @@ It's critical because we'll need certain [admission controllers](https://kuberne To get 1.17 for Linux\Windows, just use `kind` since you can create a 1.17 with admissions all setup. ``` +#Windows kind create cluster --name vault --image kindest/node:v1.17.0@sha256:9512edae126da271b66b990b6fff768fbb7cd786c7d39e86bdf55906352fdf62 #Linux @@ -27,6 +28,7 @@ Remember not to check-in your TLS to GIT :) ``` kubectl create ns vault-example kubectl -n vault-example apply -f ./hashicorp/vault/server/ +kubectl -n vault-example get pods ``` ## Storage @@ -44,6 +46,7 @@ if you need to change the storage class, deleve the pvc , edit YAML and re-apply kubectl -n vault-example exec -it vault-example-0 vault operator init #unseal 3 times kubectl -n vault-example exec -it vault-example-0 vault operator unseal +kubectl -n vault-example get pods ``` ## Depploy the Injector @@ -53,7 +56,8 @@ VIDEO: Injector allows pods to automatically get secrets from the vault. ``` -kubectl -n vault-example apply -f ./hashicorp/vault/injector\ +kubectl -n vault-example apply -f ./hashicorp/vault/injector/ +kubectl -n vault-example get pods ``` ## Injector Kubernetes Auth Policy @@ -70,6 +74,9 @@ vault write auth/kubernetes/config \ token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ kubernetes_host=https://${KUBERNETES_PORT_443_TCP_ADDR}:443 \ kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt +exit + +kubectl -n vault-example get pods ``` @@ -91,7 +98,7 @@ Objective: * Let's create a basic secret in vault manually * Application consumes the secret automatically -[Try it](./vault/example-apps/basic-secret/readme.md) +[Try it](./example-apps/basic-secret/readme.md) From b279955aff9afd0a3f0b86ab84189aa8c51cd118 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Fri, 6 Mar 2020 09:54:25 +1100 Subject: [PATCH 13/14] pgadmin --- .../dynamic-postgresql/pgadmin.yaml | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 hashicorp/vault/example-apps/dynamic-postgresql/pgadmin.yaml diff --git a/hashicorp/vault/example-apps/dynamic-postgresql/pgadmin.yaml b/hashicorp/vault/example-apps/dynamic-postgresql/pgadmin.yaml new file mode 100644 index 0000000..6eb0394 --- /dev/null +++ b/hashicorp/vault/example-apps/dynamic-postgresql/pgadmin.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: ConfigMap +metadata: +  name: pgadmin-config +  labels: +    app: pgadmin +data: + PGADMIN_DEFAULT_EMAIL: admin@admin.com + PGADMIN_DEFAULT_PASSWORD: admin123 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: pgadmin +spec: + selector: + matchLabels: + app: pgadmin + replicas: 1 + template: + metadata: + labels: + app: pgadmin + spec: + containers: + - name: pgadmin + image: dpage/pgadmin4 + imagePullPolicy: "IfNotPresent" + ports: + - containerPort: 80 + envFrom: + - configMapRef: + name: pgadmin-config \ No newline at end of file From b7f939855dfaba187cb1af1d41b3394158603e10 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Fri, 6 Mar 2020 20:29:21 +1100 Subject: [PATCH 14/14] add pgadmin interface --- .../example-apps/dynamic-postgresql/pgadmin.yaml | 6 +++--- .../vault/example-apps/dynamic-postgresql/readme.md | 1 + hashicorp/vault/readme.md | 11 +++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/hashicorp/vault/example-apps/dynamic-postgresql/pgadmin.yaml b/hashicorp/vault/example-apps/dynamic-postgresql/pgadmin.yaml index 6eb0394..208158d 100644 --- a/hashicorp/vault/example-apps/dynamic-postgresql/pgadmin.yaml +++ b/hashicorp/vault/example-apps/dynamic-postgresql/pgadmin.yaml @@ -1,9 +1,9 @@ apiVersion: v1 kind: ConfigMap metadata: -  name: pgadmin-config -  labels: -    app: pgadmin + name: pgadmin-config + labels: + app: pgadmin data: PGADMIN_DEFAULT_EMAIL: admin@admin.com PGADMIN_DEFAULT_PASSWORD: admin123 diff --git a/hashicorp/vault/example-apps/dynamic-postgresql/readme.md b/hashicorp/vault/example-apps/dynamic-postgresql/readme.md index 425f3c5..b96546e 100644 --- a/hashicorp/vault/example-apps/dynamic-postgresql/readme.md +++ b/hashicorp/vault/example-apps/dynamic-postgresql/readme.md @@ -6,6 +6,7 @@ Deploy our test database ``` kubectl create ns postgres kubectl -n postgres apply -f ./hashicorp/vault/example-apps/dynamic-postgresql/postgres.yaml +kubectl -n postgres apply -f ./hashicorp/vault/example-apps/dynamic-postgresql/pgadmin.yaml kubectl -n postgres get pods kubectl -n postgres exec -it bash diff --git a/hashicorp/vault/readme.md b/hashicorp/vault/readme.md index 1e5a5c2..bee642d 100644 --- a/hashicorp/vault/readme.md +++ b/hashicorp/vault/readme.md @@ -100,8 +100,15 @@ Objective: [Try it](./example-apps/basic-secret/readme.md) - - +### Dynamic Secrets: Postgres + +Objective: +---------- +* We have a Postgres Database +* Let's delegate Vault to manage life cycles of our database credentials +* Deploy an app, that automatically gets it's credentials from vault + +[Try it](./example-apps/basic-secret/readme.md)