Skip to content

Commit

Permalink
Merge pull request #190 from bank-vaults/examples
Browse files Browse the repository at this point in the history
Add new examples
  • Loading branch information
sagikazarmark authored Sep 7, 2023
2 parents 270b14d + 5b56261 commit e6bde6e
Show file tree
Hide file tree
Showing 11 changed files with 483 additions and 0 deletions.
157 changes: 157 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Vault Operator examples

These examples demonstrate different Vault Operator features.

## Examples

- [Base](base/): Minimal example for launching Vault
- [File storage](file/): Persistent volumes and file storage
- [Startup secrets](startup-secrets/): Initialize Vault with secrets
- [Kubernetes auth](kubernetes-auth/): Authenticate against Vault using Kubernetes Service Accounts

## Prerequisites

- Ability to setup a Kubernetes cluster (eg. using [KinD](https://kind.sigs.k8s.io/))
- kubectl
- kustomize
- [Helm](https://helm.sh/)
- [vault CLI](https://developer.hashicorp.com/vault/downloads)
- kubectl [view-secret plugin](https://github.com/elsesiy/kubectl-view-secret) _(optional)_

It is recommended that you check out this repository and run examples from there as some examples require additional steps (but you may be able to run some of them directly):

```shell
git clone [email protected]:bank-vaults/vault-operator.git
cd vault-operator/examples
```

## Set up a Kubernetes cluster

Vault Operator should run on recent Kubernetes versions.
We generally use [KinD](https://kind.sigs.k8s.io) for demos, but [k3d](https://k3d.io) is also a popular option.

You can launch a local cluster using KinD by running the following command:

```shell
kind create cluster
```

## Install Vault Operator

Install the latest version of the Vault Operator:

```shell
helm upgrade --install --wait --namespace vault-system --create-namespace vault-operator oci://ghcr.io/bank-vaults/helm-charts/vault-operator
```

## Install Vault

Choose one of the examples in this folder, follow instructions (if any) in the README and install the example:

```shell
EXAMPLE=base

kustomize build $EXAMPLE | kubectl apply -f -
```

Or if you haven't checked out the repository:

```shell
EXAMPLE=base

kustomize build github.com/bank-vaults/vault-operator/examples/$EXAMPLE | kubectl apply -f -
```

> [!IMPORTANT]
> Examples are generally mutually exclusive, so make sure you don't install two of them on the same cluster at the same time.
> If you want to experiment with multiple examples, consider using [vCluster](https://www.vcluster.com/).
## Checking Vault

After installation, you may want to check the installation and interact with Vault.

First, wait for Vault to become ready:

```shell
kubectl wait pods vault-0 --for condition=Ready --timeout=120s
```

> [!NOTE]
> You may need to pass a namespace parameter to the above and following commands: `--namespace YOUR_NAMESPACE`
Set the Vault token from the Kubernetes secret:

```shell
export VAULT_TOKEN=$(kubectl get secrets vault-unseal-keys -o jsonpath={.data.vault-root} | base64 --decode)
```

Tell the CLI where Vault is listening:

```shell
export VAULT_ADDR=http://127.0.0.1:8200
```

> [!NOTE]
> If you are running an example with TLS configured, the address should be `https://127.0.0.1:8200`.
Port forward to the Vault service:

```shell
kubectl port-forward service/vault 8200 1>/dev/null &
```

Check Vault status:

```shell
vault status
```

Open the UI (and login with the root token):

```shell
open $VAULT_ADDR
```

The same commands again:

```shell
kubectl wait pods vault-0 --for condition=Ready --timeout=120s
export VAULT_TOKEN=$(kubectl get secrets vault-unseal-keys -o jsonpath={.data.vault-root} | base64 --decode)
export VAULT_ADDR=http://127.0.0.1:8200
kubectl port-forward service/vault 8200 1>/dev/null &
vault status
```

TODO: Write a script with the above commands?

## Cleanup

Kill background jobs:

```shell
kill %1
```

Delete the installed example:

```shell
kustomize build $EXAMPLE | kubectl delete -f -
```

Delete unseal keys:

```shell
kubectl delete secret vault-unseal-keys
```

Delete the Operator:

```shell
helm -n vault-system delete vault-operator
```

Delete the cluster:

```shell
kind delete cluster
```
6 changes: 6 additions & 0 deletions examples/base/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- rbac.yaml
- vault.yaml
46 changes: 46 additions & 0 deletions examples/base/rbac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
kind: ServiceAccount
apiVersion: v1
metadata:
name: vault

---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: vault
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["*"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "update", "patch"]

---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: vault
roleRef:
kind: Role
name: vault
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: vault

---
# This binding allows the deployed Vault instance to authenticate clients
# through Kubernetes ServiceAccounts (if configured so).
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: vault-auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: vault
namespace: default
50 changes: 50 additions & 0 deletions examples/base/vault.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
apiVersion: vault.banzaicloud.com/v1alpha1
kind: Vault
metadata:
name: vault
spec:
size: 1

image: hashicorp/vault:1.14.1

# Specify the ServiceAccount where the Vault Pod and the Bank-Vaults configurer/unsealer is running
serviceAccount: vault

# A YAML representation of a final vault config file.
# See https://www.vaultproject.io/docs/configuration/ for more information.
config:
storage:
inmem: {}
listener:
tcp:
address: "0.0.0.0:8200"
tls_disable: true
ui: true
log_level: debug

# See: https://bank-vaults.dev/docs/cli-tool/#example-external-vault-configuration
externalConfig:
policies:
- name: allow_secrets
rules: |
path "secret/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
secrets:
- path: secret
type: kv
description: General secrets.
options:
version: 2

auth:
- type: kubernetes
roles:
# Default role assumed by workloads by default
# Allow every pod in the default namespace to use the secret kv store
- name: default
bound_service_account_names: ["*"]
bound_service_account_namespaces: ["default"]
policies: ["allow_secrets"]
ttl: 1h
16 changes: 16 additions & 0 deletions examples/file/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../base/

patches:
- path: vault.yaml
- patch: |-
- op: remove
path: /spec/config/storage/inmem
target:
group: vault.banzaicloud.com
version: v1alpha1
kind: Vault
name: vault
32 changes: 32 additions & 0 deletions examples/file/vault.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apiVersion: vault.banzaicloud.com/v1alpha1
kind: Vault
metadata:
name: vault
spec:
# Use local disk to store Vault file data, see config section.
volumes:
- name: vault-file
persistentVolumeClaim:
claimName: vault-file

volumeMounts:
- name: vault-file
mountPath: /vault/file

volumeClaimTemplates:
- metadata:
name: vault-file
spec:
# https://kubernetes.io/docs/concepts/storage/persistent-volumes/#class-1
# storageClassName: ""
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi

config:
storage:
file:
path: /vault/file
84 changes: 84 additions & 0 deletions examples/kubernetes-auth/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Kubernetes auth

This example demonstrates how to authenticate against Vault using a Kubernetes Service Account token.
It also contains an example for writing policies targeting the accessor (identity behind the token).

## Check access

Run the following command to open a shell in the `default` namespace:

```shell
kubectl run vault-shell --rm -i --tty --env "VAULT_ADDR=http://vault:8200" --image hashicorp/vault:1.14.1 -- sh
```

Exchange the Service Account token for a Vault token:

```shell
export VAULT_TOKEN=$(vault write -field=token auth/kubernetes/login role=default jwt=$(cat /run/secrets/kubernetes.io/serviceaccount/token))
```

## Simple policy

Write some data into Vault:

```shell
vault kv put shared/foo bar=baz
```

Read the secret back:

```shell
vault kv get shared/foo
```

## Accessor-based policy

The second policy limits access to `namespaces/NAMESPACE` (namespace in this case is `default`, because that's where the shell pod is running).

Try writing some data into Vault:

```shell
vault kv put namespaces/not-default/foo bar=baz
```

You should see a permission denied error:

```
Error writing data to namespaces/data/vault/foo: Error making API request.
URL: PUT http://vault:8200/v1/namespaces/data/vault/foo
Code: 403. Errors:
* 1 error occurred:
* permission denied
```

Try writing some data into the right path:

```shell
vault kv put namespaces/default/foo bar=baz
```

Read the data back:

```shell
vault kv get namespaces/default/foo
```

Try reading from another path:

```shell
vault kv get namespaces/not-default/foo
```

It should fail again:

```
Error reading namespaces/data/not-default/foo: Error making API request.
URL: GET http://vault:8200/v1/namespaces/data/not-default/foo
Code: 403. Errors:
* 1 error occurred:
* permission denied
```
Loading

0 comments on commit e6bde6e

Please sign in to comment.