# 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/ │ └── / └── / └── 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 `_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: maintenance: "false" host: ca_host: suffix_url: node_selector_app: mongo: host: port: "27017" user: redis: host: port: "6379" max_retries: "3" neo4j: url: 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.