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
add
to insert a Datadog annotation for log configuration into thespec.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
andDD_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 toDeployment
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
- 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
modifyObjects
and 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 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 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.