Let Argo CD manage its own deployment

This commit is contained in:
2026-10-18 15:22:15 +02:00
parent ff1ae78f66
commit b83e27f27d
9 changed files with 210 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: argocd
namespace: argocd
spec:
description: Argo CD self-management
sourceRepos:
- https://code.brunner.ninja/feedc0de/homelab-gitops.git
- https://argoproj.github.io/argo-helm
destinations:
- namespace: argocd
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: apiextensions.k8s.io
kind: CustomResourceDefinition
- group: rbac.authorization.k8s.io
kind: ClusterRole
- group: rbac.authorization.k8s.io
kind: ClusterRoleBinding
namespaceResourceWhitelist:
- group: ""
kind: ConfigMap
- group: ""
kind: Service
- group: ""
kind: ServiceAccount
- group: apps
kind: Deployment
- group: apps
kind: StatefulSet
- group: networking.k8s.io
kind: Ingress
- group: networking.k8s.io
kind: NetworkPolicy
- group: rbac.authorization.k8s.io
kind: Role
- group: rbac.authorization.k8s.io
kind: RoleBinding
+23
View File
@@ -0,0 +1,23 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: argocd
namespace: argocd
spec:
project: argocd
source:
repoURL: https://code.brunner.ninja/feedc0de/homelab-gitops.git
targetRevision: main
path: apps/argocd
helm:
releaseName: argocd
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
enabled: true
prune: false
selfHeal: true
syncOptions:
- ServerSideApply=true
+74
View File
@@ -0,0 +1,74 @@
#!/bin/sh
set -eu
expected_context=kubernetes-admin@kubernetes
current_context=$(kubectl config current-context)
if [ "${current_context}" != "${expected_context}" ]; then
echo "Refusing recovery through unexpected context: ${current_context}" >&2
exit 1
fi
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
repository_dir=$(dirname -- "${script_dir}")
app_dir="${repository_dir}/apps/argocd"
for command in helm kubectl openssl base64 ruby; do
if ! command -v "${command}" >/dev/null 2>&1; then
echo "Required command not found: ${command}" >&2
exit 1
fi
done
kubectl create namespace argocd --dry-run=client --output=yaml \
| kubectl apply --filename=-
if ! kubectl --namespace argocd get secret argocd-secret >/dev/null 2>&1; then
kubectl --namespace argocd create secret generic argocd-secret
fi
if [ -z "$(kubectl --namespace argocd get secret argocd-secret --output='jsonpath={.data.server\.secretkey}')" ]; then
secret_key=$(openssl rand -hex 32)
secret_key_base64=$(printf '%s' "${secret_key}" | base64 | tr -d '\n')
secret_patch=$(mktemp)
chmod 600 "${secret_patch}"
printf '{"data":{"server.secretkey":"%s"}}\n' "${secret_key_base64}" > "${secret_patch}"
kubectl --namespace argocd patch secret argocd-secret \
--type=merge --patch-file="${secret_patch}" >/dev/null
rm -f "${secret_patch}"
unset secret_key secret_key_base64
fi
kubectl --namespace argocd label secret argocd-secret \
app.kubernetes.io/name=argocd-secret \
app.kubernetes.io/part-of=argocd --overwrite >/dev/null
if ! kubectl --namespace argocd get secret argocd-notifications-secret >/dev/null 2>&1; then
kubectl --namespace argocd create secret generic argocd-notifications-secret
fi
if ! kubectl --namespace argocd get secret argocd-redis >/dev/null 2>&1; then
redis_password=$(openssl rand -hex 32)
kubectl --namespace argocd create secret generic argocd-redis \
--from-literal="auth=${redis_password}"
unset redis_password
fi
if ! kubectl --namespace argocd get secret argocd-oidc >/dev/null 2>&1; then
echo "Missing argocd/argocd-oidc; restore or provision it before recovery." >&2
exit 1
fi
helm dependency update "${app_dir}"
set -- "${app_dir}"/charts/argo-cd-*.tgz
if [ "$#" -ne 1 ] || [ ! -f "$1" ]; then
echo "Expected exactly one downloaded argo-cd chart archive" >&2
exit 1
fi
chart_archive=$1
child_values=$(mktemp)
trap 'rm -f "${child_values}"' EXIT HUP INT TERM
ruby -ryaml -e 'puts YAML.dump(YAML.load_file(ARGV.fetch(0)).fetch("argo-cd"))' \
"${app_dir}/values.yaml" > "${child_values}"
helm upgrade --install argocd "${chart_archive}" \
--namespace argocd \
--values "${child_values}" \
--wait \
--timeout 10m
+6
View File
@@ -35,3 +35,9 @@ kubectl --namespace argocd wait application/metallb \
kubectl --namespace argocd wait application/metallb \
--for=jsonpath='{.status.health.status}'=Healthy \
--timeout=5m
kubectl --namespace argocd wait application/argocd \
--for=jsonpath='{.status.sync.status}'=Synced \
--timeout=10m
kubectl --namespace argocd wait application/argocd \
--for=jsonpath='{.status.health.status}'=Healthy \
--timeout=10m
+2
View File
@@ -1,6 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- argocd-project.yaml
- argocd.yaml
- project.yaml
- platform-project.yaml
- sealed-secrets.yaml