4.0 KiB
Test Automation Architecture
Responsibilities
GitLab CI is the orchestrator. It validates the project configuration, starts tool-specific Kubernetes jobs, collects raw output, invokes normalizers, and publishes rendered reports. Ansible is one test executor alongside ZAP and future tools; it is not the pipeline controller.
flowchart LR
A[assets.yml] --> V[Validate and prepare]
V --> K[k3s tool jobs]
K --> AN[Ansible]
K --> Z[ZAP]
K --> O[Other tools]
AN --> R[Raw artifacts]
Z --> R
O --> R
R --> N[Tool adapters]
N --> J[Normalized JSON]
J --> D[Markdown / HTML / PDF]
D --> G[GitLab artifacts]
Data Contracts
assets.ymlis the canonical project and asset list. It is valid Ansible YAML inventory and is parsed during pipeline preparation for CI metadata.- Tool output is retained unchanged under
artifacts/raw/<tool>/. - Every adapter writes schema-valid reports under
artifacts/normalized/. schemas/test-report.schema.jsonis the versioned interface between tools and report generation. Standards mappings belong on individual results, so IEC 62443 and OWASP ASVS findings can coexist without flattening semantics.- Generated Markdown, HTML, and PDF files are stored under
artifacts/rendered/and uploaded as GitLab artifacts. TARGET_ENVIRONMENTselects GitLab environment-scoped variables and must match the environment declared inassets.yml. Only tool jobs declare that GitLab environment, keeping secrets out of validation and rendering jobs.
Kubernetes State
The test-automation namespace contains reusable platform state. The initial
manifests request one volume using the cluster's default StorageClass:
tool-cache is a long-lived, replaceable cache for downloaded vulnerability
databases, scanner rules, and package indexes.
Pipeline evidence is never authoritative on a PVC. GitLab artifacts are the immutable record and receive an explicit retention policy. Databases that require transactions or concurrent writers should use a dedicated StatefulSet and PVC rather than the shared cache. Back up only state that cannot be reconstructed from an upstream feed.
ZAP jobs are ephemeral and receive no persistent ZAP home by default. This
prevents sessions, authentication state, and target data from leaking between
projects. Only a future explicitly reviewed ZAP add-on cache should use
tool-cache.
Job Isolation
Each GitLab CI job is already an ephemeral pod because testserv uses the
Kubernetes executor. Tool jobs receive the checked-out project, narrowly scoped
credentials, resource requests and limits, and the shared tool cache. Output is
written to the GitLab workspace and uploaded directly as pipeline artifacts.
NetworkPolicy should be added once target ranges and proxy requirements are known.
Required Runner Configuration
The runner manager on testserv uses the ci/gitlab-runner ServiceAccount.
Configure its Helm values so [runners.kubernetes].namespace is
test-automation, and mount the tool-cache PVC at /cache/tools. The
cross-namespace RoleBinding in platform/kubernetes/runner-rbac.yml grants only
the pod, attach, log, Secret, Service, and event operations required by GitLab's
Kubernetes executor.
Bootstrap the namespace, storage, and RBAC once with an administrator context:
kubectl apply -k platform/kubernetes
CI tool pods do not need Kubernetes API credentials. The runner manager uses its in-cluster identity to create and clean them up. Do not copy the admin kubeconfig into GitLab CI.
Delivery Sequence
- Make inventory validation, schema validation, and report rendering mandatory.
- Run Ansible in its GitLab Kubernetes-executor pod and normalize its JSON.
- Add ZAP Automation Framework plans and a ZAP-to-common-schema adapter with ASVS mappings.
- Add SBOM generation through Ansible for Windows and Linux targets; preserve CycloneDX as a raw artifact and normalize policy findings separately.
- Add aggregate project reports and quality-gate policies after result semantics are stable.