Consolidates the five cogarchhubgitops-* source skills into one skill with scope routing: ArgoCD Applications, Copier templates, Helm values, environment answer files, and the end-to-end resource-addition walkthrough. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
162 lines
5.7 KiB
Markdown
162 lines
5.7 KiB
Markdown
# CogArchHubGitOps — Reference Implementation
|
||
|
||
The concrete instance of every pattern in this skill. Read when working in
|
||
`CogArchHubGitOps/` specifically, or as a worked example when standing up a new GitOps
|
||
repository from the generic rules.
|
||
|
||
The generic rules live in `SKILL.md` and the other reference files; this file records only
|
||
what is specific to this repository.
|
||
|
||
---
|
||
|
||
## 1. Repositories
|
||
|
||
```text
|
||
CogArchHubGitOps/ ← target repository (the Copier template + answer files)
|
||
CogArchHubGitOps-code-agent/ ← code-agent repository (skills and agent tooling)
|
||
```
|
||
|
||
Work described by this skill lands in the **target** repository. Deployed environments are
|
||
rendered copies of it.
|
||
|
||
---
|
||
|
||
## 2. Layout
|
||
|
||
```text
|
||
CogArchHubGitOps/
|
||
├── copier.yaml
|
||
├── cluster/
|
||
│ ├── argocd/
|
||
│ │ ├── application.yaml.jinja # 000-root app-of-apps
|
||
│ │ ├── {{ '200-operators' if … }}/
|
||
│ │ ├── {{ '300-configuration' if … }}/
|
||
│ │ ├── {{ '400-databases' if … }}/
|
||
│ │ ├── {{ '700-advantage-mcp' if … }}/
|
||
│ │ └── {{ '800-applications' if … }}/
|
||
│ └── resources/
|
||
│ └── <mirrored conditional directories>/
|
||
└── <env>/
|
||
└── copier-answers.yaml
|
||
```
|
||
|
||
`cluster/argocd/application.yaml.jinja` is the root app named `000-root`. It watches
|
||
`cluster/argocd/` recursively and creates every child Application it finds.
|
||
|
||
---
|
||
|
||
## 3. Bands in use
|
||
|
||
| Band | Domain | Concrete contents |
|
||
|---|---|---|
|
||
| 000 | Root | `000-root` app-of-apps |
|
||
| 200–299 | Operators | External Secrets Operator (ESO), CloudNativePG (CNPG), Redis |
|
||
| 300–399 | Cluster configuration | ClusterSecretStore and related config |
|
||
| 400–499 | Databases | PostgreSQL clusters, Redis clusters |
|
||
| 700–799 | Advantage / MCP | MCP servers, AI agent workloads |
|
||
| 800–899 | Platform applications | notification, integration, agent-service |
|
||
|
||
ESO occupies a contiguous sub-group inside the 2xx band — operator group, subscription, and
|
||
configuration each take their own number (`210`, `213`, `215`), so a related set stays
|
||
readable in a sorted directory listing. Follow the same grouping habit for new operators.
|
||
|
||
---
|
||
|
||
## 4. Feature flags
|
||
|
||
| Variable | Gates |
|
||
|---|---|
|
||
| `operators.is_enabled` | The whole `200-operators` band |
|
||
| `operators.eso_is_enabled` | ESO operator group, subscription, configuration |
|
||
| `operators.cnpg_is_enabled` | CNPG operator group and subscription |
|
||
| `operators.redis_is_enabled` | Redis operator group and subscription |
|
||
| `configuration.is_enabled` | The whole `300-configuration` band |
|
||
| `configuration.cluster_secret_store_is_enabled` | ClusterSecretStore |
|
||
| `databases.is_enabled` | The whole `400-databases` band |
|
||
| `advantage_mcp.is_enabled` | The whole `700-advantage-mcp` band |
|
||
| `applications.is_enabled` | The whole `800-applications` band |
|
||
|
||
Sub-flags are named `<sub>_is_enabled` and live flat under the domain object — `operators.eso_is_enabled`,
|
||
not `operators.eso.is_enabled`. Keep new flags consistent with that shape.
|
||
|
||
---
|
||
|
||
## 5. ArgoCD conventions
|
||
|
||
- ArgoCD runs in the `openshift-gitops` namespace (OpenShift GitOps operator), so every
|
||
`Application` sets `metadata.namespace: openshift-gitops`.
|
||
- `spec.project` is `default`.
|
||
- `spec.destination.server` is `https://kubernetes.default.svc` (in-cluster).
|
||
- `prune: true` and `selfHeal: true` are on for all apps.
|
||
|
||
---
|
||
|
||
## 6. Application global settings
|
||
|
||
`applications.global` in each answer file provides the settings shared by all 8xx services:
|
||
|
||
```yaml
|
||
applications:
|
||
global:
|
||
is_internal: "false"
|
||
enable_instana: "false"
|
||
ca_secret_name: ca-secret
|
||
ca_env: <env-name>
|
||
maintenance: "false"
|
||
host: <public-hostname>
|
||
ca_host: <internal-hostname>
|
||
suffix_url: <path-suffix>
|
||
node_selector_app: <node-label>
|
||
mongo:
|
||
host: <mongodb-host>
|
||
port: "27017"
|
||
user: <mongodb-user>
|
||
redis:
|
||
host: <redis-host>
|
||
port: "6379"
|
||
max_retries: "3"
|
||
neo4j:
|
||
url: <neo4j-bolt-url>
|
||
user: <neo4j-user>
|
||
```
|
||
|
||
The datastore blocks (`mongo`, `redis`, `neo4j`) carry connection coordinates only. Credentials
|
||
come from ESO-managed secrets at runtime, which is why `ca_secret_name` and the
|
||
ClusterSecretStore in the 3xx band are prerequisites for the 8xx band to work at all.
|
||
|
||
`is_internal`, `enable_instana`, and `maintenance` are **quoted strings**, not YAML booleans —
|
||
they reach the Helm chart as strings. Feature flags in the same file are real booleans. See
|
||
`environments.md` §4.
|
||
|
||
---
|
||
|
||
## 7. Private registry
|
||
|
||
Workload images pull from a private registry using the pre-existing secret `storage-images`:
|
||
|
||
```yaml
|
||
imagePullSecrets:
|
||
- name: "storage-images"
|
||
```
|
||
|
||
The secret is expected to exist in the target namespace already; it is not created by these
|
||
templates. A new namespace therefore needs the secret provisioned before its first sync, or
|
||
pods stall on `ImagePullBackOff`.
|
||
|
||
---
|
||
|
||
## 8. Ordering dependencies
|
||
|
||
The bands are numbered so a full bootstrap converges in ascending order:
|
||
|
||
1. **2xx operators** install the CRDs everything else depends on (ESO, CNPG, Redis).
|
||
2. **3xx configuration** creates the ClusterSecretStore that supplies secrets.
|
||
3. **4xx databases** create instances using the operators' CRDs.
|
||
4. **7xx / 8xx workloads** consume the databases and secrets.
|
||
|
||
ArgoCD does not enforce this ordering — the app-of-apps creates all children at once and each
|
||
syncs independently. The numbering is a convention that makes the intended order legible, and
|
||
failing apps in a fresh cluster usually resolve themselves once the band they depend on has
|
||
finished syncing. Do not add sync-waves to force ordering without discussing it first; retry
|
||
plus eventual consistency is the assumed model here.
|