From 4906c52d8067acbe7cc6dc7b48bb1e12f75adbf2 Mon Sep 17 00:00:00 2001 From: James Andariese Date: Sun, 23 Apr 2023 21:05:13 -0500 Subject: [PATCH] initial import --- .gitignore | 3 ++ README.md | 69 +++++++++++++++++++++++++++++ argo1/Chart.lock | 6 +++ argo1/Chart.yaml | 13 ++++++ argo1/delete-crds.sh | 54 ++++++++++++++++++++++ argo1/install-crds.sh | 56 +++++++++++++++++++++++ argo1/templates/sealed-secrets.yaml | 33 ++++++++++++++ argo1/templates/secrets.yaml | 33 ++++++++++++++ argo1/templates/self.yaml | 30 +++++++++++++ argo1/values.yaml | 15 +++++++ install.sh | 25 +++++++++++ secrets/README.md | 18 ++++++++ secrets/sealed-secret.yaml | 22 +++++++++ secrets/secret.yaml | 14 ++++++ uninstall.sh | 18 ++++++++ 15 files changed, 409 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 argo1/Chart.lock create mode 100644 argo1/Chart.yaml create mode 100644 argo1/delete-crds.sh create mode 100644 argo1/install-crds.sh create mode 100644 argo1/templates/sealed-secrets.yaml create mode 100644 argo1/templates/secrets.yaml create mode 100644 argo1/templates/self.yaml create mode 100644 argo1/values.yaml create mode 100644 install.sh create mode 100644 secrets/README.md create mode 100644 secrets/sealed-secret.yaml create mode 100644 secrets/secret.yaml create mode 100644 uninstall.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d51becf --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +\#*# +*~ +charts/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..1cce922 --- /dev/null +++ b/README.md @@ -0,0 +1,69 @@ +# `argo1` + +#### A different opinionated opinion on how to bootstrap your ArgoCD + +This repo is a basic skeleton for managing your apps with ArgoCD. + +It uses helm to bootstrap and maintain the ArgoCD installation. You may +then add additional applications in argo1/templates either as helm charts +or as directories which should live alongside `argo1`. + +## Setup your own Argo1 + +1. Clone this repo as a template +2. If you will be using a private repo, configure a secret similar to secret.yaml + * You might also wish to use sealed secrets (via kubeseal). + * Check `secrets/` for more info on secrets and git repos. +3. update `argo1/values.yaml` + * At the very least, you will need to update the bootstrap.source.repoURL to + point to your clone -- this URL must match the prefix of the secret from + step 2, as well. + * You may configure the argo-cd helm template via the argo-cd map in values.yaml. + A basic example is available in the default values.yaml file which suppresses + installing the CRDs (which are instead installed via install-crds.sh) + +4. Install + ```bash + bash install.sh + ``` +5. all done! + +## App of Apps pattern + +This is already an app of apps. + +Add additional applications to `templates/`. These may reference Values or +they may be verbatim manifests (be careful of any `{{}}` in your manifests +though!) + +Do not modify (or be careful with) `1-self.yaml` which is the application which +references this repo to enable self-management. + +## Uninstalling + +```bash +bash uninstall.sh +``` + +## Adding an application + +An application is added to `argo1/templates` similarly to `sealed-secrets.yaml` for +a helm chart or similarly to `secrets.yaml` for a project colocated in this repo. + +Steps for adding an application: + - if helm chart, copy `argo1/templates/sealed-secrets.yaml` to a new file in the same folder + - if local manifests, copy `argo1/templates/secrets.yaml` to a new file in the same folder + - update the new file. at least the following will change: + - the key in `.Values` on line 1 + - `metadata.name` + - `spec.source` + +Applications which affect how secrets are loaded for Git repos must update the following +pre-bootstrap files: + - `argo1/install-crds.sh` + - `argo1/delete-crds.sh` + - `install.sh` + - `uninstall.sh` + + +[argo-crds]: https://argo-cd.readthedocs.io/en/stable/operator-manual/installation/ diff --git a/argo1/Chart.lock b/argo1/Chart.lock new file mode 100644 index 0000000..169a284 --- /dev/null +++ b/argo1/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: argo-cd + repository: https://argoproj.github.io/argo-helm + version: 5.29.1 +digest: sha256:bc009287f8e46edcddb1d36d4e6865080d92e97b6572ae2fd4d553d5e41cd2a2 +generated: "2023-04-23T21:03:44.445603-05:00" diff --git a/argo1/Chart.yaml b/argo1/Chart.yaml new file mode 100644 index 0000000..6e201dc --- /dev/null +++ b/argo1/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +name: argo1 +description: A Helm chart for your management ArgoCD of your management ArgoCD + +type: application +version: 0.1.0 +appVersion: &argoVersion |- + 5.29.1 + +dependencies: +- name: argo-cd + version: *argoVersion + repository: "https://argoproj.github.io/argo-helm" diff --git a/argo1/delete-crds.sh b/argo1/delete-crds.sh new file mode 100644 index 0000000..6572dba --- /dev/null +++ b/argo1/delete-crds.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +MAINDIR="$(dirname "$0")" +cd "$MAINDIR" + +application_chart_info() { + F="$1" + yq -o json . "$F" | jq -r ' + .spec.source + | ( + @sh "CHART=\(.chart)", + @sh "VERSION=\(.targetRevision)", + @sh "REPO=\(.repoURL)" + ) + ' +} + +dependency_chart_info() { + F="${1:-"$MAINDIR"/Chart.yaml}" + DEP="${2:-0}" + + yq -o json . "$F" | jq -r --argjson d "$DEP" ' + .dependencies[$d] + | ( + @sh "CHART=\(.name)", + @sh "VERSION=\(.version)", + @sh "REPO=\(.repository)" + ) + ' +} + +( + set -e + eval "$(dependency_chart_info)" + set -x + helm template argocd-crds --include-crds "$CHART" --repo "$REPO" --version "$VERSION" | yq 'select(.kind == "CustomResourceDefinition")' | kubectl delete -f - +) + +RC=$? +if [ $RC -ne 0 ];then + 1>&2 echo "error deleting ArgoCD CRDs" +fi + +( + set -e + eval "$(application_chart_info templates/sealed-secrets.yaml)" + set -x + helm template sealed-secrets-crds --include-crds "$CHART" --repo "$REPO" --version "$VERSION" | yq 'select(.kind == "CustomResourceDefinition")' | kubectl delete -f - +) + +RC=$? +if [ $RC -ne 0 ];then + 1>&2 echo "error deleting Sealed Secrets CRDs" +fi diff --git a/argo1/install-crds.sh b/argo1/install-crds.sh new file mode 100644 index 0000000..b534a79 --- /dev/null +++ b/argo1/install-crds.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +MAINDIR="$(dirname "$0")" +cd "$MAINDIR" + +application_chart_info() { + F="$1" + yq -o json . "$F" | jq -r ' + .spec.source + | ( + @sh "CHART=\(.chart)", + @sh "VERSION=\(.targetRevision)", + @sh "REPO=\(.repoURL)" + ) + ' +} + +dependency_chart_info() { + F="${1:-"$MAINDIR"/Chart.yaml}" + DEP="${2:-0}" + + yq -o json . "$F" | jq -r --argjson d "$DEP" ' + .dependencies[$d] + | ( + @sh "CHART=\(.name)", + @sh "VERSION=\(.version)", + @sh "REPO=\(.repository)" + ) + ' +} + +( + set -e + eval "$(dependency_chart_info)" + set -x + helm template argocd-crds --include-crds "$CHART" --repo "$REPO" --version "$VERSION" | yq 'select(.kind == "CustomResourceDefinition")' | kubectl apply -f - +) + +RC=$? +if [ $RC -ne 0 ];then + 1>&2 echo "exiting due to error creating ArgoCD CRDs" + exit $RC +fi + +( + set -e + eval "$(application_chart_info templates/sealed-secrets.yaml)" + set -x + helm template sealed-secrets-crds --include-crds "$CHART" --repo "$REPO" --version "$VERSION" | yq 'select(.kind == "CustomResourceDefinition")' | kubectl apply -f - +) + +RC=$? +if [ $RC -ne 0 ];then + 1>&2 echo "exiting due to error creating Sealed Secrets CRDs" + exit $RC +fi diff --git a/argo1/templates/sealed-secrets.yaml b/argo1/templates/sealed-secrets.yaml new file mode 100644 index 0000000..0ccf93e --- /dev/null +++ b/argo1/templates/sealed-secrets.yaml @@ -0,0 +1,33 @@ +# {{ if (index .Values "sealed-secrets").enabled -}} +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: "{{ .Release.Name }}-sealed-secrets" + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + chart: sealed-secrets + repoURL: https://bitnami-labs.github.io/sealed-secrets + targetRevision: 2.7.4 + helm: + releaseName: "sealed-secrets-controller" # required for kubeseal to work ezpz + destination: + server: "https://kubernetes.default.svc" + namespace: kube-system + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + retry: + limit: 10 + backoff: + duration: 5s + factor: 2 + maxDuration: 3m0s +# {{- end }} diff --git a/argo1/templates/secrets.yaml b/argo1/templates/secrets.yaml new file mode 100644 index 0000000..5fe6cb6 --- /dev/null +++ b/argo1/templates/secrets.yaml @@ -0,0 +1,33 @@ +{{ if (index .Values "secrets").enabled -}} +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: {{ .Release.Name }}-secrets + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + path: secrets + repoURL: "{{ .Values.bootstrap.source.repoURL }}" + targetRevision: "{{ .Values.bootstrap.source.targetRevision }}" + directory: + recurse: true + include: '*.yaml' + destination: + server: "https://kubernetes.default.svc" + namespace: argocd + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + retry: + limit: 10 + backoff: + duration: 5s + factor: 2 + maxDuration: 3m0s +{{- end }} diff --git a/argo1/templates/self.yaml b/argo1/templates/self.yaml new file mode 100644 index 0000000..676e401 --- /dev/null +++ b/argo1/templates/self.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: "{{ .Release.Name }}" + namespace: "{{ .Release.Namespace }}" + # DO NOT place the resource finalizer here. Since this is ArgoCD itself, it + # will never be able to finalize itself since it will have to delete itself + # before removing the finalizer. +spec: + project: default + source: + repoURL: "{{.Values.bootstrap.source.repoURL}}" + targetRevision: "{{.Values.bootstrap.source.targetRevision}}" + path: argo1 + destination: + namespace: "{{ .Release.Namespace }}" + name: in-cluster + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + retry: + limit: 10 + backoff: + duration: 5s + factor: 2 + maxDuration: 3m0s diff --git a/argo1/values.yaml b/argo1/values.yaml new file mode 100644 index 0000000..a671162 --- /dev/null +++ b/argo1/values.yaml @@ -0,0 +1,15 @@ +bootstrap: + source: + repoURL: "https://set.to.your.fork/of/this" + targetRevision: "main" + +secrets: {enabled: true} +sealed-secrets: {enabled: true} + +argo-cd: + crds: + install: false + + configs: + params: + "server.insecure": "true" diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..e736b29 --- /dev/null +++ b/install.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +cd "$(dirname "$0")/argo1" + +TARGETNS="argocd" +ORIGNS="$(kubectl config view --minify -o jsonpath='{..namespace}')" + +( + set -e + + 1>&2 echo "creating namespace if it doesn't exist" + jq -n --args '{"apiVersion":"v1","kind":"Namespace","metadata":{"name": $ARGS.positional[0]}}' "$TARGETNS" | kubectl apply -f - + + [ x"$TARGETNS" != x"$ORIGNS" ] && kubectl config set-context --current --namespace $TARGETNS + helm dependency build + bash install-crds.sh + helm install -n "$TARGETNS" argo1 . + kubectl apply -f ../secrets + kubectl wait -n $TARGETNS deploy/argo1-argocd-server --for=condition=available + until argocd --core app sync argo1-sealed-secrets;do sleep 1;done + until argocd --core app sync argo1-secrets;do sleep 1;done + until argocd --core app sync argo1;do sleep 1;done +) + +[ x"$TARGETNS" != x"$ORIGNS" ] && kubectl config set-context --current --namespace "$ORIGNS" diff --git a/secrets/README.md b/secrets/README.md new file mode 100644 index 0000000..8bfb11f --- /dev/null +++ b/secrets/README.md @@ -0,0 +1,18 @@ +Secrets. + +Any manifests in this folder ending in .yaml will be installed. + +It is recommended that SealedSecrets or similar are used to +avoid directly including secrets in your Git repo. + +For example, the sample secret may be modified and then sealed. + +```bash +cp git-creds-plain.yaml.sample git-creds-plain.yaml +vi git-creds-plain.yaml +kubeseal -o yaml < git-creds-plain.yaml > git-creds.yaml +rm git-creds-plain.yaml +git add git-creds.yaml +git commit -m 'add git-creds sealed secret' +git push +``` diff --git a/secrets/sealed-secret.yaml b/secrets/sealed-secret.yaml new file mode 100644 index 0000000..2bbdb38 --- /dev/null +++ b/secrets/sealed-secret.yaml @@ -0,0 +1,22 @@ +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + creationTimestamp: null + name: local-git-token + namespace: argocd +spec: + encryptedData: + password: AgAlNckjIJjOhBKYA54pngBa50DagQ6BtT0I9vvjyhbwBV62efdfnIrRcPSUzrXzSnCMrJPFCYyGZQwHCe7+MurVLPX+i94bBDFjZlGwP7kokaMQjTi4122nWbM0y9AGrYQUtDV3KodRdUkhRP8aAuhqtbzOjqSKB96xHc9EzUKupwrhs7iymbY50d5b7FVxvCBWL0ZzctIwlZU7o2OQ46ImmrAo/0Hn1ueI2wsuhSjg4a4xsh1GipVsRWTCuLO5Ot0eDOgEqQEhTQji5+uwOy4iCuYnj+UHlNodClGsn9MsRv4dIZhCt8kapKKTv4PdQNKSq9JjefgPjyXJs7Za5xTOj07KSsOHdrOQOBNzbf2piaKiGt3p1e8/NhdhB4ODpxbW973y/2ErR4xcf+hpCKQ8CqffNIYEvcRs+NcZAq0afaHQymWTjzqRgYjtceDp8gNIUbQxD5WRlbvaxRwgDWfe4aSrp/cRw7JbwkcOEQGfjGNJr15PmYO7jT8yb8ZJNavUG9KK4tCio8j2nCC7OZECewWr1vj/FLquYvD6AYeKMHKgfL2eRdxcqTwbXIoWXAP6JeWF1oN97xN0TANPljf+Pyt89D73BHMDVuQ1Ei2528y7JZy6xir7C3PoDRBBbSX0imMmHFCngSwtbGYMKdRfbxJ7rG+aamYGo6LUfqArrpnXDGPe4ti/FIp/fUKjYs7azT1f+Ntwfg== + project: AgCaMGRFcW9LaVW8M5dLLwpEGEAnbwXgHZzBWkgkc804rL9lKNuu6L40l0QmZizziEf14u3MdVh5VecHo9julJgMQNaArWIwOLRGR3vcETcYdYHjMmQwUT+TO7GwY7xJZCAxEKMoQrM74ha+wgT2uWMn0uEOFTkobTQfnWLoTlXZcspIWFcTNhdgZeJKAqZMKIt7yE1CF0AjMy+7XWDAGHOByyWllpZSHp2wh78fuaK0tLGzY50+NmwE44cft6lATSh5a/Ko1UL+1uCDeMRvrs2cR5+1Zh9MNWbXHKCggyM81vojf831p58dfJ3yPzXJTWLADZ/k2o3liWvY43W5mp/C4my9wUYR9JRXFsByvbvtu+7vvdhFV2YLEPErKvJAVv66R/r+6u3YQTAAtz8iAHaxLtEn9Tj91b+iBeCqZnnChqfRF4Ts2XZvSmwH6O1V8k6Lv1s9ULYN7lDesvO0W4vbkO01P72vaPgjWYgDLkxeWrnEx5jQM9jPs29U9NaCiiWxnHxReGN87WklCA0Gsb5eyXmbXoh50qICx26Cf2TUqbrVGyMPT0pEJdavXpX7mgQDohP9iAy9ALGFicUmZ8gDH9DeadtqkHT8UgGWWoAGroTMulRCWK1v+plVfRJkfrtw3AXmWTegkNFYX8lYjyAHJokMOEpF4OjL1By2XngfwAnd2eAiSWtU1cPL1Jjv2NCYDR5ZlHXu + type: AgBWOyU8137TFCt3kJC2WJV3gXlBQEirknbHVmS3IDcxwmyhuIxZh5NeLbDfc7Ip9OEtGQFViBD523gUzr3qJRZBE0IAWplF98+NwRopT3jVjxRCt8H6yF8+/3EiagUBe/9WM/eb5+S428KMDT7eDn9PiB6pEjoduxD5w/l+QDBUQQOoejc98bzxjC8ml8EpkaMS4H4yiO7JAlW2QYFRyF1fFaopoEdwyIEkPJ5Br/TXDOtdJeCEIhUhNKE+wQmNZc7MBJKWiqGyb54HzdsAndmF2PQs1FZ+sUCn0xJtu1pP8WTpcKGm4VpHPASlDNQgpuNFBvkYRGe+MErAmqyrAs0E5VU3R0qoIkmbhuvXY+gOploJ2YljG5gqLUx8DtECoSmkrF92oQZx61Yf4duvE/mEciWcDRThzUXwrG8A+qj8B/JxomoEQB4xu/l3WgNBOPMonF77b2dpTckBfH9VH70QKygbMTGAj7zl/sZDavPMZq37SCqNTmRhcDBs1qt3wtv8sUy6F4RUmr6XZsOtePxGg+WYijeHpXXeQSu7oASiZgUcNnjIPFPLc64IXoUv3s4a/QiSGRCgz8uUqws6QSu+TggY4P7f8VBOrJATv4jbOc++XGgWe0o/+b9oQACn5qPrdCkR4hiGd5wZ1BQXVINK5FMXCJq3l4kIjxDdKC6TjfG4vhi2VLld5eAz6f9cNphrocM= + url: AgAk92yrw8BJX0rVsCkZOEz3PhkLMoNhKBOXEAGqlcH+AESKIKUH152fMcfFKNj3DBrOEaNGXM+HiM1DLCd+e4A46ytx/aqSF4uEno2853wLlHjlLQlqfSWdkMYwosSV11Y9MuMGhGTMyCB/u10QUIycUjBs/gZEHDrJV/ObJYtw1pIlMadeKG5nomYYoOiMArdKZ1EXqv010imTItAhrW+Xn4h7/GftCEm2vWPbCdTbFBNIirif2DIAge7kTM3NeLzeLdAqf+tM7+A2Ekw7lU6+bnuVGGNWzEbQI/e4soSGYATQqVdhRPD/UFRJJrmp6IFZ2ymgqKr7t7EbTJ8UKr+GiMP2Gy/9ihBe3cDiQuVEfj791yHMSfChkIQ4vDYzJjMueYJE5pAz04y6QMbqgDxfVaQlx1B2XTP2ma3W+9bMB8vrDCuqK5iWtfM1jSmLVnM10KCsxcQAraE6C8jOArpkUqMPzsCmIfAudEe8FUxv56EeOP0MVT7sHLDKjklxqfgFCzzeqpGAZOP+k8zLT89vXlqbgeUWl3VmXMRqheDmhS6v8YiwJhkusvEdMeC8GOukvXM5limKC/+SZDIUNLlf0wct8/ymi0nkkmcGsfI2Jl7M5ZyOrjjXfvMLeNhc/vE+atXeKIXy8NLoDM0UwjyvMiO2mOpx3ZUwu2M5ff2i9n3rpxevYTh+fpOLWz2CXpLkMzvIm8wIgOow/4mWWYuY1Oqg + username: AgCIo+y2uwCJVEfnLl8wwTKLyw10rMfpJExCHcXq7dBlYWit2tG/uBQr6SM0jqlRINoe0jSNcaVUuzdRZWjvRwW7fwRonz2rjFih9wdmCXYhSc5K4qF5FeB8mO7tmOW+CzILUviZfqnqTyYLzd66BV2etCusuGHPBGomOYsaELYLMzQmpKPLt7an4PP8dUAM09aCeKe0KkTwQcgCkNRKBPRysg1mXnulCpGgWdUDGsj5QCM3byp2+l45g+/RDvELZgnkRjzVNNnXK9AI4Xy3vekDMoNEuFX3A+YWoBwI6LRSRWFOy5hi6w596PrvCq/O4FEomIsFqk9jkBY7dEVXsUX6JKVpIxkwtlKSChO3rt558YGipamt1csNKstM7frgtkzfXoNB7jQiKzHULeimtZnUOSjI8TaboeBKKKLHfrlbIWrJBHD1xJ3kuYCM/O7dpHM5aGBOwPSbjc72ur9Lso/uDs/ZvibsYkuaIBnP+Y8rj+t2d6cFe8//W4zcC90L+0Gnxn1/rLyuAp+B92bb13yq7sY50la2zu7zmvsL41/V4NYErgAUMciT2bSZMvSNh6wtx2IhCyJJSByDbsUMth7ixzfbuK8bgIeoyS3L3V17pB90YI9ttGNLmZ5zJLXzIhejD817EpnrIXHBQqjl0fNpxRgwJw2rmAH8fkKxSbsdT+hX3BORI/LUmFMuXuWhsarwbjTXmVHUV5qvbX0= + template: + metadata: + creationTimestamp: null + labels: + argocd.argoproj.io/secret-type: repo-creds + name: local-git-token + namespace: argocd + type: Opaque + diff --git a/secrets/secret.yaml b/secrets/secret.yaml new file mode 100644 index 0000000..db11e45 --- /dev/null +++ b/secrets/secret.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +stringData: + password: password + project: default + type: git + url: https://github.com/ + username: bobtedsmithy +kind: Secret +metadata: + labels: + argocd.argoproj.io/secret-type: repo-creds + name: local-git-token + namespace: argocd +type: Opaque diff --git a/uninstall.sh b/uninstall.sh new file mode 100644 index 0000000..7ee2670 --- /dev/null +++ b/uninstall.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +cd "$(dirname "$0")/argo1" + +TARGETNS="argocd" +ORIGNS="$(kubectl config view --minify -o jsonpath='{..namespace}')" + +( + set -e + + [ x"$TARGETNS" != x"$ORIGNS" ] && kubectl config set-context --current --namespace $TARGETNS + argocd --core app set argo1 --helm-set sealed-secrets.enabled=false --helm-set secrets.enabled=false + argocd --core app sync argo1 || argocd --core app wait --sync argo1 + helm uninstall -n "$TARGETNS" argo1 + bash delete-crds.sh +) + +[ x"$TARGETNS" != x"$ORIGNS" ] && kubectl config set-context --current --namespace "$ORIGNS"