This commit is contained in:
@@ -0,0 +1,108 @@
|
|||||||
|
name: Validate manifests
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install tools
|
||||||
|
run: |
|
||||||
|
curl -sL https://github.com/yannh/kubeconform/releases/latest/download/kubeconform-linux-amd64.tar.gz \
|
||||||
|
| tar xz -C /usr/local/bin
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
|
||||||
|
curl -fsSL https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 \
|
||||||
|
-o /usr/local/bin/yq
|
||||||
|
chmod +x /usr/local/bin/yq
|
||||||
|
|
||||||
|
mkdir -p .ci-schemas/argoproj.io
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/argoproj.io/applicationset_v1alpha1.json \
|
||||||
|
-o .ci-schemas/argoproj.io/applicationset_v1alpha1.json
|
||||||
|
cp .ci-schemas/argoproj.io/applicationset_v1alpha1.json .ci-schemas/argoproj.io/ApplicationSet_v1alpha1.json
|
||||||
|
cp .ci-schemas/argoproj.io/applicationset_v1alpha1.json .ci-schemas/argoproj.io/ApplicationSet.json
|
||||||
|
cp .ci-schemas/argoproj.io/applicationset_v1alpha1.json .ci-schemas/argoproj.io/applicationset.json
|
||||||
|
|
||||||
|
- name: kubeconform - raw YAML
|
||||||
|
run: |
|
||||||
|
bootstrap_enabled=false
|
||||||
|
if [ -f bootstrap/config.yaml ] && grep -Eq '^[[:space:]]*enabled:[[:space:]]*true[[:space:]]*$' bootstrap/config.yaml; then
|
||||||
|
bootstrap_enabled=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
mapfile -t manifests < <(
|
||||||
|
find . -type f -name '*.yaml' \
|
||||||
|
! -path './.gitea/*' \
|
||||||
|
! -path './manifest/overlays/*/helm-values/*' \
|
||||||
|
! -path './bootstrap/config.yaml' \
|
||||||
|
| sort
|
||||||
|
)
|
||||||
|
|
||||||
|
if [ "$bootstrap_enabled" != "true" ]; then
|
||||||
|
filtered=()
|
||||||
|
for manifest in "${manifests[@]}"; do
|
||||||
|
[ "$manifest" = "./bootstrap/applicationset.yaml" ] && continue
|
||||||
|
filtered+=("$manifest")
|
||||||
|
done
|
||||||
|
manifests=("${filtered[@]}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${#manifests[@]}" -eq 0 ]; then
|
||||||
|
echo "No manifests found"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s\n' "${manifests[@]}" \
|
||||||
|
| xargs kubeconform \
|
||||||
|
-strict \
|
||||||
|
-kubernetes-version 1.35.0 \
|
||||||
|
-schema-location default \
|
||||||
|
-schema-location '.ci-schemas/{{.Group}}/{{.ResourceKind}}{{.KindSuffix}}.json' \
|
||||||
|
-schema-location '.ci-schemas/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
|
||||||
|
-summary
|
||||||
|
|
||||||
|
- name: Helm template
|
||||||
|
run: |
|
||||||
|
chart_version=$(yq '.spec.generators[0].list.elements[0].chartVersion' bootstrap/applicationset.yaml)
|
||||||
|
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
|
||||||
|
helm repo update sealed-secrets
|
||||||
|
helm template sealed-secrets-controller sealed-secrets/sealed-secrets \
|
||||||
|
--namespace kube-system \
|
||||||
|
--version "$chart_version" \
|
||||||
|
-f manifest/overlays/production/helm-values/values.yaml \
|
||||||
|
>/tmp/rendered.yaml
|
||||||
|
kubeconform \
|
||||||
|
-strict \
|
||||||
|
-kubernetes-version 1.35.0 \
|
||||||
|
/tmp/rendered.yaml
|
||||||
|
|
||||||
|
- name: Apply bootstrap ApplicationSet
|
||||||
|
env:
|
||||||
|
KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }}
|
||||||
|
run: |
|
||||||
|
if [ "${GITHUB_EVENT_NAME:-}" != "push" ] || [ "${GITHUB_REF:-}" != "refs/heads/main" ]; then
|
||||||
|
echo "Skipping bootstrap apply: only push events on main may apply"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f bootstrap/config.yaml ] || ! grep -Eq '^[[:space:]]*enabled:[[:space:]]*true[[:space:]]*$' bootstrap/config.yaml; then
|
||||||
|
echo "Skipping bootstrap apply: bootstrap/config.yaml is not enabled"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${KUBECONFIG_B64:-}" ]; then
|
||||||
|
echo "KUBECONFIG_B64 secret is required to apply bootstrap/applicationset.yaml"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl -fsSL https://dl.k8s.io/release/$(curl -fsSL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl \
|
||||||
|
-o /usr/local/bin/kubectl
|
||||||
|
chmod +x /usr/local/bin/kubectl
|
||||||
|
|
||||||
|
mkdir -p "${HOME}/.kube"
|
||||||
|
printf '%s' "$KUBECONFIG_B64" | base64 -d > "${HOME}/.kube/config"
|
||||||
|
|
||||||
|
kubectl apply -f bootstrap/applicationset.yaml
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
.DS_Store
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# sealed-secrets
|
||||||
|
|
||||||
|
GitOps source-of-truth repository for the cluster Sealed Secrets controller.
|
||||||
|
|
||||||
|
This repo follows the same dormant-bootstrap pattern as the other application
|
||||||
|
repositories, but the runtime payload is a pinned upstream Helm chart instead of
|
||||||
|
raw kustomize manifests. The controller is installed in `kube-system` with the
|
||||||
|
name `sealed-secrets-controller` so `kubeseal` works with its default controller
|
||||||
|
name assumptions.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```text
|
||||||
|
.
|
||||||
|
├── .gitea/
|
||||||
|
│ └── workflows/validate.yaml
|
||||||
|
├── .gitignore
|
||||||
|
├── bootstrap/
|
||||||
|
│ ├── applicationset.yaml
|
||||||
|
│ └── config.yaml
|
||||||
|
├── manifest/
|
||||||
|
│ └── overlays/
|
||||||
|
│ └── production/
|
||||||
|
│ └── helm-values/
|
||||||
|
│ └── values.yaml
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Bootstrap activation model
|
||||||
|
|
||||||
|
1. Prepare the repo on `init`.
|
||||||
|
2. Keep `bootstrap/config.yaml` set to `enabled: false` while validating.
|
||||||
|
3. Promote the repo to `main`.
|
||||||
|
4. Change `bootstrap/config.yaml` to `enabled: true` on `main`.
|
||||||
|
5. Let the bootstrap workflow apply `bootstrap/applicationset.yaml`.
|
||||||
|
|
||||||
|
## Controller decisions
|
||||||
|
|
||||||
|
- Namespace: `kube-system`
|
||||||
|
- Helm chart: `bitnami-labs/sealed-secrets`
|
||||||
|
- Chart version pin: `2.18.5`
|
||||||
|
- Controller name override: `sealed-secrets-controller`
|
||||||
|
|
||||||
|
The name override matters because the chart defaults to `sealed-secrets`, while
|
||||||
|
`kubeseal` expects `sealed-secrets-controller` unless you pass explicit flags.
|
||||||
|
|
||||||
|
## Secret migration workflow
|
||||||
|
|
||||||
|
1. Install `kubeseal` locally.
|
||||||
|
2. Fetch the controller cert:
|
||||||
|
`kubeseal --fetch-cert --controller-namespace kube-system > sealed-secrets.pem`
|
||||||
|
3. Convert an existing Secret manifest:
|
||||||
|
`kubeseal --format yaml --cert sealed-secrets.pem < secret.yaml > sealed-secret.yaml`
|
||||||
|
4. Commit the resulting `SealedSecret` manifest in the owning app repo.
|
||||||
|
5. Remove the old SOPS-backed secret generator entry only after the app is
|
||||||
|
syncing from the new `SealedSecret` path.
|
||||||
|
|
||||||
|
Use the default `strict` scope unless a secret must survive renames inside the
|
||||||
|
same namespace. Avoid `cluster-wide` scope unless there is a concrete need.
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: ApplicationSet
|
||||||
|
metadata:
|
||||||
|
name: sealed-secrets
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
goTemplate: true
|
||||||
|
goTemplateOptions:
|
||||||
|
- missingkey=error
|
||||||
|
generators:
|
||||||
|
- list:
|
||||||
|
elements:
|
||||||
|
- environment: production
|
||||||
|
namespace: kube-system
|
||||||
|
path: manifest/overlays/production
|
||||||
|
chartVersion: 2.18.5
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
name: 'sealed-secrets-{{ .environment }}'
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: argocd
|
||||||
|
app.kubernetes.io/name: sealed-secrets
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
sources:
|
||||||
|
- repoURL: https://bitnami-labs.github.io/sealed-secrets
|
||||||
|
chart: sealed-secrets
|
||||||
|
targetRevision: '{{ .chartVersion }}'
|
||||||
|
helm:
|
||||||
|
releaseName: sealed-secrets-controller
|
||||||
|
valueFiles:
|
||||||
|
- $values/{{ .path }}/helm-values/values.yaml
|
||||||
|
- repoURL: http://gitea-ha-http.apps:3000/olb42/sealed-secrets.git
|
||||||
|
targetRevision: main
|
||||||
|
ref: values
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: '{{ .namespace }}'
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=false
|
||||||
|
- ApplyOutOfSyncOnly=true
|
||||||
|
- ServerSideApply=true
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
enabled: false
|
||||||
|
target_namespace: argocd
|
||||||
|
apply_from_branch: main
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Production values for the official sealed-secrets Helm chart.
|
||||||
|
# Chart version is pinned in bootstrap/applicationset.yaml.
|
||||||
|
|
||||||
|
fullnameOverride: sealed-secrets-controller
|
||||||
|
namespace: kube-system
|
||||||
|
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 128Mi
|
||||||
|
limits:
|
||||||
|
cpu: 250m
|
||||||
|
memory: 256Mi
|
||||||
|
|
||||||
|
podLabels:
|
||||||
|
app.kubernetes.io/part-of: sealed-secrets
|
||||||
|
app.kubernetes.io/environment: production
|
||||||
|
|
||||||
|
metrics:
|
||||||
|
serviceMonitor:
|
||||||
|
enabled: false
|
||||||
Reference in New Issue
Block a user