Skip to content
Notifications
Clear all

Step-by-step: How I built a custom dashboard for our audit committee.

1 Posts
1 Users
0 Reactions
1 Views
(@ci_cd_plumber)
Reputable Member
Joined: 3 months ago
Posts: 156
Topic starter   [#5097]

We were drowning in spreadsheets and PDFs. Our audit committee needed a single pane of glass for status, metrics, and evidence, but nothing off-the-shelf fit our specific controls and reporting structure. So I built a custom dashboard. The key was treating it like a CI/CD pipeline: data in, transform, deploy.

The stack is simple and reliable:
* **Backend:** Python (FastAPI) to handle data aggregation and API endpoints.
* **Data:** PostgreSQL. All raw audit findings, control test results, and remediation status live here.
* **Frontend:** Basic React with Recharts for graphs. No fancy UI frameworks that break every six months.
* **Infrastructure:** Docker containers, deployed via a GitLab CI pipeline to a Kubernetes cluster.

The core of the system is the data sync. We pull from our GRC tool, JIRA, and a couple of internal databases. This runs nightly as a Kubernetes CronJob. The pipeline ensures the build and deployment are reproducible.

Here's the heart of the GitLab CI pipeline (.gitlab-ci.yml):

```yaml
stages:
- test
- build
- deploy

variables:
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

test:
stage: test
image: python:3.11-slim
script:
- pip install -r requirements.txt
- pytest

build:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker build -t $DOCKER_IMAGE .
- docker push $DOCKER_IMAGE

deploy:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/audit-dashboard audit-dashboard=$DOCKER_IMAGE --record -n audit
- kubectl rollout status deployment/audit-dashboard -n audit
only:
- main
```

The dashboard itself just consumes the API. The most valuable views we built:
* **Remediation Heatmap:** Control failures by department and over time.
* **Open Finding Age:** Anything older than 90 days turns red.
* **Testing Completion:** Real-time status against the annual plan.

Biggest pitfalls to avoid:
* Don't try real-time sync. Batch it nightly; it's more than enough and prevents API rate limits.
* Build idempotent data ingestion. If the job fails halfway, re-running it shouldn't duplicate records.
* Keep the frontend dumb. All logic and data shaping happens in the backend API.

It's been running for 9 months now with zero flaky deployments. The committee gets a consistent, auto-updating view every morning, and the audit team spends less than an hour a month on status reporting.


Build once, deploy everywhere


   
Quote