Skip to content

Onboarding nueva app por GitOps (RUN-NEW-APP-GITOPS)

Status: Active standard
Owner: Wetopi platform architecture
Applies to: a new service repository that will run on the RKE2 platform
Last reviewed: 2026-09-23

Purpose

Use this runbook to create a new application repository with the same minimum engineering and operational contract as the rest of the Wetopi platform, then register it once in platform-gitops so Argo CD can reconcile it.

The application repository owns the application and its workload manifests. platform-gitops owns only the Argo CD registration and project allow-list. The cluster is an observed runtime, never a place to edit the source of truth.

This runbook is separate from the Paperclip fleet framework: Paperclip issues and agents may execute it, but they do not change the ownership boundaries below.

Authority and ownership

Concern Canonical authority
Application source, tests and Docker build Application repository
Workload manifests and release configuration Application repository
Argo Application/AppProject registration wetopi-platform/platform-gitops
Secret values Wetopi secret manager (currently Infisical)
Desired cluster state Git repositories consumed by Argo CD
Live health, revision and events Kubernetes and Argo CD
Work assignment and execution evidence Paperclip issue/run/documents

Never put workload manifests in platform-gitops. Never put secret values in either Git repository. A kubectl apply is not an onboarding step; it bypasses the GitOps review and is prohibited by this runbook.

Inputs and exit result

Before starting, the request must identify:

  • application name and owning team;
  • Git repository URL and release branch;
  • runtime namespace and environment;
  • image registry/repository and promotion policy;
  • service ports, health endpoints and persistence needs;
  • required secrets, external dependencies and data classification;
  • whether the service is internal-only or needs an explicitly approved route;
  • rollback target and an owner for the first on-call response.

The runbook is complete only when both reviewed changes have landed and the child Argo application is Synced and Healthy with the expected immutable image digest:

  1. application-repository change: code, tests, build and workload manifests;
  2. platform-gitops change: Argo registration and, if required, project source allow-list.

Phase 1 — application repository contract

Create the repository with a README that states ownership, purpose, local development, test commands, release channel, runtime namespace, dependencies, health endpoints, secrets policy and rollback procedure. Add a docs/ section for architecture and operations when the service is more than a trivial utility.

Use a predictable tree. Names may vary by language, but the boundaries must be visible:

app-repository/
├── README.md
├── AGENTS.md                         # repository-specific agent rules, if needed
├── Dockerfile
├── .dockerignore
├── src/                              # or the language's conventional source tree
├── tests/
├── docs/                             # architecture, operations, ADRs as needed
├── .github/workflows/                # test, build and release workflows
└── manifests/<release-channel>/
    ├── namespace.yaml                # only when this repo owns the namespace
    ├── serviceaccount.yaml
    ├── role.yaml                     # omit when no API access is needed
    ├── rolebinding.yaml
    ├── configmap.yaml
    ├── deployment.yaml               # or statefulset/job as appropriate
    ├── service.yaml                  # when the workload is networked
    ├── networkpolicy/
    └── secrets/infisical-*.yaml      # references only; no secret values

Manifests must be renderable and reviewable from the repository. Use immutable image references (prefer a digest). Make the destination namespace explicit and use the same namespace in every namespaced manifest; do not leave placeholders such as <namespace> in files consumed by Argo.

The minimum workload contract is:

  • non-root or otherwise justified security context;
  • dedicated ServiceAccount and least-privilege RBAC;
  • CPU/memory requests and limits;
  • startup, readiness and liveness probes where the process supports them;
  • default-deny ingress/egress posture, with narrowly scoped exceptions;
  • no public exposure without an approved route and security review;
  • graceful shutdown and a documented rollback path;
  • persistence and backup/restore requirements explicitly recorded;
  • external secrets represented as references managed by the existing secret mechanism.

Phase 2 — build and promotion contract

The application repository CI must, at minimum:

  1. run unit/integration tests and the repository's static checks;
  2. validate Kubernetes YAML, including namespace consistency and schema;
  3. scan the image and fail on the repository's blocking findings;
  4. build and publish an immutable image;
  5. record the image digest as release evidence;
  6. update the manifest digest through a reviewable commit or an approved promotion bot.

Wetopi builds use the platform's self-hosted GitHub Actions runners where the workflow requires internal network or registry access. Images are published to the private Wetopi registry, registry.wetopi.net, unless an approved project contract says otherwise. The workflow must make the runner class and registry destination explicit; do not silently fall back to a public runner or registry for a production-bound image.

A source-code push is not a deployment. Argo cannot deploy a new image until the desired manifest revision points at that image digest. Keep the build PR and the promotion change separate when that makes the review boundary clearer.

Phase 3 — one-time GitOps registration

Work in a branch of wetopi-platform/platform-gitops and use a pull request. Do not apply an Application directly with kubectl.

3.1 Allow the source repository

If the application repository is not already allowed by the relevant AppProject, add its exact URL to spec.sourceRepos in the same reviewed change. Keep the allow-list narrow; do not add a wildcard to make onboarding convenient.

3.2 Add the Argo application

Create apps/<app-name>.yaml following the existing platform-gitops pattern:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: app-name
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: <approved-project>
  source:
    repoURL: <canonical-application-repository-url>
    targetRevision: <release-branch-or-tag>
    path: manifests/<release-channel>
    directory:
      recurse: true
      include: '{namespace.yaml,serviceaccount.yaml,role.yaml,rolebinding.yaml,configmap.yaml,deployment.yaml,service.yaml,networkpolicy/*.yaml,secrets/infisical-*.yaml}'
  destination:
    server: https://kubernetes.default.svc
    namespace: <runtime-namespace>
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
      - PruneLast=true

Only include files that exist and are intentionally owned by the application. If the existing project uses a different sync policy, copy that policy and record the reason in the PR rather than inventing a second convention.

The apps/<app-name>.yaml registration and any change to its include glob must land together with the application manifest change. An Argo Application that watches a path but excludes a new manifest produces a misleadingly healthy-looking partial deployment.

3.3 Review and merge

The PR must show:

  • source repository, branch and manifest path;
  • destination namespace and project;
  • exact image digest and promotion evidence;
  • secret references without values;
  • RBAC, network policy, persistence and rollback review;
  • CI results and an explicit statement that no imperative cluster mutation was used.

After merge, the root gitops Application discovers apps/<app-name>.yaml. That child Application then reconciles the application repository. This is the only recurring registration step; subsequent releases update the application repository's desired revision and do not require a new Argo Application.

Phase 4 — verification and evidence

Verify in this order, using read-only Argo/Kubernetes commands or the platform's approved API:

  1. root gitops Application is Synced and Healthy at the expected platform-gitops revision;
  2. child application is Synced and Healthy at the expected app-repository revision;
  3. child resources are in the intended namespace;
  4. Deployment/StatefulSet image and live pod imageID match the approved digest;
  5. desired replica count, readiness, probes and recent events are healthy;
  6. service reachability is limited to the approved network path;
  7. secret references resolve without exposing values;
  8. the Argo history, PR, commit and verification report are linked from the Paperclip issue.

Record the evidence in the application issue/run and, for a new platform pattern or a failed rollout, in a dated docs/reports/ document. If any check is inconclusive, leave the Application unchanged and mark the work blocked.

Recurring release flow

Once onboarding is complete, the normal release is:

feature branch
  → tests and review in application repository
  → merge/build/publish immutable image
  → update manifest image digest
  → Argo root discovers/maintains child Application
  → child Application syncs
  → verify health, digest and evidence

The GitOps registration is a one-time platform operation. The application repository remains responsible for its own manifests and release evidence; platform-gitops remains responsible for the registration that makes Argo watch that repository.

Stop conditions

Stop and create a reviewable blocker when any of these is true:

  • owner, namespace, source path or rollback target is missing;
  • a manifest contains a secret value or a mutable image tag where an immutable release is required;
  • the repository is not allowed by the Argo project;
  • a namespaced manifest uses a different or unresolved namespace;
  • an include glob omits a manifest that the repository expects Argo to apply;
  • the requested route exposes the service publicly without approval;
  • the change requires cluster, RBAC, network or persistent-data mutation beyond the approved PR;
  • root or child Argo is OutOfSync, Degraded or reports a failed sync.

Do not work around a stop condition with a direct cluster edit. Fix the source of truth, review it, and let Argo reconcile it.