Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions charts/br-ccs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Changelog

All notable changes to the br-ccs Helm chart are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.0] - 2026-07-07
Comment thread
brunobls marked this conversation as resolved.

### Added

- Initial Helm chart for the br-ccs service (BACEN CCS regulatory integration).
- Single Deployment running `CCS_RUN_MODE=all` (HTTP API + background workers in one process).
- ClusterIP Service on port 4030 (`SERVER_ADDRESS=:4030`).
- Health probes wired to the verified application endpoints: liveness `GET /health`,
readiness `GET /readyz`.
- Full env-var coverage from `config/.env.example` split across ConfigMap (non-secret)
and Secret (credentials, crypto keys, object-storage keys, M2M API keys).
- PostgreSQL migrations Job using the dedicated `br-ccs-migrations` image
(golang-migrate runner; PreSync for external Postgres, PostSync for the bundled
subchart), plus a migration-only Secret hook for the external chart-managed path.
- Optional subchart dependencies: `postgresql`, `valkey`, `rabbitmq` (all `.enabled`-gated).
- External-infra bootstrap Jobs for PostgreSQL and RabbitMQ (opt-in via `global.*Definitions.enabled`).
- HPA, PodDisruptionBudget, Ingress, ServiceAccount templates.
- Non-root, read-only-root-filesystem, drop-ALL security contexts on all containers.
12 changes: 12 additions & 0 deletions charts/br-ccs/Chart.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
dependencies:
- name: valkey
repository: oci://registry-1.docker.io/bitnamicharts
version: 2.4.7
- name: postgresql
repository: https://charts.bitnami.com/bitnami
version: 16.3.5
- name: rabbitmq
repository: https://groundhog2k.github.io/helm-charts
version: 2.1.11
digest: sha256:7bb3353ae1606ded8101b27d09edeeb9e82d7d8b627c74acb4ea6b9badb77c3c
generated: "2026-07-07T11:01:18.762917187-03:00"
40 changes: 40 additions & 0 deletions charts/br-ccs/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
apiVersion: v2
name: br-ccs-helm
description: A Helm chart for br-ccs — Lerian's BACEN CCS (Cadastro de Clientes
do Sistema Financeiro Nacional) regulatory integration service
type: application
annotations:
lerian.studio/chart-type: single-service
home: https://github.com/LerianStudio/helm
sources:
- https://github.com/LerianStudio/helm/tree/main/charts/br-ccs
- https://github.com/LerianStudio/br-ccs
maintainers:
- name: "Lerian Studio"
email: "support@lerian.studio"

version: 1.0.0-beta.4

appVersion: "1.0.0"

keywords:
- ccs
- bacen
- regulatory
- lerian
- ledger
- brazil
icon: https://avatars.githubusercontent.com/u/148895005?s=200&v=4
dependencies:
- name: valkey
version: "2.4.7"
repository: "oci://registry-1.docker.io/bitnamicharts"
condition: valkey.enabled
- name: postgresql
version: "16.3.5"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
- name: rabbitmq
version: "2.1.11"
repository: "https://groundhog2k.github.io/helm-charts"
condition: rabbitmq.enabled
93 changes: 93 additions & 0 deletions charts/br-ccs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# br-ccs Helm Chart

Helm chart for **br-ccs** — Lerian's Go service for the BACEN **CCS (Cadastro de
Clientes do Sistema Financeiro Nacional)** regulatory integration. It ingests
customer-relationship data (from Fetcher), computes the daily delta, renders the
BACEN XML layouts, transmits via **STA**, and reconciles the responses, honoring
judicial secrecy (liminares / LC 105) and LGPD.

- Chart name: `br-ccs-helm`
- Chart type: `single-service`
- Source: https://github.com/LerianStudio/br-ccs

## Chart Contract

- Chart type: `single-service`
- Required secrets: `brCcs.secrets.CCS_CRYPTO_MASTER_KEY` (AES-256-GCM, 64 hex chars — empty fails fast at boot). `POSTGRES_PASSWORD` and `REDIS_PASSWORD` are single-sourced from the bundled `<release>-{postgresql,valkey}` Secrets via `secretKeyRef` when those subcharts are enabled; supply them (or `<subchart>.auth.existingSecret`) for external infra. `FETCHER_CRYPTO_KEY` is optional (empty = passthrough). See `docs/helm-chart-standard.md`.
- Dependency notes: Bundled PostgreSQL and Valkey subcharts are used unless external services are configured; RabbitMQ is optional and disabled by default. No MongoDB.
- Production overrides: Disable the bundled subcharts (`<subchart>.enabled=false`, `.external=true`), set `POSTGRES_HOST`/`REDIS_HOST`, and supply secrets via a secrets manager or `brCcs.useExistingSecret`; override image tags, ingress, resources, and integration endpoints (Fetcher/STA/Reporter).
- Source/license: Source is in `github.com/LerianStudio/helm` and `github.com/LerianStudio/br-ccs`; license is Apache-2.0.

## TL;DR

```bash
helm dependency build charts/br-ccs
helm install br-ccs charts/br-ccs \
--set brCcs.configmap.ENV_NAME=production \
--set brCcs.secrets.POSTGRES_PASSWORD=... \
--set brCcs.secrets.REDIS_PASSWORD=... \
--set brCcs.secrets.CCS_CRYPTO_MASTER_KEY=$(openssl rand -hex 32)
```

## Service topology

| Aspect | Value |
|--------|-------|
| Container port / Service port | `4030` (`SERVER_ADDRESS=:4030`) |
| Service type | `ClusterIP` |
| Run mode | Single Deployment, `CCS_RUN_MODE=all` (API + workers) |
| Liveness probe | `GET /health` |
| Readiness probe | `GET /readyz` (PROJECT_RULES §13.4) |
| Persistence | PostgreSQL (no MongoDB) |
| Messaging | RabbitMQ (optional, disabled by default) |
| Cache / idempotency / rate-limit | Redis / Valkey |

## Dependencies

All bundled subcharts are `.enabled`-gated. For BYOC / production, disable them
and point the app at external infrastructure (see `values-template.yaml`).

| Subchart | Version | Repository |
|----------|---------|------------|
| postgresql | 16.3.5 | https://charts.bitnami.com/bitnami |
| valkey | 2.4.7 | oci://registry-1.docker.io/bitnamicharts |
| rabbitmq | 2.1.11 | https://groundhog2k.github.io/helm-charts |

## Configuration

Non-secret configuration lives under `brCcs.configmap`; credentials and keys
under `brCcs.secrets`. Every variable from the application's
`config/.env.example` is mapped. Optional knobs not modeled explicitly can be
set via `brCcs.extraEnvVars`.

### Required secrets

| Key | Required | Notes |
|-----|----------|-------|
| `POSTGRES_PASSWORD` | Yes | Single-sourced from the bundled subchart Secret when `postgresql.enabled=true`; supply here for external Postgres. |
| `REDIS_PASSWORD` | Yes | Single-sourced from the bundled valkey Secret when `valkey.enabled=true`; supply here for external Redis. |
| `CCS_CRYPTO_MASTER_KEY` | Yes | AES-256-GCM master key, 64 hex chars (`openssl rand -hex 32`). Empty fails fast at boot. |
| `FETCHER_CRYPTO_KEY` | No | Optional. Empty = passthrough / plaintext (dev/staging); set to the Fetcher `APP_ENC_KEY` to decrypt snapshots. |

### Migrations

`brCcs.migrations.enabled=true` (default) runs the dedicated `br-ccs-migrations`
image as a Helm/ArgoCD hook:

- **External Postgres** → PreSync (`pre-install,pre-upgrade`), backed by a
migration-only Secret carrying just `POSTGRES_PASSWORD`.
- **Bundled Postgres subchart** → PostSync (`post-install,post-upgrade`), reading
the app Secret after the database is provisioned.

## Security

All containers run non-root (`runAsUser: 1000`, `runAsNonRoot: true`), with
`readOnlyRootFilesystem: true`, `allowPrivilegeEscalation: false`,
`capabilities.drop: [ALL]`, and `seccompProfile: RuntimeDefault`.

## Validation

```bash
helm lint charts/br-ccs
helm template charts/br-ccs
```
35 changes: 35 additions & 0 deletions charts/br-ccs/files/rabbitmq/load_definitions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"users": [
{
"name": "br-ccs",
"tags": ""
}
],
Comment thread
brunobls marked this conversation as resolved.
"vhosts": [
{
"name": "/"
}
],
"permissions": [
{
"user": "br-ccs",
"vhost": "/",
"configure": ".*",
"write": ".*",
"read": ".*"
}
],
"queues": [],
"exchanges": [
{
"name": "events",
"vhost": "/",
"type": "topic",
"durable": true,
"auto_delete": false,
"internal": false,
"arguments": {}
}
],
"bindings": []
}
153 changes: 153 additions & 0 deletions charts/br-ccs/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "br-ccs.name" -}}
{{- default (default "br-ccs" .Values.nameOverride) | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name for br-ccs.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "br-ccs.fullname" -}}
{{- default (include "br-ccs.name" .) .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "br-ccs.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create br-ccs app version
*/}}
{{- define "br-ccs.defaultTag" -}}
{{- default .Chart.AppVersion .Values.brCcs.image.tag }}
{{- end -}}

{{/*
Return valid br-ccs version label
*/}}
{{- define "br-ccs.versionLabelValue" -}}
{{ regexReplaceAll "[^-A-Za-z0-9_.]" (include "br-ccs.defaultTag" .) "-" | trunc 63 | trimAll "-" | trimAll "_" | trimAll "." | quote }}
{{- end -}}

{{/*
Common labels
*/}}
{{- define "br-ccs.labels" -}}
helm.sh/chart: {{ include "br-ccs.chart" .context }}
{{ include "br-ccs.selectorLabels" (dict "context" .context "component" .component "name" .name) }}
app.kubernetes.io/version: {{ include "br-ccs.versionLabelValue" .context }}
app.kubernetes.io/managed-by: {{ .context.Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "br-ccs.selectorLabels" -}}
app.kubernetes.io/name: {{ include "br-ccs.name" .context }}
app.kubernetes.io/instance: {{ .context.Release.Name }}
{{- if .component }}
app.kubernetes.io/component: {{ .component }}
{{- end }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "br-ccs.serviceAccountName" -}}
{{- if .Values.brCcs.serviceAccount.create }}
{{- default (include "br-ccs.fullname" .) .Values.brCcs.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.brCcs.serviceAccount.name }}
{{- end }}
{{- end }}

{{/*
Expand the namespace of the release.
Allows overriding it for multi-namespace deployments in combined charts.
*/}}
{{- define "global.namespace" -}}
{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}}
{{- end }}

{{/*
Enable internal dependencies
These helpers check both .enabled and .external flags
*/}}
{{- define "rabbitmq.enabled" -}}
{{- if and (default true .Values.rabbitmq.enabled) (not .Values.rabbitmq.external) -}}
true
{{- else -}}
false
{{- end -}}
{{- end -}}

{{- define "valkey.enabled" -}}
{{- if and (default true .Values.valkey.enabled) (not .Values.valkey.external) -}}
true
{{- else -}}
false
{{- end -}}
{{- end -}}

{{- define "postgresql.enabled" -}}
{{- if and (default true .Values.postgresql.enabled) (not .Values.postgresql.external) -}}
true
{{- else -}}
false
{{- end -}}
{{- end -}}

{{/*
br-ccs.infraSecretRef — emit a `- name: <envName> valueFrom: secretKeyRef: {name,key}`
entry pointing at a Bitnami subchart's generated Secret (or the operator's existingSecret
override). Inputs (dict): context (root .), subchart, key, envName.
*/}}
{{- define "br-ccs.infraSecretRef" -}}
{{- $ctx := .context -}}
{{- $sub := .subchart -}}
{{- $auth := default dict (index $ctx.Values $sub "auth") -}}
{{- $secretName := "" -}}
{{- if $auth.existingSecret -}}
{{- $secretName = $auth.existingSecret -}}
{{- else -}}
{{- $secretName = include "common.names.dependency.fullname" (dict "chartName" $sub "chartValues" (index $ctx.Values $sub) "context" $ctx) -}}
{{- end -}}
- name: {{ .envName }}
valueFrom:
secretKeyRef:
name: {{ $secretName }}
key: {{ .key }}
{{- end }}

{{/*
br-ccs.migrationPostgresPassword — POSTGRES_PASSWORD for the migration-only Secret.
migration-secret.yaml renders ONLY on the EXTERNAL Postgres path (the bundled subchart path
reads the subchart Secret via secretKeyRef instead), so the operator MUST supply the password.
*/}}
{{- define "br-ccs.migrationPostgresPassword" -}}
{{- $secrets := get (.Values.brCcs | default dict) "secrets" | default dict -}}
{{- required "brCcs.secrets.POSTGRES_PASSWORD is required when migrations run against external PostgreSQL with a chart-managed Secret" (get $secrets "POSTGRES_PASSWORD") -}}
{{- end }}

{{/*
Vendored from Bitnami common (charts/common/templates/_names.tpl) so infra
Secret/Service names render even when all bundled subcharts are disabled
(external-infra path). Self-contained: no other common.* helpers required.
*/}}
{{- define "common.names.dependency.fullname" -}}
{{- if .chartValues.fullnameOverride -}}
{{- .chartValues.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .chartName .chartValues.nameOverride -}}
{{- if contains $name .context.Release.Name -}}
{{- .context.Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .context.Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
Loading
Loading