diff --git a/README.md b/README.md new file mode 100644 index 0000000..a16f88f --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +# Using KSOPS and adding secrets + +## Keys + +The public key is stored in the repo as `./.sops.yaml`. +The private keys are: + +- K8s cluster as a secret +- MacOS - `$HOME/Library/Application Support/sops/age/keys.txt` + +## 1. Create the resource + +``` +cat < secret.yaml +apiVersion: v1 +kind: Secret +metadata: + name: mysecret +type: Opaque +data: + username: YWRtaW4= + password: MWYyZDFlMmU2N2Rm +EOF +``` + +## 2. Encrypt the resource + +Note 1: the encryption key is included in the repo, but the decryption key is not + +Note 2: Delete the plaintext resource after encrypting it. + +``` +# Encrypt with SOPS CLI +# Specify SOPS configuration in .sops.yaml +sops -e secret.yaml > secret.enc.yaml +``` + +## 3. Create teh KSOPS kustomize generator + +``` +# Create a local Kubernetes Secret +cat < secret-generator.yaml +apiVersion: viaduct.ai/v1 +kind: ksops +metadata: + # Specify a name + name: example-secret-generator + annotations: + config.kubernetes.io/function: | + exec: + # if the binary is in your PATH, you can do + path: ksops + # otherwise, path should be relative to manifest files, like + # path: ../../../ksops +files: + - ./secret.enc.yaml +EOF +``` + +## 4. Add to kustomization + +``` +generators: + - ./secret-generator.yaml +``` + +## 5. Build to test + +``` +kustomize build --enable_alpha_plugins path/to/kustomization.yaml +``` + +# References + +- https://getsops.io/docs/#encrypting-and-decrypting-from-other-programs +- https://github.com/viaduct-ai/kustomize-sops diff --git a/apps/cloudflare-tunnel/base/deployment.yaml b/apps/cloudflare-tunnel/base/deployment.yaml new file mode 100644 index 0000000..f2d526e --- /dev/null +++ b/apps/cloudflare-tunnel/base/deployment.yaml @@ -0,0 +1,38 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: cloudflared + name: cloudflared-deployment +spec: + replicas: 2 + selector: + matchLabels: + pod: cloudflared + template: + metadata: + creationTimestamp: null + labels: + pod: cloudflared + spec: + containers: + - command: + - cloudflared + - tunnel + - --no-autoupdate + # In a k8s environment, the metrics server needs to listen outside the pod it runs on. + # The address 0.0.0.0:2000 allows any pod in the namespace. + - --metrics + - 0.0.0.0:2000 + - run + image: cloudflare/cloudflared:latest + name: cloudflared + livenessProbe: + httpGet: + # Cloudflared has a /ready endpoint which returns 200 if and only if + # it has an active connection to the edge. + path: /ready + port: 2000 + failureThreshold: 1 + initialDelaySeconds: 10 + periodSeconds: 10 diff --git a/apps/cloudflare-tunnel/base/kustomization.yaml b/apps/cloudflare-tunnel/base/kustomization.yaml new file mode 100644 index 0000000..ad6b3f5 --- /dev/null +++ b/apps/cloudflare-tunnel/base/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - namespace.yaml + - deployment.yaml diff --git a/apps/cloudflare-tunnel/base/namespace.yaml b/apps/cloudflare-tunnel/base/namespace.yaml new file mode 100644 index 0000000..4bd7dc1 --- /dev/null +++ b/apps/cloudflare-tunnel/base/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: network-system diff --git a/apps/cloudflare-tunnel/overlays/system/config.json b/apps/cloudflare-tunnel/overlays/system/config.json new file mode 100644 index 0000000..7503bc2 --- /dev/null +++ b/apps/cloudflare-tunnel/overlays/system/config.json @@ -0,0 +1,11 @@ +{ + "appName": "cloudflare-tunnel", + "userGivenName": "cloudflare-tunnel", + "destNamespace": "network-system", + "destServer": "https://kubernetes.default.svc", + "srcPath": "apps/cloudflare-tunnel/overlays/system", + "srcRepoURL": "ssh://git@gitea-ssh.gitops.svc.cluster.local:2222/davad/argo.git", + "srcTargetRevision": "", + "labels": null, + "annotations": null +} diff --git a/apps/cloudflare-tunnel/overlays/system/deployment.patch.yaml b/apps/cloudflare-tunnel/overlays/system/deployment.patch.yaml new file mode 100644 index 0000000..38a15f2 --- /dev/null +++ b/apps/cloudflare-tunnel/overlays/system/deployment.patch.yaml @@ -0,0 +1,15 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cloudflared-deployment +spec: + template: + spec: + containers: + - name: cloudflared + env: + - name: TUNNEL_TOKEN + valueFrom: + secretKeyRef: + name: cloudflared-config + key: token diff --git a/apps/cloudflare-tunnel/overlays/system/kustomization.yaml b/apps/cloudflare-tunnel/overlays/system/kustomization.yaml new file mode 100644 index 0000000..50e9778 --- /dev/null +++ b/apps/cloudflare-tunnel/overlays/system/kustomization.yaml @@ -0,0 +1,11 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../../base + +generators: + - ./secret-generator.yaml + +patches: + - path: deployment.patch.yaml diff --git a/apps/cloudflare-tunnel/overlays/system/secret-generator.yaml b/apps/cloudflare-tunnel/overlays/system/secret-generator.yaml new file mode 100644 index 0000000..7e5244f --- /dev/null +++ b/apps/cloudflare-tunnel/overlays/system/secret-generator.yaml @@ -0,0 +1,10 @@ +apiVersion: viaduct.ai/v1 +kind: ksops +metadata: + name: cloudflared-ksops-generator + annotations: + config.kubernetes.io/function: | + exec: + path: ksops +files: + - ./secret.enc.yaml diff --git a/apps/cloudflare-tunnel/overlays/system/secret.enc.yaml b/apps/cloudflare-tunnel/overlays/system/secret.enc.yaml new file mode 100644 index 0000000..5b6857c --- /dev/null +++ b/apps/cloudflare-tunnel/overlays/system/secret.enc.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: Secret +metadata: + name: cloudflared-config +type: Opaque +data: + token: ENC[AES256_GCM,data:tkJD0z6idw6QZZL8IKu/PWo6RXABPy8BcgtP3ai43QnbXjW+uZa3nimTLSwWFcFIcVpRQAKYjvCOFI18ntf+gePk3rwLaUn7IXw2DerTwUYh6k8Erau1Tpp1J8K2X3l6JDtRVlpUwKaSyvIOuhlxsPNra+np3433flYHEuXCC2tB27IXcB/k36KHAramo3XptHhKe+3DoywUfQTYqco9oBrGWWCJVlcGm+KhOMAieekqdW9Ftj3EguMcQGkcLzqoiK1Z3v+fkI1/IL0gWR8Vew6hUzlD1IFcj0VD0vpGSM9s/VzMVn3vp7D1e3L3urFkmyM9nJHUW/8=,iv:In08NkxVSuyAzPdl7dayM/QXZPnc1OrShGrwar/iLsE=,tag:qEk5ZRioUvXwGcOClhdkHQ==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1y26vr5qt6th3wu92rnsgkqcpxxah3pqkqa4khcjjycm3kg40aqyqjgfzx9 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxNGxaU3FHY1dMTnNXZDh2 + S2M2QjhPcERqTXI0ajRLRDQ1MXdZNHdUbkhZCnM5Ly9VYk5ySlZmUVUwb3A3UzBI + QzU4RHFiQVFzaGlqbHFZOXQxVisrMVkKLS0tIEJEYVllQVNKc0ppTTZ6SUU1dXRI + a1ZkNHJLQjBlNmhaOTBMVXJEK1UxY1kKy4ioaiasJz3obb/+oR666lDqCWI4OcZu + aUAeQPGqR9U/UWLHqdKcJvsAxVItQyrl9a3vANdg6FZP8IQqDd4y/w== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-09-27T21:03:45Z" + mac: ENC[AES256_GCM,data:kaQhH6AgeAhMuIqG8M4SoJCVUJhv9jkcXssoRASOM5sSixvRuzyLzaBHjY0jGHpmNPDDYmhe8YCrmnKBR6XSHbe5W0bkAK3fV+QPcWlHP5RHmtLMq68KM02ljxeKe+Z3Rdy5urydVCU8NYLnFET9rIcFFJMI5DM9pX5flNX3ZeQ=,iv:Ks8A9awmvnL7LmKrKc7tl3qsfc6oH4UAUeokMMfdjqc=,tag:xgN5BNdHkEllnR0TEjf0YQ==,type:str] + pgp: [] + encrypted_regex: ^(data|stringData)$ + version: 3.8.1