Skip to main content

Resource naming

Every Containers scope creates a set of Kubernetes objects: a Deployment, a Service, an HPA, a Secret, sometimes a PodDisruptionBudget, plus the Ingress or HTTPRoute that routes traffic to it.

Nullplatform supports three strategies for naming those objects: IDs (the default) builds names from numeric ids, qualified from the application and scope slugs, and custom from a pattern you write.

What it solves​

  • Identify an application and scope straight from a pod, Deployment or Service name.
  • Match what your team already sees in dashboards, alerts and kubectl output.
  • Keep your own naming convention if you have one, without leaving nullplatform.

Strategies​

Pick a strategy on the container-orchestration provider with naming.strategy. It applies to every Containers scope under that provider's NRN.

IDs​

This is the default (ids). Objects are named from the raw scope and deployment ids.

deployment:     d-123456-789012
hpa: hpa-d-123456-789012
scope ingress: k-8-s-production-123456-internet-facing

Nothing changes for an existing scope unless you choose another strategy.

Qualified​

Objects take the application and scope slugs, followed by the numeric id.

naming:
strategy: qualified
deployment:     checkout-api-production-789012
service: checkout-api-production-789012
hpa: checkout-api-production-789012
scope ingress: checkout-api-production-123456

Every object of a deployment shares one name. Kubernetes names are unique per kind, so a Deployment, a Service, an HPA and a PodDisruptionBudget can all be called the same thing without colliding.

The one exception is the pair of Secrets a scope creates, since those are the same kind: the one holding file parameters is suffixed -files. Additional ports keep a -http-<port> or -grpc-<port> suffix on their Services for the same reason.

Deployment-level objects use application, scope and the deployment id. Scope-level objects (the Ingress, HTTPRoute and serving certificate) use application, scope and the scope id.

Custom​

Write the pattern yourself. Each {...} is a path into the deployment context, so a pattern can use any field that context carries, including your scope's capabilities.

naming:
strategy: custom
deployment_pattern: "{.namespace.slug}-{.application.slug}-{.deployment.id}"
scope_pattern: "{.application.slug}-{.scope.slug}-{.scope.id}"
deployment:     payments-checkout-api-789012
scope ingress: checkout-api-production-123456

Defining only one of the two patterns is fine. The other falls back to what qualified would produce.

Available paths​

The most useful ones:

PathExample value
{.account.slug}acme
{.namespace.slug}payments
{.application.slug}checkout-api
{.scope.slug}production
{.scope.dimensions.environment}production
{.deployment.id}789012
{.scope.id}123456
{.release.semver}1.4.2

Any scalar field in the deployment context works, so {.scope.capabilities.visibility} or a capability of your own is equally valid.

Pattern rules​

A few constraints keep a pattern from producing a name Kubernetes rejects, or one that collides with another object.

Separate placeholders with a single hyphen. A literal prefix or suffix is fine, so edge-{.application.slug}-{.deployment.id} works, but anything other than - between two placeholders is rejected.

Start with something alphabetic. Kubernetes names must begin with a letter, so a pattern that starts with a numeric field is rejected. Put a slug first.

Use plain field access. Only dotted paths like .scope.capabilities.tenant and bracketed keys like .labels["team-name"] are accepted. Pipes, filters and variable bindings are not.

Every path has to resolve. A path that finds nothing fails the deploy rather than rendering an empty segment. This matters for fields that not every scope carries, such as a dimension or an optional capability: a pattern built around {.scope.dimensions.environment} works for scopes that define that dimension and breaks the ones that don't. Since the strategy applies to every scope under the provider's NRN, pick fields they all have.

The unique id is added if you leave it out. A deployment pattern needs {.deployment.id} and a scope pattern needs {.scope.id}; without one, a new deployment would overwrite the previous one's objects. If your pattern already has it, anywhere, it's used exactly where you put it. If it doesn't, it's appended and a warning tells you the pattern that was actually used, so the deploy succeeds and you still find out.

Name length​

Kubernetes caps object names at 63 characters, and nullplatform derives pod names from the Deployment name by appending a suffix. Deployment-level names are therefore budgeted at 46 characters by default, and scope-level names at 52.

When a name would exceed its budget, the slugs are shortened evenly until it fits:

application: customer-notifications-dispatcher
scope: production-canary-eu-west
deployment: customer-notificati-production-canary-e-789012

Numeric ids are never shortened, so names stay unique no matter how much trimming happens.

Existing objects are never renamed​

Changing a scope's strategy, or editing a custom pattern, does not rename anything that already exists. Renaming an Ingress or HTTPRoute would mean creating a new one while the old one keeps routing, which causes downtime.

So before naming a scope-level object, nullplatform looks for the live one in the cluster and keeps the name it already has. An existing scope keeps its original names for as long as it lives. A scope created after you set the strategy gets the new ones.

Deployment-level objects work differently, and they don't need freezing: every deployment creates a fresh set of them, so the new strategy simply applies to the next deployment. The blue deployment during a rollback is the exception, and nullplatform finds its live objects rather than recomputing their names, so a rollback after a strategy change still points at objects that exist.

Next steps​