Initial commit: GitOps Starter Pack
A teaching-first, single-cluster GitOps setup: Talos Linux + Argo CD with an app-of-apps layout, MetalLB pre-installed for real LoadBalancer IPs on bare metal, a demo app, and a progressive docs/ walkthrough with a CLAUDE.md tutor persona and guided bootstrap checklist. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
# Installing Argo CD — command reference
|
||||
|
||||
Companion to [`docs/03-installing-argocd.md`](../docs/03-installing-argocd.md)
|
||||
and [`docs/04-app-of-apps.md`](../docs/04-app-of-apps.md). Read those for the
|
||||
why; this is the exact commands.
|
||||
|
||||
Run these once `kubectl get nodes` shows your node `Ready` (see
|
||||
[`talos/README.md`](../talos/README.md)).
|
||||
|
||||
## 1. Install Argo CD
|
||||
|
||||
```sh
|
||||
kubectl create namespace argocd
|
||||
kubectl apply --server-side -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
|
||||
```
|
||||
|
||||
`--server-side` matters here, not just as a nice-to-have: one of Argo CD's
|
||||
CRDs (`applicationsets.argoproj.io`) is large enough that a normal
|
||||
(client-side) `kubectl apply` fails outright — it tries to stash the whole
|
||||
manifest into an annotation for its 3-way-merge bookkeeping, and that
|
||||
annotation hits Kubernetes' size limit. Server-side apply has the API
|
||||
server do that diffing instead, so this limit doesn't apply.
|
||||
|
||||
This is an **imperative** install: a plain `kubectl apply` of a manifest
|
||||
bundle that the Argo CD project maintains, rather than a Helm chart or
|
||||
operator. It's the officially documented quickstart path, and it means
|
||||
Argo CD itself isn't part of your GitOps loop — you install it once, by
|
||||
hand, and *it* then manages everything else declaratively. Bootstrapping
|
||||
has to start somewhere outside the loop; this is that starting point.
|
||||
|
||||
The `stable` in that URL is a moving tag maintained by the Argo CD project
|
||||
that always points at the latest stable release — convenient here, but not
|
||||
reproducible: what it installs today may differ from what it installs in
|
||||
six months. For a production setup, pin an explicit version instead, e.g.
|
||||
`.../v2.13.0/manifests/install.yaml` — see [releases](https://github.com/argoproj/argo-cd/releases)
|
||||
for current tags.
|
||||
|
||||
Wait for everything to come up:
|
||||
|
||||
```sh
|
||||
kubectl -n argocd wait --for=condition=Available --timeout=300s deployment --all
|
||||
```
|
||||
|
||||
## 2. Get the initial admin password
|
||||
|
||||
```sh
|
||||
kubectl -n argocd get secret argocd-initial-admin-secret \
|
||||
-o jsonpath="{.data.password}" | base64 -d; echo
|
||||
```
|
||||
|
||||
This secret is auto-generated on first install. Save the password
|
||||
somewhere; you'll change it in a moment.
|
||||
|
||||
## 3. Reach the UI and CLI
|
||||
|
||||
Argo CD doesn't expose itself outside the cluster by default. For this
|
||||
learning setup, forward its port to your machine:
|
||||
|
||||
```sh
|
||||
kubectl -n argocd port-forward svc/argocd-server 8080:443
|
||||
```
|
||||
|
||||
Leave that running in its own terminal. In another terminal:
|
||||
|
||||
```sh
|
||||
argocd login localhost:8080 --username admin --password <password-from-above> --insecure
|
||||
```
|
||||
|
||||
`--insecure` here means "skip TLS certificate verification" — the server's
|
||||
certificate is self-signed by default and there's nothing on the other end
|
||||
but your own port-forward, so this is fine for local access. It is **not**
|
||||
something to carry into a setup reachable over the real network.
|
||||
|
||||
Open `https://localhost:8080` in a browser to see the same thing visually.
|
||||
|
||||
Optional but recommended — replace the initial password:
|
||||
|
||||
```sh
|
||||
argocd account update-password
|
||||
```
|
||||
|
||||
## 4. Hand the cluster to Git
|
||||
|
||||
[`app-of-apps/app-of-apps.yaml`](app-of-apps/app-of-apps.yaml) is the one
|
||||
manifest in this whole repo you apply by hand — everything after it, Argo
|
||||
CD applies for you. First, every Application manifest needs its own
|
||||
`repoURL` pointed at your fork (they don't inherit it from each other):
|
||||
|
||||
```sh
|
||||
grep -rl YOUR_GITHUB_USERNAME .
|
||||
```
|
||||
|
||||
Edit `spec.source.repoURL` in each file that command finds, commit, and
|
||||
push — the child Applications are read from Git, not your local disk, so
|
||||
this has to land in your fork before the next step. Then:
|
||||
|
||||
```sh
|
||||
kubectl apply -f argocd/app-of-apps/app-of-apps.yaml
|
||||
```
|
||||
|
||||
Watch it take over:
|
||||
|
||||
```sh
|
||||
argocd app get app-of-apps
|
||||
argocd app list
|
||||
```
|
||||
|
||||
You should see `app-of-apps` sync, then `demo` and `metallb` Applications
|
||||
appear underneath it, then sync themselves. See
|
||||
[`docs/04-app-of-apps.md`](../docs/04-app-of-apps.md) for what's happening
|
||||
here and [`docs/checklist.md`](../docs/checklist.md) for the full guided
|
||||
path.
|
||||
|
||||
## 5. Give the UI a real address (MetalLB)
|
||||
|
||||
Once `metallb` (above) is `Synced`/`Healthy` and you've configured its
|
||||
address pool (see [`docs/05-metallb.md`](../docs/05-metallb.md)), you can
|
||||
retire the port-forward from step 3 and give Argo CD's UI a permanent
|
||||
address instead. This one change is applied directly, not through Git —
|
||||
Argo CD's own install isn't managed by this repo's GitOps loop:
|
||||
|
||||
```sh
|
||||
kubectl -n argocd patch svc argocd-server --type merge -p \
|
||||
'{"spec":{"type":"LoadBalancer"},"metadata":{"annotations":{"metallb.universe.tf/loadBalancerIPs":"<ARGOCD_IP>"}}}'
|
||||
```
|
||||
|
||||
```sh
|
||||
kubectl -n argocd get svc argocd-server
|
||||
```
|
||||
|
||||
Once `EXTERNAL-IP` shows your chosen address, `https://<that-address>`
|
||||
works directly, from any machine on your network — no port-forward
|
||||
required.
|
||||
@@ -0,0 +1,47 @@
|
||||
# The app-of-apps. This is the ONE manifest in this entire repo that you
|
||||
# apply by hand, one time, with `kubectl apply -f`. It's the seed: after
|
||||
# this exists, Argo CD takes over and everything else in the apps/ folder
|
||||
# gets applied automatically, because this Application's job is to watch
|
||||
# that folder.
|
||||
#
|
||||
# Before applying this file, edit spec.source.repoURL below to point at YOUR
|
||||
# fork of this repo (Argo CD needs to clone it, so it must be a real URL it
|
||||
# can reach — not this template's URL).
|
||||
#
|
||||
# >> Ask Claude: "why does the app-of-apps live in argocd/app-of-apps
|
||||
# instead of inside apps/ with everything else?" before moving on — the
|
||||
# answer (avoiding a directory managing itself) is worth understanding.
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: app-of-apps
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
|
||||
source:
|
||||
repoURL: https://github.com/YOUR_GITHUB_USERNAME/k8s-starter-pack.git
|
||||
targetRevision: main
|
||||
path: apps
|
||||
directory:
|
||||
# recurse: false is deliberate. apps/ contains both Application
|
||||
# manifests (apps/demo.yaml) AND subfolders full of the actual
|
||||
# workload manifests they point to (apps/demo/*.yaml). Without this,
|
||||
# Argo CD would try to apply everything inside apps/demo/ directly
|
||||
# under the app-of-apps too — duplicating work the demo Application
|
||||
# already does, and blurring which Application actually owns what.
|
||||
# recurse: false means "only look at files directly in apps/, ignore
|
||||
# subfolders" — so the app-of-apps only ever sees the Application
|
||||
# manifests, never the workloads themselves.
|
||||
recurse: false
|
||||
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: argocd
|
||||
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
Reference in New Issue
Block a user