Module 12 · Operate with teams · 35 min · You are: Platform and product
How product teams work with Argo CD
In this module
- You learn: The agreement between the platform team and a product team: who owns which repo and file, how a team deploys and rolls back, how it investigates a problem on its own, and when it asks for help.
- You do: Add the operating model and review rules (CODEOWNERS) to the platform repo. Ship a chart release to dev as team-checkout, inspect it with the team\'s own login, then roll it back with a revert.
- You end with: The platform repo documents the rules and enforces who reviews what. You have run a full release and rollback as team-checkout, and dev is back on the release it started with.
Tools do not make an operating model; agreements do. Everything is in place: projects, accounts, three repos. This module makes the rules explicit, adds review rules that enforce them, and runs a release and a rollback as team-checkout from start to end.
Open this module in the interactive course to track progress and switch tracks.
GitOps loop practised: Committed → Reviewed → Detected → Rendered → Compared → Synced → Healthy → Observed
Concepts
- What teams own
- Their chart, their values, their secrets, their releases and rollbacks. Inside their project, they need nobody.
- What the platform owns
- Argo CD, projects, namespaces, RBAC, repo credentials, add-ons. Teams propose; the platform reviews.
- How teams deploy
- A pull request to
checkout-config(versions, values) or toapps/checkout-*.yaml(chart release), reviewed through CODEOWNERS. - How teams inspect
- Read-only in Argo CD for their apps: status, diff, history, logs, events. Write access is Git.
- When to escalate
- When the fix is outside their repos: permissions, credentials, add-ons, Argo CD itself.
Ownership
| Thing | Platform team | team-checkout |
|---|---|---|
| Argo CD install, upgrades, exposure, SSO, RBAC | Owns | Uses |
| AppProject, namespaces, quotas | Owns | Requests by pull request |
| Repository credentials | Seals and commits | Adds the deploy key to its repo |
apps/checkout-*.yaml | Reviews | Proposes (CODEOWNERS) |
Chart (checkout-app) | Owns, releases by tag | |
Values and secrets (checkout-config) | Owns | |
| Sync, refresh, rollback | Can | Can, in its project |
When team-checkout escalates
| Symptom | Team first | Escalate when |
|---|---|---|
| OutOfSync, sync failed on my manifests | Fix or revert in my repo | Never: it is ours |
| Degraded, failed hook | Logs, events, revert | Never: it is ours |
not permitted in project | Check I deploy only into my namespaces | I need a new kind or destination |
permission denied | Check I am logged in as myself | My role is wrong |
Repo Failed, authentication | Check the deploy key is on my repo | The credential in Argo CD must change |
| Every app Unknown, UI down | Nothing | Immediately |
Files to know
Open them in your editor or on GitHub; the bullets say what to look at.
docs/operating-model.md(reference): The contract, written down. Copy it into your platform repo.platform/.github/CODEOWNERS(reference): The review rules that enforce it.- The team approves its own chart bumps; the platform owns the rest L4
Steps
1. Write the contract into the platform repo
Copy the operating model and the review rules. In an organisation, replace @YOUR_GITHUB_USER with team handles (@acme/platform, @acme/team-checkout) and require code-owner review in branch protection.
Copy the two documents: who owns what, and how to debug:
cd ~/work/argocd-platform && git switch -q main && git pull -q
mkdir -p docs && cp ~/work/argocd-gitops/docs/operating-model.md ~/work/argocd-gitops/docs/debugging.md docs/
Copy the review rules. CODEOWNERS tells GitHub who must approve a change to which file. Your GitHub user replaces the placeholder.
cp ~/work/argocd-gitops/platform/.github/CODEOWNERS .github/ && perl -pi -e 's/YOUR_GITHUB_USER/YOUR_GITHUB_USER/g' .github/CODEOWNERS
git add -A && git commit -qm "Operating model and review rules" && git push -q
2. team-checkout ships a release, end to end
As the team: a new chart release, then a pull request bumping dev to it. Watch it as checkout-dev, not as admin.
cd ~/work/checkout-app && git switch -q main && git pull -q
Change in ~/work/checkout-app/chart/Chart.yaml
- version: 1.0.0
+ version: 1.1.0
Release it. Commit and push the new chart version:
git commit -qam "checkout chart 1.1.0" && git push -q
Then tag that commit as the release v1.1.0 and push the tag:
git tag v1.1.0 && git push -q origin v1.1.0
Now the platform repo: point dev at the new release.
cd ~/work/argocd-platform && git switch -q main && git pull -q
Change in ~/work/argocd-platform/apps/checkout-dev.yaml
- targetRevision: v1.0.0 # a release of the chart
+ targetRevision: v1.1.0 # a release of the chart
git add -A && git commit -qm "checkout-dev: chart v1.1.0" && git push -q
Watch it as the team, not as admin:
argocd login argocd.localtest.me:8443 --grpc-web --insecure --username checkout-dev --password 'another-long-one'
argocd app get checkout-dev --refresh >/dev/null
argocd app wait checkout-dev --sync --health --timeout 240
3. Inspect like a product team
Everything team-checkout needs to answer "what is running and is it OK", without kubectl.
Is it OK? Expect Synced and Healthy, and the chart source at v1.1.0.
argocd app get checkout-dev
What was deployed, and when? The newest row is the release you just shipped.
argocd app history checkout-dev
Is anything waiting to be applied? Expect no diff output, and exit code 0 (the number means: nothing to apply).
argocd app diff checkout-dev; echo "diff exit: $?"
What objects does it own? Expect the Deployment, Service, ConfigMap and the rest, each Synced.
argocd app resources checkout-dev
What is it saying? The last five log lines, without kubectl:
argocd app logs checkout-dev --tail 5
4. Roll back with a revert, not the button
The release is unwanted. Revert the pull request. The UI rollback refuses to run while auto-sync is on, and turning auto-sync off to use it would leave Git saying something else than the cluster.
Try the rollback command first. Expect a refusal that mentions auto-sync:
argocd app rollback checkout-dev 2>&1 | tail -1
Log back in as alice, then undo the release the Git way:
argocd login argocd.localtest.me:8443 --grpc-web --insecure --username alice --password 'choose-a-long-one'
cd ~/work/argocd-platform && git switch -q main && git pull -q
git revert --no-edit HEAD && git push -q
Wait until dev is back on the earlier release and healthy:
argocd app get checkout-dev --refresh >/dev/null
argocd app wait checkout-dev --sync --health
Break it on purpose: Test in prod from a branch
team-checkout wants to try a chart change in prod "just for an hour". The team pushes a branch and, through a pull request it may approve itself, points checkout-prod at the branch instead of a release.
You practise: spotting an Application that follows a branch, why that turns every push into a deploy, and enforcing the contract with a check instead of trust.
1. Break it
cd ~/work/checkout-app && git switch -q main && git pull -q
git switch -c try-it
Change in ~/work/checkout-app/chart/values.yaml
- progressDeadlineSeconds: 120 # report a failed rollout after 2 minutes
+ progressDeadlineSeconds: 90 # report a failed rollout after 2 minutes
git commit -qam "try a shorter deadline" && git push -qu origin try-it
cd ~/work/argocd-platform && git switch -q main && git pull -q
Change in ~/work/argocd-platform/apps/checkout-prod.yaml
- targetRevision: v1.0.0 # a release of the chart
+ targetRevision: try-it # a release of the chart
git add -A && git commit -qm "checkout-prod: try a branch" && git push -q
argocd app get root --refresh >/dev/null; sleep 30
2. What you see
The check passed and the pull request merged. argocd app get checkout-prod shows the chart source at try-it, and prod runs the branch: kubectl -n checkout-prod get deploy checkout -o jsonpath='{.spec.progressDeadlineSeconds}' prints 90. Expected: prod only ever runs a release. From now on, every push to try-it deploys to prod with no review.
3. Fix it yourself
Put prod back on release v1.0.0 and delete the branch. Then change the platform repo's check so that a pull request like this one fails: the chart source of every Application must use a release tag like v1.2.3.
Hint 1
Undo the pull request the way you undo every change. The check lives in scripts/validate.sh and already looks at every Application.
Hint 2
Inside the if kind == "Application": block, loop over spec.get("sources", []) and fail when a source with path: chart has a targetRevision that does not match v\d+\.\d+\.\d+. Try it on the bad file before you ship it.
The fix
cd ~/work/argocd-platform && git switch -q main && git pull -q
git revert --no-edit HEAD && git push -q
Delete the branch:
git -C ~/work/checkout-app push -q origin --delete try-it
cd ~/work/argocd-platform && git switch -q main && git pull -q
Change in ~/work/argocd-platform/scripts/validate.sh
- import glob, sys, yaml
+ import glob, re, sys, yaml
Add to ~/work/argocd-platform/scripts/validate.sh inside if kind == "Application":, after the YOUR_GITHUB_USER check, at the same indentation
for src in spec.get("sources", []):
rev = str(src.get("targetRevision", ""))
if src.get("path") == "chart" and not re.fullmatch(r"v\d+\.\d+\.\d+", rev):
print(f"FAIL {f}: chart source must be a release tag like v1.2.3, not {rev}"); bad += 1
Prove it catches the bad change: point checkout-prod at the branch again, in your editor only, and run the check.
Change in ~/work/argocd-platform/apps/checkout-prod.yaml
- targetRevision: v1.0.0 # a release of the chart
+ targetRevision: try-it # a release of the chart
Expect a FAIL apps/checkout-prod.yaml line saying the chart source must be a release tag like v1.2.3, not try-it:
scripts/validate.sh
Undo that edit, check again, and ship the check:
Change in ~/work/argocd-platform/apps/checkout-prod.yaml
- targetRevision: try-it # a release of the chart
+ targetRevision: v1.0.0 # a release of the chart
scripts/validate.sh
Ship the check:
git add -A && git commit -qm "CI: chart sources must use release tags" && git push -q
After you fixed it: the five questions
- What failed?
- A product Application followed a branch, so unreviewed commits reached prod.
- How was it detected?
- Only by reading the Application or the running config: everything stayed Synced and Healthy.
- Who responds?
- team-checkout reverts; the platform team owns the check that prevents it.
- How is it corrected?
- Revert the pull request, delete the branch, and add a check that chart sources use release tags.
- How is it prevented?
- Contracts that matter are enforced by checks in CI, not by trust. Self-approval through CODEOWNERS is fine once the check guards it.
Quiz
- team-checkout wants to run a new chart release in dev. Which change?
- A pull request changing targetRevision in apps/checkout-dev.yaml, which they can approve through CODEOWNERS
- Edit the Application in the UI and click sync, which leaves an entry in the audit log and needs no review from anyone else on the platform
- Ask the platform team to create a new AppProject for dev, then point the team's Application at it so that the release can be rolled out
- Why is the Argo CD rollback button the wrong rollback here?
- It is slower than a revert and takes longer to bring the old version back, since it has to rebuild every object of the application first
- It refuses while auto-sync is on, and turning auto-sync off leaves Git disagreeing with the cluster
- It deletes the Application and all of its resources, so everything has to be created again from Git before the old version is back
- team-checkout sees
authentication requiredon its apps. Who acts first?- The platform team acts first, rotating every deploy key and sealed credential on the cluster, because they own all of the repository access
- Nobody yet: wait until the error clears by itself when Argo CD retries the repository, which it normally does within a few minutes
- team-checkout checks its deploy key is still on the repo, and escalates if the credential in Argo CD must change
Answers
- A pull request changing targetRevision in apps/checkout-dev.yaml, which they can approve through CODEOWNERS Teams own their releases; the platform repo's review rules let them approve their own files.
- It refuses while auto-sync is on, and turning auto-sync off leaves Git disagreeing with the cluster Revert in Git: one record, one source of truth.
- team-checkout checks its deploy key is still on the repo, and escalates if the credential in Argo CD must change The key lives on the team's repo; the sealed credential is the platform's.
Field note
The best platform teams I have worked with measure one thing here: how often a product team has to ask them for something. Every escalation in the table above is a candidate for self-service later.