Skip to main content

Customize Kubernetes with object modifiers

Nullplatform allows you to modify Kubernetes manifests before deployment using object modifiers. This feature lets you customize objects like Deployments and Services at runtime by configuring modifiers within nullplatform’s NRN.

Key benefits

  • Dynamic configuration: Adjust manifests dynamically without manual edits.
  • Reusable modifications: Define once, apply anywhere—across multiple deployments, clusters, or environments.
  • Context-aware replacements: Inject variables and settings based on your runtime context.

How it works

Before deploying or updating your Kubernetes resources, nullplatform processes your defined modifiers through the modifyObjects function. The process works as follows:

  1. Filter modifiers by object type: Ensures only modifiers matching the current object type (e.g., deployment) are considered.

  2. Apply each modifier. For each matching modifier:

    • Uses JSONPath to locate target fields within the object.
    • Executes the specified action (add, update, or remove).
    • Performs placeholder substitution with the provided context, if applicable.

Supported actions

ActionDescription
addIf targeting an array, the value is appended. If targeting an object, the value is merged.
updateOverwrites the existing content at the selected path with the provided value.
removeDeletes the field or array element identified by the selector.

Example configuration

Below is an example of a JSON configuration you can include in your NRN. It shows how to add Datadog-related annotations, environment variables, and labels to a Kubernetes Deployment.

{
"modifiers": [
{
"selector": "$.spec.template.metadata.annotations",
"action": "add",
"type": "deployment",
"value": {
"ad.datadoghq.com/application.logs": "[{\"source\":\"${NP_APPLICATION}\",\"service\":\"${NP_APPLICATION}\",\"log_processing_rules\":[{\"type\":\"mask_sequences\",\"name\":\"mask_password\",\"replace_placeholder\":\"\\\"password\\\": \\\"**\\\"\",\"pattern\":\"(?:\\\"password\\\":\\\"([^\\\"]+)\\\")\"}]}]"
}
},
{
"selector": "$.spec.template.spec.containers[?(@.name=='application')].env",
"action": "add",
"type": "deployment",
"value": {
"name": "DD_AGENT_HOST",
"valueFrom": {
"fieldRef": {
"apiVersion": "v1",
"fieldPath": "status.hostIP"
}
}
}
},
{
"selector": "$.spec.template.spec.containers[?(@.name=='application')].env",
"action": "add",
"type": "deployment",
"value": {
"name": "DD_HOSTNAME",
"valueFrom": {
"fieldRef": {
"apiVersion": "v1",
"fieldPath": "spec.nodeName"
}
}
}
},
{
"selector": "$.spec.template.metadata.labels",
"action": "add",
"type": "deployment",
"value": {
"tags.datadoghq.com/service": "${NP_APPLICATION}"
}
}
]
}

What’s happening here?

  • Added Datadog annotation: The first modifier uses add to insert a Datadog annotation for log configuration into the spec.template.metadata.annotations field of adeployment. The ${NP_APPLICATION} placeholder is replaced using the runtime context.
  • Added environment variables: The next two modifiers add environment variables (DD_AGENT_HOST and DD_HOSTNAME) to the container named application.
  • Added a label: The final modifier adds a label (tags.datadoghq.com/service) to the deployment’s template metadata. Again, placeholders are replaced from the context.

Placeholders and context replacement

Values can contain placeholders of the form ${...}. During runtime, these are replaced by values from the context object. If a placeholder is not found in the context, it remains unchanged.

Object types

The type field in each modifier indicates the Kubernetes object type you’re targeting. For example:

  • type: "deployment" applies to Deployment objects.
  • Expansions could include service, ingress, statefulset, etc.

When the modifyObjects function is invoked, it filters modifiers by the provided objectType and only applies those that match.

Integration steps

  1. Add the modifiers to your NRN configuration: Place the JSON configuration (as shown above) under the corresponding NRN keys used by your organization or environment.
  2. Deploy or update your application: When nullplatform applies the manifests to your cluster, it automatically invokes modifyObjects and adjusts the Kubernetes objects based on the defined rules.
  3. Review the changes in the cluster: Inspect the deployed manifests (kubectl describe, kubectl get) to verify the modifications have been applied.

Tips and best practices

  • Use specific selectors: The more specific your JSONPath selector, the safer your modifications. For example, use [?(@.name=='application')] to target a specific container by name.
  • Test in a non-production environment: Validate your modifiers in a staging environment before applying them to production to ensure they produce the desired results.
  • Context variables: Keep your context placeholders meaningful and document what each variable represents. This ensures that any changes in runtime context configurations remain transparent.
  • Avoid over-complex modifications: While performing complex manipulations is possible, strive for clear, maintainable rules. Complex modifications can be harder to debug.

Troubleshooting

  • Unexpected values not changed: Ensure your selector matches an existing field. Use kubectl get -o json to review the full object and confirm your JSONPath expressions are correct.
  • Placeholders not replaced: Verify the context object is populated and that placeholder keys match those in the context.
  • Conflicting modifiers: If multiple modifiers attempt to change the same field in incompatible ways, the last applied modifier will ultimately determine the final state. Order is based on the order of modifiers in your configuration.