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:
-
Filter modifiers by object type: Ensures only modifiers matching the current object type (e.g., deployment) are considered.
-
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
| Action | Description |
|---|---|
| add | If targeting an array, the value is appended. If targeting an object, the value is merged. |
| update | Overwrites the existing content at the selected path with the provided value. |
| remove | Deletes 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
addto insert a Datadog annotation for log configuration into thespec.template.metadata.annotationsfield of adeployment. The${NP_APPLICATION}placeholder is replaced using the runtime context. - Added environment variables: The next two modifiers add environment variables (
DD_AGENT_HOSTandDD_HOSTNAME) to the container namedapplication. - Added a label: The final modifier adds a label (
tags.datadoghq.com/service) to thedeployment’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 toDeploymentobjects.- 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
- 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.
- Deploy or update your application: When nullplatform applies the manifests to your cluster, it automatically invokes
modifyObjectsand adjusts the Kubernetes objects based on the defined rules. - 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 jsonto review the full object and confirm your JSONPath expressions are correct. - Placeholders not replaced: Verify the
contextobject is populated and that placeholder keys match those in thecontext. - 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.