Sitemap

Platform Engineering Starter Kit Series: GitOps Bootstrap with Argo CD (3)

5 min readAug 20, 2025

In Post 1 we set up our workstation and baseline repo, and in Post 2 we scaffolded Terraform modules, bootstrapped a GKE cluster, and added a Makefile for repeatable workflows.

Now we’ll introduce GitOps — the practice of managing infrastructure and application deployments entirely from Git.

By the end of this post, you’ll have:

  • Argo CD running in your GKE cluster
  • A GitOps “app-of-apps” setup to manage your platform components from Git

0. Starting Point

If you finished Post 2:

git checkout -b post-03-argo-cd-gitops

If you skipped Post 2, you can start from its branch:

git clone -b post-02-repo-scaffolding-infra https://github.com/JiminByun0101/platform-starter-kit.git
cd platform-starter-kit
git checkout -b post-03-gitops-bootstrap

Make sure your GKE dev cluster is running:

make kubeconfig
kubectl get nodes

If you destroyed the cluster after Post 2, run make apply before make kubeconfig.

1. Why GitOps + Argo CD?

Traditional CI/CD pushes code directly into your cluster, often from your pipeline.
With GitOps, the cluster pulls its desired state from Git. Argo CD watches your Git repo and applies changes automatically, ensuring:

  • Version-controlled deployments: Rollback to any Git commit
  • Cluster state drift detection: See if something changed outside Git
  • Self-healing: Argo CD syncs the cluster back to the declared state

In our platform, we’ll:

  • Deploy Argo CD via Helm
  • Store Argo CD “Application” manifests in argocd/
  • Use an “app-of-apps” pattern so new services can be added by just creating a new manifest in Git

2. Repo Layout Update

We’ll add an argocd/ folder for GitOps manifests and a Helm chart for Argo CD itself:

platform-starter-kit/
├── argocd/
│ ├── apps/ # App-of-apps children
│ │ ├── platform-monitoring.yaml
│ │ └── sample-app.yaml
│ └── root-app.yaml # The root Argo CD app-of-apps
├── helm/
│ └── argocd/ # Helm chart for Argo CD
│ ├── values.yaml
│ └── Chart.yaml

3. Create Argo CD Values File

mkdir -p helm/argocd

cat > helm/argocd/values.yaml <<'EOF'
global:
image:
tag: v3.0.12 # Pin Argo CD app version for reproducibility

server:
service:
type: ClusterIP # Avoid external LB cost until Post 4
ingress:
enabled: false

configs:
params:
server.insecure: true # For local/dev use only
EOF

4. Install Argo CD via Helm

4.1 Create Namespace

kubectl create namespace argocd

4.2 Add Argo CD Helm Repo

helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

4.3 Helm Install (Initial)

We’ll keep the config minimal here — later posts will customize authentication, RBAC, and ingress.

helm upgrade --install argocd argo/argo-cd \
--namespace argocd \
--version 8.2.7 \
-f helm/argocd/values.yaml

4.4 Verify Installation

Run through these checks to confirm Argo CD is up and running:

4.4.1 Check pods are running

kubectl get pods -n argocd

All pods should be Running (or Completed for init jobs).

4.4.2. Port-forward to access the UI
We set server.insecure: true for dev, so forward port 80:

kubectl -n argocd port-forward svc/argocd-server 8080:80

Open https://localhost:8080 and accept the certificate warning.

4.4.3. Get the initial admin password

kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d; echo

Login with:

Username: admin
Password: <output above>

Once logged in, open the left menu and click Applications — it should be empty. That’s expected; we’ll add it next.

In Argo CD, Applications are definitions telling Argo CD what to deploy (e.g., a Helm chart or Kubernetes manifests) and where to deploy it.
Right after installation, it will be empty because Argo CD isn’t yet linked to any Git repository — we’ll do that by applying our root application in the next step.

Press enter or click to view image in full size
Applications

5. Define the Root App (App-of-Apps Pattern)

The root application tells Argo CD where to find all your other apps.
It’s the only app you install manually — everything else is managed by Git.

platform-starter-kit/argocd/root-app.yaml

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/<your-username>/platform-starter-kit.git
targetRevision: post-03-gitops-bootstrap # Temporary branch for this post
path: argocd/apps
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true

Note: We set targetRevision to the branch for this post (post-03-gitops-bootstrap) so that Argo CD only syncs what’s ready at this stage of the series. After the series is complete and merged to main, change this to main (or HEAD).

Push the branch now so Argo CD can see it:

git add .
git commit -m "Post 03: Add helm values.yaml for Argo CD and its root app"
git push -u origin post-03-gitops-bootstrap

Once pushed, we can apply it in Step 7 and verify it appears in the Argo CD UI.

You can also view the full code for this post on GitHub: Post 3 branch on GitHub

6. Add a placeholder Child App

We’ll create a dummy application manifest so that the root app has something to display in Argo CD.
This one is for a future platform monitoring stack (Prometheus, Grafana, Loki), which we’ll fully implement with a Helm chart in Post 5.
For now, it’s only here to demonstrate the app-of-apps pattern and avoid errors about a missing argocd/apps path.

platform-starter-kit/argocd/apps/platform-monitoring.yaml

mkdir -p argocd/apps

cat > argocd/apps/platform-monitoring.yaml <<'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: platform-monitoring
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/<your-username>/platform-starter-kit.git
targetRevision: post-03-gitops-bootstrap
path: helm/platform-monitoring # will exist in Post 5
destination:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
automated:
prune: true
selfHeal: true
EOF

git add argocd/apps/platform-monitoring.yaml
git commit -m "Post 03: add placeholder child app"
git push -u origin post-03-gitops-bootstrap

7. Bootstrap the GitOps Root App

Once Argo CD is installed:

kubectl apply -f argocd/root-app.yaml

Argo CD will see the argocd/apps folder in your repo and deploy all child apps.

Verify in Argo CD UI

  1. Access the Argo CD UI
kubectl -n argocd port-forward svc/argocd-server 8080:80

Open https://localhost:8080, Login with admin and the password from step 4.4.

2. Check Applications page

  • You should now see root-app listed.
  • Status should be:
    - Synced (green check) if it successfully pulled from the repo.
    - Healthy (green heart) if all child apps are in a good state.
  • If you’ve created the placeholder platform-monitoring app (Step 6), it will also appear here.
    Its status will likely be Unknown because we haven’t created the helm/platform-monitoring chart yet. This is expected and will be resolved in Post 5.
Press enter or click to view image in full size

8. Cost & Cleanup Warning

Argo CD’s footprint is small, but your GKE cluster still incurs costs.
If you’re pausing work:

make destroy

Next in the Series

In Post 4, we’ll:

  • Secure Argo CD with HTTPS via Ingress + Cert-Manager
  • Add SSO authentication
  • Organize platform components into separate Argo CD Projects

--

--

Jimin
Jimin

Written by Jimin

DevOps engineer and tech enthusiast. Sharing tech insights to simplify the complex. Let's connect on LinkedIn! https://www.linkedin.com/in/byun-jimin/

No responses yet