Skip to content

Deploy MinIO via Argo CD using 1Password Operator secrets (k3s + NFS) #194

@SRF-Audio

Description

@SRF-Audio

Goal

Deploy MinIO into k3s via Argo CD Application, with:

  • Standalone MinIO (single-node / non-distributed)
  • Persistence on NFS-backed PVC
  • Credentials sourced exclusively via 1Password Operator CRDs (OnePasswordItem)
  • Provisioning enabled to create a bucket + a Loki user (non-root)
  • ClusterIP only (no ingress)

Repo changes

1) Add new MinIO app folder and manifests

Create (match your repo conventions; names here are suggested):

  • argocd/minio/minio.yml (ArgoCD Application)
  • argocd/minio/minio-onepassword.yml (OnePasswordItem CR(s))

Namespace:

  • observability-minio

Argo project:

  • coachlight-k3s-observability

2) 1Password Operator objects (no raw Secret manifests)

2.1 Create a 1Password item in your vault

Copilot should not do this step in git (obviously), but the PR should document the required 1Password item.

Create a 1Password item (example name):

  • k3s-observability-minio

It must contain fields for:

  • rootUser
  • rootPassword
  • lokiAccessKey
  • lokiSecretKey

(Exact field names can be adjusted to whatever the MinIO Helm chart expects; Copilot must map these correctly.)

2.2 Create OnePasswordItem CR in-cluster

Create argocd/minio/minio-onepassword.yml that defines a OnePasswordItem in observability-minio that materializes a Kubernetes Secret (generated by the operator) with the above fields.

Example (Copilot must adapt to your established 1Password Operator patterns in-repo):

---
apiVersion: onepassword.com/v1
kind: OnePasswordItem
metadata:
  name: minio-credentials
  namespace: observability-minio
spec:
  itemPath: "vaults/<YOUR_VAULT>/items/k3s-observability-minio"

Copilot requirements

  • Search the repo for existing OnePasswordItem usage and mirror:

    • apiVersion/kind
    • itemPath conventions
    • naming conventions
  • Ensure Argo CD will apply this CR before the MinIO Helm release needs the Secret (sync-wave or separate Application ordering).


3) MinIO Helm chart: use existingSecret generated by 1Password Operator

3.1 Chart source and version pin

Use the same chart approach you already intended (MinIO chart repo), but:

  • Pin targetRevision to a specific chart version (no floating).

Copilot must fetch chart values/docs and confirm parameter names.

3.2 Helm values: NFS persistence + secret wiring

In argocd/minio/minio.yml, set:

  • mode: standalone (or equivalent)
  • persistence.enabled: true
  • persistence.storageClass: <YOUR_NFS_STORAGECLASS>
  • service.type: ClusterIP
  • ingress.enabled: false
  • existingSecret: minio-credentials (this is the Secret produced by the OnePasswordItem)

Important
Copilot must confirm the exact key names the chart expects inside that Secret (often rootUser/rootPassword or accesskey/secretkey style). If the chart expects different keys, either:

  • Adjust the 1Password item field names to match, or
  • Use the chart’s “secretKey” mapping values (if supported).

No guessing. Copilot must validate against the chart’s values.yaml.


4) Provisioning: bucket + Loki user

We want MinIO to:

  • Create bucket: loki
  • Create a non-root user: loki
  • Attach policy allowing RW to loki bucket

Copilot requirements

  • Confirm the MinIO chart’s provisioning mechanism and exact values structure (some charts use a provisioning job and take config from values and/or Secrets).
  • Ensure the provisioning uses lokiAccessKey/lokiSecretKey from the Secret produced by the OnePasswordItem, not hardcoded.
  • Ensure the root creds are used only for MinIO bootstrap/provisioning, not by Loki.

Again: verify chart structure; don’t invent YAML.


5) Argo CD application manifests

5.1 OnePasswordItem should land first

You have two acceptable patterns. Copilot should use whichever matches your repo:

Pattern A: same Argo Application, split via sync-waves

  • Put the OnePasswordItem in the same folder and ensure it applies before Helm render depends on the Secret.
  • Use argocd.argoproj.io/sync-wave annotations on the CR manifest (or Kustomize ordering if you use it).

Pattern B: separate Argo Application

  • Create minio-secrets Application (wave 10)
  • Create minio Application (wave 20)
    This is often cleaner/less fragile.

Copilot should search the repo for how you already deploy 1Password items and follow that exact pattern.

5.2 MinIO Argo Application skeleton

Create argocd/minio/minio.yml similar to:

---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: minio
  namespace: argocd
  annotations:
    argocd.argoproj.io/sync-wave: "20"
spec:
  project: coachlight-k3s-observability
  source:
    repoURL: https://charts.min.io/
    chart: minio
    targetRevision: "<PINNED_VERSION>"
    helm:
      valuesObject:
        mode: standalone

        existingSecret: minio-credentials

        persistence:
          enabled: true
          storageClass: "<YOUR_NFS_STORAGECLASS>"
          size: 20Gi

        service:
          type: ClusterIP

        ingress:
          enabled: false

        provisioning:
          enabled: true
          # Copilot: fill in exact provisioning values according to chart values.yaml
          # Must create:
          # - bucket: loki
          # - user: loki (creds sourced from existingSecret keys)
          # - policy binding to bucket
  destination:
    server: https://kubernetes.default.svc
    namespace: observability-minio
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

6) Verification steps (commands only)

Add to PR description:

  • kubectl -n observability-minio get onepassworditems
  • kubectl -n observability-minio get secrets | grep minio-credentials
  • kubectl -n observability-minio get pods
  • kubectl -n observability-minio get pvc
  • kubectl -n observability-minio logs <minio-pod> (confirm startup)
  • Verify provisioning job/resources succeeded (chart-dependent)

  1. Expose MinIO Console UI via Tailscale Ingress (replace prior step)
    Intent

Expose the MinIO Console UI privately over Tailscale using the Tailscale Kubernetes Operator and an Ingress (so Homepage can discover it via ingress annotations the same way as your other tools).

Requirements

Copilot MUST:

Determine MinIO’s console service port

The MinIO chart typically exposes:

S3 API on 9000

Console on 9001

But Copilot must confirm the actual service ports created by the chart (names + ports) and target the console port.

Create an Ingress in observability-minio that routes:

https://minio./ → MinIO console service port

Apply the required Tailscale ingress annotations

Copilot must search the repo for how you already annotate Ingress resources for Tailscale exposure and copy that pattern exactly (annotation keys vary by operator/version and your setup).

Add Homepage discovery annotations

Copilot must follow your existing Homepage ingress discovery annotation pattern (whatever labels/annotations you’re already using in the repo for other services).

Deliverable manifest

Create argocd/minio/minio-ingress.yml containing:

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata annotations:

Tailscale operator exposure annotations (from repo precedent)

Homepage annotations (from repo precedent)

spec:

host: minio.

backend: MinIO console service + port

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions