GitLab Deployment and Runner Classes
GitLab CE 18.11.1 on a single VM at 30.30.30.5 behind HAProxy — internal LAN endpoint for automation, public route for browsers, eleven ct-* role groups, five planned runner classes, and the FG-1 readiness gate.
GitLab is the lab’s operational source for platform and application delivery. It hosts the platform GitOps repository that hub and spoke Argo CD pull from; it hosts application source for division teams; it triggers Jenkins via webhook; and (planned) it hosts protected runner classes for in-GitLab CI.
GitHub remains the planning surface for the opp-full-plat workspace — issues, milestones, ADRs, reports, handoffs. GitLab and GitHub together split the “what we plan vs what we execute” axis cleanly.
This page covers the GitLab VM deployment and the runner-class model. Sister pages cover the federated monorepo architecture (page 2), the protected runner model (page 3), and tokens/bots (page 4).
Architecture
Two distinct entry points by purpose:
- Operators in browsers →
https://gitlab.apps.sub.comptech-lab.comvia HAProxy + LE wildcard. - Automation (Argo CD, Jenkins, future runners, platform API work) → the internal LAN endpoint directly on the lab
/24, port80, no TLS termination by HAProxy.
This split is non-negotiable per the operator guide.
What it is
| Property | Value |
|---|---|
| VM | gitlab at 30.30.30.5 |
| Internal LAN endpoint | http://30.30.30.5 (port 80, no TLS) |
| Human browser route | https://gitlab.apps.sub.comptech-lab.com (TLS at HAProxy edge) |
| GitLab version | 18.11.1 |
| Edition | GitLab CE (non-Enterprise) |
| Current operational platform repo | comptech-platform/openshift-ops/openshift-platform-gitops (project ID 12) |
| Local clone for the platform GitOps repo | /home/ze/claude-agent/clones/platform-gitops (worktree-of-main convention) |
| Bootstrap admin user | zahid |
| Operator PAT custody | gitlab-md-pat file in the local-only secrets directory (Git-ignored) |
Why a single VM CE
Per the operator guide:
- CE is acceptable for the lab’s current scope — branch protection, merge requests, and approval rules at the CE feature level are enough.
- Single VM matches the bootstrap pattern for all supporting services (Nexus, Jenkins, SigNoz, Trivy, DefectDojo, etc.).
- Internal LAN endpoint as the automation surface keeps platform tools off the public path. Argo CD, Jenkins, GitLab Runner (future), and platform tooling use it; only humans use the public route.
CE has limitations vs Premium/Ultimate — most relevantly, certain advanced merge-rule features. When the lab hits one, the compensating control is CODEOWNERS, protected branches, validation pipelines, and documented MR evidence rather than upgrading the GitLab edition.
Endpoints, one more time
The two-endpoint distinction is the most-misused piece of the GitLab design. Repeating for clarity:
| Use | Endpoint |
|---|---|
git clone for automation (Argo CD, Jenkins, runners) | LAN endpoint, http://, port 80 |
git clone from a human operator workstation | LAN endpoint OR public route — both work |
| Browser, MR review, issue tracking | Public route, https://gitlab.apps.* |
| API calls from automation | LAN endpoint |
| API calls from an operator’s CLI | Either; prefer LAN endpoint for consistency |
Configuring Argo CD or Jenkins to use the public route is a drift indicator — it breaks the assumption that automation lives on the LAN, complicates TLS trust setup, and pulls automation behind the HAProxy SNI plane unnecessarily.
Current group structure
The federated group skeleton already exists (per the operator guide):
comptech-platform/
openshift-ops/
openshift-platform-gitops (project ID 12, migrated from gitops/platform-gitops)
infra-ops/
platform-services/
tenant-registry/
divisions/
sandbox/
openliberty-readiness-probe
demo-smoke
Eleven ct-* role groups are already provisioned with bootstrap membership:
ct-gitlab-admins
ct-openshift-platform-maintainers
ct-openshift-platform-reviewers
ct-infra-platform-maintainers
ct-infra-platform-reviewers
ct-cicd-platform-maintainers
ct-security-reviewers
ct-auditors
ct-sandbox-app-maintainers
ct-sandbox-developers
ct-sandbox-release-approvers
The full ownership matrix lives in the federated monorepo page.
Runner classes (planned)
Per the operator guide, five runner classes are intended, each with a specific privilege bound:
| Class | Purpose | What it must NOT have |
|---|---|---|
| Validation runner | Render templates, lint, policy checks | live apply credentials |
| Build runner | Build/test/scan app images | platform infra credentials |
| Security runner | Trivy/SBOM/SCA checks | broad deploy credentials |
| Ops runner | Terraform/OpenTofu, Ansible, platform API work | shared with app builds; protected, restricted to platform repos |
| Deploy runner | VM runtime deployment | unrestricted target list; scoped to approved VM targets |
The existing gitlab-vm-docker runner is project-scoped, unprotected, and runs untagged jobs — it is explicitly not the future trusted platform runner. Protected runner classes must be created under the GitLab Runner Operating Model milestone before production-like work.
Runner rules (per operator guide):
- Use the internal LAN endpoint.
- Store runner tokens outside Git.
- Use protected runners for protected branches.
- Don’t share ops runners with untrusted app builds.
- Don’t put platform kubeconfigs or admin tokens on build runners.
- OpenShift deploys through Argo CD pull, not runner-side
oc apply.
Detailed runner privileges live on the protected runner model page.
FG-1 readiness gate — in progress
FG-1 is the first federated GitOps readiness gate — the named, repeatable bar that GitLab must clear before more divisions onboard or production-like CI runs in-GitLab. It is tracked under issue #83, governed by ADR 0023, and the formal ownership matrix it locks in lives on the federated monorepo architecture page.
The gate’s acceptance criteria, in current state:
| Criterion | Status | Notes |
|---|---|---|
GitLab CE 18.11.1 at 30.30.30.5, public route via HAProxy LE wildcard, internal LAN endpoint reachable | Done | preflight 2026-05-09; smart-HTTP clone fails through public route by design — automation uses LAN |
Two-tree group skeleton (comptech-platform/ + divisions/) provisioned | Done | 11 ct-* role groups created with bootstrap membership |
openshift-platform-gitops at project ID 12, main protected, force-push disabled, Maintainers-only push/merge | Done | confirmed live |
CODEOWNERS on openshift-platform-gitops | In progress | CE limitations on approval-rule enforcement to be documented as a compensating control |
Validation-only pipeline on openshift-platform-gitops (Kustomize render, YAML parse, no plaintext Secrets, no unmanaged public images, no app-team cluster-admin) | In progress | runs on the (planned) validation runner class only |
| Five protected runner classes provisioned with dedicated registration tokens | Open | covered on the protected runner model page; current gitlab-vm-docker runner is not a substitute |
| Negative access tests (sandbox apps cannot write to platform repos, platform GitOps cannot read secrets, etc.) | Open | run after CODEOWNERS + runner classes land |
| Documented MR mechanics for platform-gitops changes (PAT custody, sync-wave 10 convention, operator-install pattern) | Done | tokens-and-bots page documents the PAT flow; sync-wave convention lives in the platform GitOps repo |
The gate’s compensating control posture matters: GitLab CE doesn’t expose the full approval-rules surface (the preflight saw HTTP 404 on the project approval-rules API). The lab compensates with CODEOWNERS, protected branches, the validation pipeline, and the protected-runner trust boundaries, rather than upgrading the GitLab edition.
FG-1 closes when every criterion above is Done. Until then, app-team onboarding stays inside the sandbox division.
Repository ownership
The bootstrap-phase intent is captured fully on the federated monorepo page. The summary table:
| GitLab path | Writers | Default readers |
|---|---|---|
comptech-platform/openshift-ops/openshift-platform-gitops | OpenShift/platform team only | platform, security, auditors |
comptech-platform/infra-ops/vm-platform-ops (planned) | Infra/platform tools team | OpenShift read, security, auditors |
divisions/<division>/<division>-apps-monorepo | Division app team | platform/CI/security as needed |
divisions/<division>/<division>-gitops | Division app team (inside guardrails) | OpenShift/platform retains maintainer for guardrails/emergency rollback |
Application teams must not write to:
openshift-platform-gitopsopenshift-cluster-buildvm-platform-ops- Platform runner or admin configuration repos
Branch protection baseline
Every operational repository runs with:
- Default branch
main. - Protected
main. - Force push disabled.
- Direct push to
maindisabled except named break-glass maintainers. - Merge requests required for normal changes.
- Approval required (one for non-production repos, two for production-impacting).
- CODEOWNERS approval required for protected paths.
- Pipeline required before merge where validation jobs exist.
- Stale approval dismissal for production-impacting repos where the edition supports it.
- MR templates for platform, infra, runner, and release repos.
Daily operator checks
# GitLab health
curl -fsS "http://30.30.30.5/-/readiness"
curl -fsS "http://30.30.30.5/-/liveness"
# API check
GITLAB_PAT="$(cat <secrets-dir>/gitlab-md-pat)"
curl -fsS --header "PRIVATE-TOKEN: $GITLAB_PAT" \
"http://30.30.30.5/api/v4/version"
unset GITLAB_PAT
# Platform repo reachability
git ls-remote \
http://30.30.30.5/comptech-platform/openshift-ops/openshift-platform-gitops.git \
main
OpenShift GitOps consumer
The v6 OpenShift model is ACM plus OpenShift GitOps Basic pull. GitLab’s role:
hub-dc-v6Argo CD pulls fromopenshift-platform-gitopsvia the internal LAN endpoint.spoke-dc-v6Argo CD does the same.- GitLab must therefore be reachable from hub Argo CD repo-server, spoke Argo CD repo-server, Jenkins, future GitLab runners, and platform operator workstations — all using the LAN endpoint.
A platform repo Argo CD health check:
K_HUB=/home/ze/.kube/configs/hub-dc-v6.kubeconfig
K_SPOKE=/home/ze/.kube/configs/spoke-dc-v6.kubeconfig
oc --kubeconfig "$K_HUB" -n openshift-gitops get app hub-dc-v6-bootstrap -o wide
oc --kubeconfig "$K_SPOKE" -n openshift-gitops get app spoke-dc-v6-cluster-config -o wide
Expected: Synced Healthy.
Drift indicators
Per the operator guide, watch for:
- Users directly added to many projects (should be via role groups).
- App-team group appearing on
openshift-platform-gitops. - Public route appearing in Argo CD/Jenkins/runner config.
- Unprotected runner executing protected-branch jobs.
- Direct pushes to
main. - Missing session report for a live GitLab mutation.
- Platform GitOps containing VM service configuration or application source.
- App GitOps repo containing platform cluster-scoped guardrails.
Roadmap
Immediate (FG-1 close-out):
- Land CODEOWNERS on
openshift-platform-gitopsand document the CE compensating-control posture. - Finish the validation-only pipeline (Kustomize render, YAML parse, no plaintext Secrets, no unmanaged public images, no app-team cluster-admin) — runs on the validation runner class only.
- Define and provision the five protected GitLab Runner classes and tags (covered on the protected runner model page).
- Negative access tests for sandbox apps against platform repos.
- Close FG-1 (issue #83) — all criteria in the FG-1 readiness gate table at Done.
Next:
- Create
vm-platform-opsonce ownership and first service adoption are ready. - Create sandbox division repos with negative access tests.
- Move from bootstrap admin/PAT usage to named users, deploy tokens, and Vault-backed or protected variable custody.
Longer:
- Support future
hub-dr,spoke-dr, dev, UAT, staging, production OCP clusters. - Onboard multiple BFSI divisions.
- Adopt HAProxy, PowerDNS, GitLab, Jenkins, Nexus, Docker runtime, Vault, Trivy, SigNoz into Git-tracked VM/platform operations.
- Add audit evidence retention for GitLab changes.
- Add signed commits for production-impacting repos if feasible.
- Add automated access drift checks against the matrix.
References
opp-full-plat/connection-details/gitlab-operator-guide.md— canonical operator runbook.opp-full-plat/adr/0023-federated-gitlab-group-repo-ownership.md— ownership model.opp-full-plat/adr/0015-federated-gitops-repo-architecture.md— parent architecture decision.opp-full-plat/adr/0018-acm-openshift-gitops-pull-model-v6.md— Argo CD pull-model consumer.opp-full-plat/adr/0019-nexus-only-image-supply-chain.md— mirror ownership the platform GitOps owns.