Skip to content

feat(langsmith): add extraManifests values key#714

Open
karantyagi-reltio wants to merge 2 commits into
langchain-ai:mainfrom
karantyagi-reltio:feat/extra-manifests
Open

feat(langsmith): add extraManifests values key#714
karantyagi-reltio wants to merge 2 commits into
langchain-ai:mainfrom
karantyagi-reltio:feat/extra-manifests

Conversation

@karantyagi-reltio
Copy link
Copy Markdown

@karantyagi-reltio karantyagi-reltio commented May 11, 2026

Summary

Adds two top-level lists to the langsmith chart so users can ship arbitrary Kubernetes resources alongside the chart without forking it:

  • extraManifests — plain resources, normal lifecycle.
  • preInstallManifests — prerequisite resources rendered as pre-install / pre-upgrade Helm hooks, applied before the rest of the chart. Useful for resources the chart consumes during install/upgrade, such as an ExternalSecret (External Secrets Operator) whose materialized Kubernetes Secret is referenced by config.existingSecretName or the per-datastore *.external.existingSecretName values.

Each entry in either list may be a YAML object or a multi-line YAML string; both are rendered through tpl so template expressions like {{ .Release.Name }} work.

Useful for ConfigMaps, Secrets, NetworkPolicies, ServiceMonitors, ExternalSecrets, or anything else the chart doesn't natively support.

Usage

extraManifests (plain resources)

extraManifests:
  - apiVersion: v1
    kind: ConfigMap
    metadata:
      name: my-extra
    data:
      key: value
  - |
    apiVersion: v1
    kind: Secret
    metadata:
      name: {{ .Release.Name }}-token
    stringData:
      token: changeme

preInstallManifests (pre-requisite hooks)

preInstallManifests:
  - apiVersion: external-secrets.io/v1beta1
    kind: ExternalSecret
    metadata:
      name: langsmith-app
    spec:
      refreshInterval: 1h
      secretStoreRef:
        name: vault-backend
        kind: ClusterSecretStore
      target:
        name: langsmith-app-secret      # matches config.existingSecretName
        creationPolicy: Orphan          # so the materialized Secret survives upgrades
      data:
        - secretKey: langsmith_license_key
          remoteRef:
            key: secret/langsmith/app
            property: langsmith_license_key

The chart then consumes the materialized Secret via the existing knobs:

config:
  disableSecretCreation: true
  existingSecretName: langsmith-app-secret

Implementation

  • templates/extra-manifests.yaml — iterates .Values.extraManifests, runs each entry through tpl (object entries via toYaml first).
  • templates/pre-install-manifests.yaml — iterates .Values.preInstallManifests, runs each entry through tpl, then injects the following annotations (user-provided values on the same keys win):
    • helm.sh/hook: pre-install,pre-upgrade
    • helm.sh/hook-weight: "-5"
    • helm.sh/hook-delete-policy: before-hook-creation
  • values.yaml — adds extraManifests: [] and preInstallManifests: [] with doc comments and examples covering both forms.

Defaults are [] for both, so behavior is unchanged for existing users.

Caveats

  • Hook resources (preInstallManifests) are not tracked as part of the Helm release and are recreated on every upgrade. For ExternalSecret entries, prefer target.creationPolicy: Orphan (or target.deletionPolicy: Retain on newer ESO versions) so the materialized Secret survives upgrades and pods consuming it don't restart.
  • Each preInstallManifests entry must be a single resource (no --- separators inside one string); extraManifests continues to pass strings through as-is and supports multi-doc strings.

Add a top-level `extraManifests` list that lets users ship arbitrary
Kubernetes resources alongside the chart without forking. Each entry
may be a YAML object or a multi-line string; both are passed through
`tpl` so template expressions like `{{ .Release.Name }}` work in
either form.

Useful for ConfigMaps, Secrets, NetworkPolicies, ServiceMonitors, or
anything else the chart doesn't natively support.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@karantyagi-reltio karantyagi-reltio requested a review from a team as a code owner May 11, 2026 13:28
Adds a second top-level list, preInstallManifests, that renders each entry as a
Helm pre-install / pre-upgrade hook (weight -5, delete-policy
before-hook-creation) so the resources are applied before the rest of the chart.

Intended for prerequisites the chart consumes during install/upgrade -- e.g. an
ExternalSecret whose materialized Kubernetes Secret is referenced via
config.existingSecretName or the per-datastore *.external.existingSecretName
values.

Hook annotations are injected automatically; user-supplied annotations on the
same keys take precedence so behavior can be overridden per entry. Entries
support both YAML-object and YAML-string forms, both rendered through tpl.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@joaquin-borggio-lc
Copy link
Copy Markdown
Contributor

For adding arbitrary manifests, I would recommend using helm composition.

something where you have this kind of structure:

my-langsmith/
  Chart.yaml
  values.yaml
  templates/
    my-configmap.yaml

this is your chart.yaml:

# Chart.yaml
apiVersion: v2
name: my-langsmith
version: 0.1.0
dependencies:
  - name: langsmith
    version: "0.x.x"
    repository: "https://langchain-ai.github.io/helm"

this anything you want in the templates folder. example:

# templates/my-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-custom-config
  namespace: {{ .Release.Namespace }}
data:
  APP_ENV: production
  SOME_FLAG: "true"

and your values file would look like this:

# values.yaml
langsmith:
  config:
    existingSecretName: langsmith-app-secret
  # any other langsmith values nested here

That's the general idea with the helm composition that allows you to combine different manifests or helm charts.

@karantyagi-reltio
Copy link
Copy Markdown
Author

karantyagi-reltio commented May 20, 2026

Thanks joaquin-borggio-lc — composition is the right tool for arbitrary side-car manifests, and I'm convinced it covers the extraManifests half of this PR.

The reason I'd still like to land the preInstallManifests half is install/upgrade ordering, which composition genuinely doesn't solve:

In a parent/child chart setup, both layers render into a single release manifest list, and Helm sorts by kind, not by chart. So a parent-chart ExternalSecret is not guaranteed to be applied (and reconciled by ESO into the target Secret) before the langsmith Deployments that consume it. On a clean install you get a window where the pods reference a not-yet-materialized Secret and crash-loop until ESO catches up; on upgrade you get a brief flap whenever the ES spec changes.

The standard fix is helm.sh/hook: pre-install,pre-upgrade with a negative weight, which is what preInstallManifests injects. You can do this by hand in a wrapper chart by annotating every entry, but:

  • it's easy to forget on one resource and silently get pod restarts,
  • the annotation set (hook, hook-weight, hook-delete-policy) and its caveats (e.g. creationPolicy: Orphan so the materialized Secret survives upgrades) are non-obvious,
  • ESO + LangSmith is a common enough combination that having a blessed path in the chart saves every adopter the same debug cycle.

@karantyagi-reltio
Copy link
Copy Markdown
Author

joaquin-borggio-lc Any update here ?

CC: Saad Farooq (@saad-supports-langchain)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants