Skip to content

Latest commit

 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

formae-helm

Helm chart for deploying the formae infrastructure-as-code agent on Kubernetes with optional PostgreSQL, OpenTelemetry, and Grafana dashboards.

Deployment Tiers

Tier Components Example
Standalone formae agent (SQLite) examples/formae-only.yaml
With database formae + PostgreSQL examples/formae-db.yaml
With auth formae + PostgreSQL + basic auth examples/formae-basic-auth.yaml
Full observability formae + PostgreSQL + OTel + Grafana dashboards examples/formae-db-grafana.yaml
Custom config Bring your own formae.conf.pkl examples/formae-custom-config.yaml

Quick Start

helm install formae . -f examples/formae-only.yaml

With PostgreSQL:

helm install formae . -f examples/formae-db.yaml \
  --set postgresql.auth.password=changeme

Full monitoring stack (requires Prometheus + Grafana already running):

helm install formae . -f examples/formae-db-grafana.yaml \
  --set postgresql.auth.password=changeme

See examples/quickstart-monitoring.yaml for a step-by-step guide to deploying the monitoring stack from scratch.

Configuration

Datastore

Parameter Description Default
formae.datastore.type Backend type: postgres, sqlite, auroradataapi postgres
formae.datastore.sqlite.filePath SQLite database path /data/formae.db
formae.datastore.postgres.host External PostgreSQL host (when postgresql.enabled=false) ""
formae.datastore.auroraDataAPI.clusterARN Aurora cluster ARN ""

PostgreSQL (in-cluster)

Parameter Description Default
postgresql.enabled Deploy PostgreSQL alongside formae true
postgresql.image.tag PostgreSQL image tag 15-alpine
postgresql.auth.username Database user formae
postgresql.auth.password Database password (set via --set) ""
postgresql.auth.database Database name formae
postgresql.auth.existingSecret Use an existing Secret for the password ""
postgresql.persistence.enabled Enable persistent storage true
postgresql.persistence.size PVC size 8Gi

Authentication

Parameter Description Default
formae.auth.enabled Enable basic authentication for the agent API false
formae.auth.basic.username Auth username ""
formae.auth.basic.password Auth password (bcrypt hash) ""
formae.auth.basic.existingSecret Use an existing Secret for credentials ""
formae.auth.basic.usernameKey Key in the existing Secret for username username
formae.auth.basic.passwordKey Key in the existing Secret for password password

Generate a bcrypt hash with:

htpasswd -bnBC 10 "" yourPassword | tr -d ':\n'

Notes:

  • Requires formae >= 0.84.0. Earlier images ship the legacy in-binary auth plugin, which the agent no longer loads. Set image.tag accordingly if the chart's appVersion is older.
  • The auth-basic plugin ships in the formae image (part of the standard metapackage), so no extra install is needed. The agent refuses to start if auth is configured but the plugin is missing.
  • /api/v1/health stays unauthenticated, so the default httpGet probes and the helm test hook keep working.
  • The chart configures the agent side only. To use the formae CLI against an authenticated agent, add cli.auth (with the plaintext password, not the hash) to your local formae.conf.pkl.

Example with inline credentials:

helm install formae . -f examples/formae-basic-auth.yaml \
  --set postgresql.auth.password=changeme \
  --set-string formae.auth.basic.username=admin \
  --set-string formae.auth.basic.password='$2y$10$...'

Example with an existing Kubernetes Secret:

formae:
  auth:
    enabled: true
    basic:
      existingSecret: my-auth-secret
      usernameKey: username
      passwordKey: password

Custom Configuration

Instead of using chart values to build formae.conf.pkl, you can provide the entire config as a string via formae.existingConfig. When set, all other formae.* values (auth, datastore, server, etc.) are ignored.

Parameter Description Default
formae.existingConfig Full formae.conf.pkl content as a string ""

Use read("env:...") in your PKL to reference secrets, and inject them via extraEnv:

formae:
  existingConfig: |
    amends "formae:/Config.pkl"
    agent {
      server { port = 49684 }
      datastore {
        datastoreType = "postgres"
        postgres {
          host = "my-db"
          password = read("env:FORMAE_DB_PASSWORD")
        }
      }
      auth {
        type = "auth-basic"
        authorizedUsers = new Listing {
          new Mapping {
            ["Username"] = read("env:FORMAE_AUTH_USERNAME")
            ["Password"] = read("env:FORMAE_AUTH_PASSWORD")
          }
        }
      }
    }

extraEnv:
  - name: FORMAE_DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: my-db-secret
        key: password
  - name: FORMAE_AUTH_USERNAME
    valueFrom:
      secretKeyRef:
        name: my-auth-secret
        key: username
  - name: FORMAE_AUTH_PASSWORD
    valueFrom:
      secretKeyRef:
        name: my-auth-secret
        key: password

See examples/formae-custom-config.yaml for a complete example.

Init Containers

Parameter Description Default
initContainers Init containers rendered verbatim into the agent Pod []

Waiting for the database removes the one crash-and-restart that otherwise happens on a fresh install, where the agent starts before PostgreSQL accepts connections:

initContainers:
  - name: wait-for-postgresql
    image: busybox
    command: ["sh", "-c", "until nc -z formae-postgresql 5432; do sleep 2; done"]

Installing extra plugins means mounting a volume over the image's plugin directory, which hides the plugins that ship in the image (aws, azure, gcp, k8s, auth-basic). Copy them into the volume first, or the agent loses them — with formae.auth.enabled it then refuses to start entirely:

initContainers:
  - name: install-custom-plugin
    image: ghcr.io/platform-engineering-labs/formae:0.88.1
    command:
      - sh
      - -c
      ## cp -R, not cp -a: preserving timestamps on the volume root fails as non-root
      - cp -R /opt/pel/formae/plugins/. /plugins/ && cp -R /plugin/. /plugins/
    volumeMounts:
      - name: plugins
        mountPath: /plugins

extraVolumes:
  - name: plugins
    emptyDir: {}

extraVolumeMounts:
  - name: plugins
    mountPath: /opt/pel/formae/plugins

podSecurityContext applies to init containers too, so their images must run as uid 1001 and cannot be root.

Observability

Parameter Description Default
formae.otel.enabled Enable OpenTelemetry instrumentation false
formae.otel.otlp.endpoint OTLP receiver endpoint localhost:4317
formae.otel.otlp.protocol OTLP protocol (grpc or http) grpc
formae.otel.prometheus.enabled Enable Prometheus metrics export false
otelCollector.enabled Deploy OTel Collector as sidecar false

Grafana Dashboards

Parameter Description Default
grafana.dashboards.enabled Create dashboard ConfigMaps true
grafana.dashboards.label Label for Grafana sidecar discovery grafana_dashboard
grafana.dashboards.labelValue Label value "1"
grafana.dashboards.folder Grafana folder name formae

Resources

Sizing recommendations from the formae docs:

Managed Resources Memory CPU
up to 1,000 512Mi 1
1,000 - 5,000 1Gi 2
5,000 - 10,000 1.5Gi 2-4
10,000 - 20,000 2Gi 4

Examples

File Description
formae-only.yaml SQLite, ephemeral storage
formae-only-persistent.yaml SQLite with PVC
formae-db.yaml In-cluster PostgreSQL
formae-db-grafana.yaml PostgreSQL + Grafana + OTel
formae-basic-auth.yaml Basic authentication
formae-custom-config.yaml Bring your own formae.conf.pkl
formae-external-db.yaml External PostgreSQL
formae-external-db-grafana.yaml External PostgreSQL + Grafana + OTel
formae-aurora.yaml Aurora Data API
quickstart-monitoring.yaml Full monitoring stack walkthrough

About

Helm chart for deploying formae with optional PostgreSQL, OpenTelemetry, and Grafana dashboards

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages