Add kubernetes job #53
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CI | |
on: | |
push: | |
branches: | |
- main | |
tags: | |
- '*' | |
pull_request: | |
branches: | |
- main | |
env: | |
CARGO_TERM_COLOR: always | |
VAULT_ADDR: http://127.0.0.1:8200 | |
jobs: | |
build: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Build | |
run: cargo build --verbose | |
- name: Run tests | |
run: cargo test --verbose | |
- name: Install Vault | |
run: | | |
sudo apt-get update -y | |
sudo apt-get install -y gpg | |
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg >/dev/null | |
gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint | |
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list | |
sudo apt-get update -y | |
sudo apt-get install -y vault | |
- name: Run local test | |
run: ./scripts/test.sh | |
- name: Run Vault in background | |
run: | | |
vault server -dev -dev-root-token-id=unsafe-root-token & | |
# Make sure Vault is running | |
sleep 1 | |
while ! vault token lookup; do sleep 1; done | |
- name: Enable AppRole auth method | |
run: | | |
vault auth enable approle | |
- name: Enable secrets engine at the custom path | |
run: | | |
vault secrets enable -path=secret2 kv-v2 | |
- name: Make sure both standard and custom secrets engine are present | |
run: | | |
vault secrets list | |
vault secrets list | grep -qE '^secret/\s+kv' | |
vault secrets list | grep -qE '^secret2/\s+kv' | |
- name: Create Vault policy for reader | |
run: | | |
cat <<EOF | vault policy write vault-sync-reader - | |
path "secret/data/*" { | |
capabilities = ["read", "list"] | |
} | |
path "secret/metadata/*" { | |
capabilities = ["read", "list"] | |
} | |
path "secret2/data/*" { | |
capabilities = ["read", "list"] | |
} | |
path "secret2/metadata/*" { | |
capabilities = ["read", "list"] | |
} | |
EOF | |
- name: Create Vault policy for writer | |
run: | | |
cat <<EOF | vault policy write vault-sync-writer - | |
path "secret/data/*" { | |
capabilities = ["create", "read", "update", "delete"] | |
} | |
path "secret2/data/*" { | |
capabilities = ["create", "read", "update", "delete"] | |
} | |
EOF | |
- name: Create Vault AppRoles for reader and writer | |
run: | | |
vault write auth/approle/role/vault-sync-reader token_policies=vault-sync-reader | |
vault write auth/approle/role/vault-sync-writer token_policies=vault-sync-writer | |
- name: Prepare environments variables for token authentication | |
run: | | |
cat <<EOF > ./vault-sync-token.env | |
export VAULT_SYNC_SRC_TOKEN=unsafe-root-token | |
export VAULT_SYNC_DST_TOKEN=unsafe-root-token | |
EOF | |
- name: Prepare environments variables for approle authentication | |
run: | | |
cat <<EOF > ./vault-sync-app-role.env | |
export VAULT_SYNC_SRC_ROLE_ID=$(vault read auth/approle/role/vault-sync-reader/role-id -format=json | jq -r .data.role_id) | |
export VAULT_SYNC_SRC_SECRET_ID=$(vault write -f auth/approle/role/vault-sync-reader/secret-id -format=json | jq -r .data.secret_id) | |
export VAULT_SYNC_DST_ROLE_ID=$(vault read auth/approle/role/vault-sync-writer/role-id -format=json | jq -r .data.role_id) | |
export VAULT_SYNC_DST_SECRET_ID=$(vault write -f auth/approle/role/vault-sync-writer/secret-id -format=json | jq -r .data.secret_id) | |
EOF | |
- name: Create configuration file for vault-sync | |
run: | | |
cat <<EOF > ./vault-sync.yaml | |
id: vault-sync | |
full_sync_interval: 10 | |
src: | |
url: http://127.0.0.1:8200/ | |
prefix: src | |
dst: | |
url: http://127.0.0.1:8200/ | |
prefix: dst | |
EOF | |
- name: Test sync once with token | |
run: | | |
vault kv put secret/src/testsecret1 foo1=bar1 | |
source ./vault-sync-token.env | |
cargo run -- --config vault-sync.yaml --once | |
vault kv get secret/dst/testsecret1 | |
- name: Test sync once with approle | |
run: | | |
vault kv put secret/src/testsecret2 foo2=bar2 | |
source ./vault-sync-app-role.env | |
cargo run -- --config vault-sync.yaml --once | |
vault kv get secret/dst/testsecret2 | |
- name: Create configuration file for vault-sync (custom secrets engine) | |
run: | | |
cat <<EOF > ./vault-sync.yaml | |
id: vault-sync | |
full_sync_interval: 10 | |
src: | |
url: http://127.0.0.1:8200/ | |
prefix: src | |
backend: secret2 | |
dst: | |
url: http://127.0.0.1:8200/ | |
prefix: dst | |
backend: secret2 | |
EOF | |
- name: Test sync once with token | |
run: | | |
vault kv put -mount secret2 src/testsecret1 foo1=bar1 | |
source ./vault-sync-token.env | |
cargo run -- --config vault-sync.yaml --once | |
vault kv get -mount secret2 dst/testsecret1 | |
- name: Test sync once with approle | |
run: | | |
vault kv put -mount secret2 src/testsecret2 foo2=bar2 | |
source ./vault-sync-app-role.env | |
cargo run -- --config vault-sync.yaml --once | |
vault kv get -mount secret dst/testsecret2 | |
kubernetes: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Create Kubernetes cluster | |
run: | | |
cat <<EOF | kind create cluster --config=- | |
kind: Cluster | |
apiVersion: kind.x-k8s.io/v1alpha4 | |
nodes: | |
- role: control-plane | |
image: kindest/node:v1.29.4 | |
EOF | |
- name: Deploy Vault | |
run: | | |
kubectl create ns vault | |
helm repo add hashicorp https://helm.releases.hashicorp.com | |
helm upgrade --install vault hashicorp/vault --namespace=vault --set server.dev.enabled=true --set injector.enabled=false | |
- name: Wait for Vault readiness | |
run: | | |
kubectl --namespace=vault get service | |
for i in $(seq 1 30); do | |
if kubectl --namespace=vault get pods | grep -q vault-0 &>/dev/null; then | |
break | |
fi | |
sleep 1 | |
done | |
kubectl --namespace=vault wait pod/vault-0 --for=condition=Ready --timeout=180s | |
kubectl --namespace=vault logs vault-0 | |
- name: Create secret backends | |
run: | | |
kubectl --namespace=vault exec vault-0 -- vault secrets enable -version=2 -path=src kv | |
kubectl --namespace=vault exec vault-0 -- vault secrets enable -version=2 -path=dst kv | |
kubectl --namespace=vault exec vault-0 -- vault kv put -mount src test foo=bar | |
- uses: actions/checkout@v4 | |
- name: Build Docker image | |
run: | | |
docker build -t pbchekin/vault-sync:$GITHUB_SHA -f docker/Dockerfile . | |
- name: Load Docker image to the cluster | |
run: | | |
kind load docker-image pbchekin/vault-sync:$GITHUB_SHA | |
- name: Deploy vault-sync | |
run: | | |
kubectl create ns vault-sync | |
cd install/helm/vault-sync/ | |
helm install --namespace=vault-sync vault-sync -f - . <<EOF | |
image: | |
tag: $GITHUB_SHA | |
vaultSync: | |
id: vault-sync | |
full_sync_interval: 3600 | |
src: | |
url: http://vault.vault.svc.cluster.local:8200 | |
backend: src | |
dst: | |
url: http://vault.vault.svc.cluster.local:8200 | |
backend: dst | |
# Secrets must be base64 encoded | |
secrets: | |
VAULT_SYNC_SRC_TOKEN: cm9vdA== | |
VAULT_SYNC_DST_TOKEN: cm9vdA== | |
EOF | |
- name: Wait for vault-sync readiness | |
run: | | |
for i in $(seq 1 30); do | |
if kubectl --namespace=vault-sync get pods | grep -q vault-sync &>/dev/null; then | |
break | |
fi | |
sleep 1 | |
done | |
kubectl --namespace=vault-sync wait pod -l app.kubernetes.io/instance=vault-sync --for=condition=Ready --timeout=180s | |
- name: Check sync result | |
run: | | |
# wait for the initial sync | |
sleep 5 | |
kubectl --namespace=vault exec vault-0 -- vault kv get -mount dst test | |
- name: Show vault-sync logs | |
run: | | |
kubectl --namespace=vault-sync logs -l app.kubernetes.io/instance=vault-sync |